boot: rework 32-bit/64-bit kernel load base selection

Change-Id: I0aed05c0ef2ff1a162581e4f988bf24ed1e521e0
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4816
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
Reviewed-by: Fredrik Holmqvist <[email protected]>
This commit is contained in:
David Karoly
2021-12-27 15:44:56 +00:00
committed by Fredrik Holmqvist
parent b9a0a02382
commit 235aa994d7
8 changed files with 32 additions and 39 deletions
@@ -14,8 +14,7 @@
// memory layout // memory layout
#define KERNEL_LOAD_BASE 0x80000000 #define KERNEL_LOAD_BASE 0xffffffc000000000
#define KERNEL_LOAD_BASE_64_BIT 0xffffffc000000000
#if (defined(__riscv) && __riscv_xlen == 64) #if (defined(__riscv) && __riscv_xlen == 64)
@@ -18,11 +18,15 @@
#ifdef _BOOT_MODE #ifdef _BOOT_MODE
#ifdef _BOOT_PLATFORM_BIOS
// 32-bit and 64-bit kernel load addresses. #define KERNEL_LOAD_BASE_32_BIT 0x80000000
#define KERNEL_LOAD_BASE_64_BIT 0xffffffff80000000ll
#define KERNEL_FIXUP_FOR_LONG_MODE (KERNEL_LOAD_BASE_64_BIT - KERNEL_LOAD_BASE_32_BIT)
#elif __x86_64__
#define KERNEL_LOAD_BASE 0xffffffff80000000ll
#else
#define KERNEL_LOAD_BASE 0x80000000 #define KERNEL_LOAD_BASE 0x80000000
#define KERNEL_LOAD_BASE_64_BIT 0xffffffff80000000ll #endif
#elif defined(__x86_64__) #elif defined(__x86_64__)
+3 -5
View File
@@ -121,7 +121,7 @@ struct ELF64Class {
{ {
#if defined(_BOOT_PLATFORM_BIOS) #if defined(_BOOT_PLATFORM_BIOS)
// Assume the real 64-bit base address is KERNEL_LOAD_BASE_64_BIT and // Assume the real 64-bit base address is KERNEL_LOAD_BASE_64_BIT and
// the mappings in the loader address space are at KERNEL_LOAD_BASE. // the mappings in the loader address space are at KERNEL_LOAD_BASE_32_BIT.
void* address = (void*)(addr_t)(*_address & 0xffffffff); void* address = (void*)(addr_t)(*_address & 0xffffffff);
#else #else
@@ -135,8 +135,7 @@ struct ELF64Class {
*_mappedAddress = address; *_mappedAddress = address;
#if defined(_BOOT_PLATFORM_BIOS) #if defined(_BOOT_PLATFORM_BIOS)
*_address = (AddrType)(addr_t)address + KERNEL_LOAD_BASE_64_BIT *_address = (AddrType)(addr_t)address + KERNEL_FIXUP_FOR_LONG_MODE;
- KERNEL_LOAD_BASE;
#else #else
platform_bootloader_address_to_kernel_address(address, _address); platform_bootloader_address_to_kernel_address(address, _address);
#endif #endif
@@ -147,8 +146,7 @@ struct ELF64Class {
Map(AddrType address) Map(AddrType address)
{ {
#ifdef _BOOT_PLATFORM_BIOS #ifdef _BOOT_PLATFORM_BIOS
return (void*)(addr_t)(address - KERNEL_LOAD_BASE_64_BIT return (void*)(addr_t)(address - KERNEL_FIXUP_FOR_LONG_MODE);
+ KERNEL_LOAD_BASE);
#else #else
void *result; void *result;
if (platform_kernel_address_to_bootloader_address(address, &result) != B_OK) { if (platform_kernel_address_to_bootloader_address(address, &result) != B_OK) {
+3 -3
View File
@@ -45,8 +45,8 @@ extern uint64 gLongKernelEntry;
static inline uint64 static inline uint64
fix_address(uint64 address) fix_address(uint64 address)
{ {
if(address >= KERNEL_LOAD_BASE) if(address >= KERNEL_LOAD_BASE_32_BIT)
return address - KERNEL_LOAD_BASE + KERNEL_LOAD_BASE_64_BIT; return address + KERNEL_FIXUP_FOR_LONG_MODE;
else else
return address; return address;
} }
@@ -194,7 +194,7 @@ long_mmu_init()
} }
// Get the physical address to map. // Get the physical address to map.
if (!mmu_get_virtual_mapping(KERNEL_LOAD_BASE + (i * B_PAGE_SIZE), if (!mmu_get_virtual_mapping(KERNEL_LOAD_BASE_32_BIT + (i * B_PAGE_SIZE),
&physicalAddress)) &physicalAddress))
continue; continue;
+12 -12
View File
@@ -80,7 +80,7 @@ static uint32 *sPageDirectory = 0;
#ifdef _PXE_ENV #ifdef _PXE_ENV
static addr_t sNextPhysicalAddress = 0x112000; static addr_t sNextPhysicalAddress = 0x112000;
static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE + kMaxKernelSize; static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE_32_BIT + kMaxKernelSize;
static addr_t sNextPageTableAddress = 0x7d000; static addr_t sNextPageTableAddress = 0x7d000;
static const uint32 kPageTableRegionEnd = 0x8b000; static const uint32 kPageTableRegionEnd = 0x8b000;
@@ -89,7 +89,7 @@ static const uint32 kPageTableRegionEnd = 0x8b000;
#else #else
static addr_t sNextPhysicalAddress = 0x100000; static addr_t sNextPhysicalAddress = 0x100000;
static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE + kMaxKernelSize; static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE_32_BIT + kMaxKernelSize;
static addr_t sNextPageTableAddress = 0x90000; static addr_t sNextPageTableAddress = 0x90000;
static const uint32 kPageTableRegionEnd = 0x9e000; static const uint32 kPageTableRegionEnd = 0x9e000;
@@ -202,7 +202,7 @@ unmap_page(addr_t virtualAddress)
{ {
TRACE("unmap_page(virtualAddress = %p)\n", (void *)virtualAddress); TRACE("unmap_page(virtualAddress = %p)\n", (void *)virtualAddress);
if (virtualAddress < KERNEL_LOAD_BASE) { if (virtualAddress < KERNEL_LOAD_BASE_32_BIT) {
panic("unmap_page: asked to unmap invalid page %p!\n", panic("unmap_page: asked to unmap invalid page %p!\n",
(void *)virtualAddress); (void *)virtualAddress);
} }
@@ -227,7 +227,7 @@ map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags)
TRACE("map_page: vaddr 0x%lx, paddr 0x%lx\n", virtualAddress, TRACE("map_page: vaddr 0x%lx, paddr 0x%lx\n", virtualAddress,
physicalAddress); physicalAddress);
if (virtualAddress < KERNEL_LOAD_BASE) { if (virtualAddress < KERNEL_LOAD_BASE_32_BIT) {
panic("map_page: asked to map invalid page %p!\n", panic("map_page: asked to map invalid page %p!\n",
(void *)virtualAddress); (void *)virtualAddress);
} }
@@ -404,8 +404,8 @@ mmu_allocate(void *virtualAddress, size_t size)
addr_t address = (addr_t)virtualAddress; addr_t address = (addr_t)virtualAddress;
// is the address within the valid range? // is the address within the valid range?
if (address < KERNEL_LOAD_BASE || address + size * B_PAGE_SIZE if (address < KERNEL_LOAD_BASE_32_BIT || address + size * B_PAGE_SIZE
>= KERNEL_LOAD_BASE + kMaxKernelSize) >= KERNEL_LOAD_BASE_32_BIT + kMaxKernelSize)
return NULL; return NULL;
for (uint32 i = 0; i < size; i++) { for (uint32 i = 0; i < size; i++) {
@@ -486,7 +486,7 @@ mmu_free(void *virtualAddress, size_t size)
size = (size + pageOffset + B_PAGE_SIZE - 1) / B_PAGE_SIZE * B_PAGE_SIZE; size = (size + pageOffset + B_PAGE_SIZE - 1) / B_PAGE_SIZE * B_PAGE_SIZE;
// is the address within the valid range? // is the address within the valid range?
if (address < KERNEL_LOAD_BASE || address + size > sNextVirtualAddress) { if (address < KERNEL_LOAD_BASE_32_BIT || address + size > sNextVirtualAddress) {
panic("mmu_free: asked to unmap out of range region (%p, size %lx)\n", panic("mmu_free: asked to unmap out of range region (%p, size %lx)\n",
(void *)address, size); (void *)address, size);
} }
@@ -507,14 +507,14 @@ mmu_free(void *virtualAddress, size_t size)
size_t size_t
mmu_get_virtual_usage() mmu_get_virtual_usage()
{ {
return sNextVirtualAddress - KERNEL_LOAD_BASE; return sNextVirtualAddress - KERNEL_LOAD_BASE_32_BIT;
} }
bool bool
mmu_get_virtual_mapping(addr_t virtualAddress, addr_t *_physicalAddress) mmu_get_virtual_mapping(addr_t virtualAddress, addr_t *_physicalAddress)
{ {
if (virtualAddress < KERNEL_LOAD_BASE) { if (virtualAddress < KERNEL_LOAD_BASE_32_BIT) {
panic("mmu_get_virtual_mapping: asked to lookup invalid page %p!\n", panic("mmu_get_virtual_mapping: asked to lookup invalid page %p!\n",
(void *)virtualAddress); (void *)virtualAddress);
} }
@@ -580,9 +580,9 @@ mmu_init_for_kernel(void)
// Save the memory we've virtually allocated (for the kernel and other // Save the memory we've virtually allocated (for the kernel and other
// stuff) // stuff)
gKernelArgs.virtual_allocated_range[0].start = KERNEL_LOAD_BASE; gKernelArgs.virtual_allocated_range[0].start = KERNEL_LOAD_BASE_32_BIT;
gKernelArgs.virtual_allocated_range[0].size gKernelArgs.virtual_allocated_range[0].size
= sNextVirtualAddress - KERNEL_LOAD_BASE; = sNextVirtualAddress - KERNEL_LOAD_BASE_32_BIT;
gKernelArgs.num_virtual_allocated_ranges = 1; gKernelArgs.num_virtual_allocated_ranges = 1;
// sort the address ranges // sort the address ranges
@@ -627,7 +627,7 @@ mmu_init(void)
{ {
TRACE("mmu_init\n"); TRACE("mmu_init\n");
gKernelArgs.arch_args.virtual_end = KERNEL_LOAD_BASE; gKernelArgs.arch_args.virtual_end = KERNEL_LOAD_BASE_32_BIT;
gKernelArgs.physical_allocated_range[0].start = sNextPhysicalAddress; gKernelArgs.physical_allocated_range[0].start = sNextPhysicalAddress;
gKernelArgs.physical_allocated_range[0].size = 0; gKernelArgs.physical_allocated_range[0].size = 0;
@@ -174,11 +174,11 @@ arch_mmu_generate_post_efi_page_tables(size_t memory_map_size,
&gKernelArgs.arch_args.vir_pgdir); &gKernelArgs.arch_args.vir_pgdir);
// Store the virtual memory usage information. // Store the virtual memory usage information.
gKernelArgs.virtual_allocated_range[0].start = KERNEL_LOAD_BASE_64_BIT; gKernelArgs.virtual_allocated_range[0].start = KERNEL_LOAD_BASE;
gKernelArgs.virtual_allocated_range[0].size gKernelArgs.virtual_allocated_range[0].size
= get_current_virtual_address() - KERNEL_LOAD_BASE_64_BIT; = get_current_virtual_address() - KERNEL_LOAD_BASE;
gKernelArgs.num_virtual_allocated_ranges = 1; gKernelArgs.num_virtual_allocated_ranges = 1;
gKernelArgs.arch_args.virtual_end = ROUNDUP(KERNEL_LOAD_BASE_64_BIT gKernelArgs.arch_args.virtual_end = ROUNDUP(KERNEL_LOAD_BASE
+ gKernelArgs.virtual_allocated_range[0].size, 0x200000); + gKernelArgs.virtual_allocated_range[0].size, 0x200000);
// Find the highest physical memory address. We map all physical memory // Find the highest physical memory address. We map all physical memory
@@ -246,7 +246,7 @@ arch_mmu_generate_post_efi_page_tables(size_t memory_map_size,
// Get the physical address to map. // Get the physical address to map.
void *phys; void *phys;
if (platform_kernel_address_to_bootloader_address( if (platform_kernel_address_to_bootloader_address(
KERNEL_LOAD_BASE_64_BIT + (i * B_PAGE_SIZE), &phys) != B_OK) { KERNEL_LOAD_BASE + (i * B_PAGE_SIZE), &phys) != B_OK) {
continue; continue;
} }
-8
View File
@@ -42,15 +42,7 @@ struct memory_region {
}; };
#if defined(KERNEL_LOAD_BASE_64_BIT)
static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE_64_BIT + 32 * 1024 * 1024;
#elif defined(KERNEL_LOAD_BASE)
static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE + 32 * 1024 * 1024; static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE + 32 * 1024 * 1024;
#else
#error Unable to find kernel load base on this architecture!
#endif
static memory_region *allocated_regions = NULL; static memory_region *allocated_regions = NULL;
+1 -1
View File
@@ -10,7 +10,7 @@ UsePrivateHeaders [ FDirName graphics vesa ] ;
UsePrivateHeaders [ FDirName storage ] ; UsePrivateHeaders [ FDirName storage ] ;
{ {
local defines = _BOOT_MODE _PXE_ENV ; local defines = _BOOT_MODE _PXE_ENV _BOOT_PLATFORM_BIOS ;
defines = [ FDefines $(defines) ] ; defines = [ FDefines $(defines) ] ;
SubDirCcFlags $(defines) ; SubDirCcFlags $(defines) ;