From fb35f06cf59659d077d5d64f91331a3684fbc454 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 22 Aug 2024 14:20:51 +0300 Subject: [PATCH] Kernel: Add better support for bootloaders loading the kernel Before I assumed that bootloaders loaded the kernel at physical address 0, but this patch kinda allows loading to different addresses. This still doesn't fully work as kernel bootstrap paging relies on kernel being loaded at 0 --- bootloader/bios/boot.S | 2 ++ kernel/arch/i686/PageTable.cpp | 13 +++++++++++++ kernel/arch/x86_64/PageTable.cpp | 15 +++++++++++++-- kernel/include/kernel/BananBootloader.h | 1 + kernel/include/kernel/BootInfo.h | 1 + kernel/include/kernel/Memory/Types.h | 3 --- kernel/kernel/ACPI/ACPI.cpp | 4 ++-- kernel/kernel/BootInfo.cpp | 4 ++++ kernel/kernel/Memory/Heap.cpp | 4 ++-- kernel/kernel/Memory/kmalloc.cpp | 5 ++--- 10 files changed, 40 insertions(+), 12 deletions(-) diff --git a/bootloader/bios/boot.S b/bootloader/bios/boot.S index 5a318c68ca..29395851ca 100644 --- a/bootloader/bios/boot.S +++ b/bootloader/bios/boot.S @@ -172,3 +172,5 @@ banan_boot_info: .long framebuffer boot_memory_map: .long memory_map + boot_kernel_paddr: + .long 0 diff --git a/kernel/arch/i686/PageTable.cpp b/kernel/arch/i686/PageTable.cpp index 15978e671e..3ee39aeb16 100644 --- a/kernel/arch/i686/PageTable.cpp +++ b/kernel/arch/i686/PageTable.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -128,6 +129,18 @@ namespace Kernel return (uint64_t*)page; } + template + static paddr_t V2P(const T vaddr) + { + return (vaddr_t)vaddr - KERNEL_OFFSET + g_boot_info.kernel_paddr; + } + + template + static vaddr_t P2V(const T paddr) + { + return (paddr_t)paddr - g_boot_info.kernel_paddr + KERNEL_OFFSET; + } + void PageTable::initialize_kernel() { ASSERT(s_global_pdpte == 0); diff --git a/kernel/arch/x86_64/PageTable.cpp b/kernel/arch/x86_64/PageTable.cpp index b00da9d564..3fe85a408f 100644 --- a/kernel/arch/x86_64/PageTable.cpp +++ b/kernel/arch/x86_64/PageTable.cpp @@ -1,6 +1,5 @@ -#include +#include #include -#include #include #include #include @@ -147,6 +146,18 @@ namespace Kernel return (uint64_t*)page; } + template + static paddr_t V2P(const T vaddr) + { + return (vaddr_t)vaddr - KERNEL_OFFSET + g_boot_info.kernel_paddr; + } + + template + static vaddr_t P2V(const T paddr) + { + return (paddr_t)paddr - g_boot_info.kernel_paddr + KERNEL_OFFSET; + } + void PageTable::initialize_kernel() { ASSERT(s_global_pml4e == 0); diff --git a/kernel/include/kernel/BananBootloader.h b/kernel/include/kernel/BananBootloader.h index 4030037692..8991b0ca1a 100644 --- a/kernel/include/kernel/BananBootloader.h +++ b/kernel/include/kernel/BananBootloader.h @@ -33,4 +33,5 @@ struct BananBootloaderInfo uint32_t command_line_addr; uint32_t framebuffer_addr; uint32_t memory_map_addr; + uint32_t kernel_paddr; } __attribute__((packed)); diff --git a/kernel/include/kernel/BootInfo.h b/kernel/include/kernel/BootInfo.h index 8ba370f0ef..d59bee1654 100644 --- a/kernel/include/kernel/BootInfo.h +++ b/kernel/include/kernel/BootInfo.h @@ -37,6 +37,7 @@ namespace Kernel BAN::String command_line; FramebufferInfo framebuffer {}; RSDP rsdp {}; + paddr_t kernel_paddr {}; BAN::Vector memory_map_entries; }; diff --git a/kernel/include/kernel/Memory/Types.h b/kernel/include/kernel/Memory/Types.h index 364635fbbe..f4587b1c4b 100644 --- a/kernel/include/kernel/Memory/Types.h +++ b/kernel/include/kernel/Memory/Types.h @@ -10,9 +10,6 @@ #error #endif -#define V2P(vaddr) (((vaddr_t)(vaddr)) - KERNEL_OFFSET) -#define P2V(paddr) (((paddr_t)(paddr)) + KERNEL_OFFSET) - #define PAGE_SIZE ((uintptr_t)4096) #define PAGE_SIZE_SHIFT 12 #define PAGE_ADDR_MASK (~(uintptr_t)0xFFF) diff --git a/kernel/kernel/ACPI/ACPI.cpp b/kernel/kernel/ACPI/ACPI.cpp index b494a0fb4c..465ba0365b 100644 --- a/kernel/kernel/ACPI/ACPI.cpp +++ b/kernel/kernel/ACPI/ACPI.cpp @@ -254,7 +254,7 @@ acpi_release_global_lock: return *s_instance; } - static bool is_rsdp(uintptr_t rsdp_addr) + static bool is_rsdp(vaddr_t rsdp_addr) { const RSDP* rsdp = (const RSDP*)rsdp_addr; @@ -287,7 +287,7 @@ acpi_release_global_lock: return &g_boot_info.rsdp; // Look in main BIOS area below 1 MB - for (uintptr_t addr = P2V(0x000E0000); addr < P2V(0x000FFFFF); addr += 16) + for (vaddr_t addr = 0x000E0000 + KERNEL_OFFSET; addr < 0x000FFFFF + KERNEL_OFFSET; addr += 16) if (is_rsdp(addr)) return reinterpret_cast(addr); return nullptr; diff --git a/kernel/kernel/BootInfo.cpp b/kernel/kernel/BootInfo.cpp index 9a6ac1e817..491ff7eabb 100644 --- a/kernel/kernel/BootInfo.cpp +++ b/kernel/kernel/BootInfo.cpp @@ -66,6 +66,8 @@ namespace Kernel memcpy(&g_boot_info.rsdp, &rsdp, BAN::Math::min(rsdp.length, sizeof(g_boot_info.rsdp))); } } + + g_boot_info.kernel_paddr = 0; } static BAN::StringView get_early_boot_command_line_multiboot2(uint32_t info) @@ -104,6 +106,8 @@ namespace Kernel g_boot_info.memory_map_entries[i].length = mmap_entry.length; g_boot_info.memory_map_entries[i].type = mmap_entry.type; } + + g_boot_info.kernel_paddr = banan_bootloader_info.kernel_paddr; } static BAN::StringView get_early_boot_command_line_banan_bootloader(uint32_t info) diff --git a/kernel/kernel/Memory/Heap.cpp b/kernel/kernel/Memory/Heap.cpp index 0db22c96e4..c522e07050 100644 --- a/kernel/kernel/Memory/Heap.cpp +++ b/kernel/kernel/Memory/Heap.cpp @@ -40,8 +40,8 @@ namespace Kernel continue; paddr_t start = entry.address; - if (start < V2P(g_kernel_end)) - start = V2P(g_kernel_end); + if (start < (vaddr_t)g_kernel_end - KERNEL_OFFSET + g_boot_info.kernel_paddr) + start = (vaddr_t)g_kernel_end - KERNEL_OFFSET + g_boot_info.kernel_paddr; if (auto rem = start % PAGE_SIZE) start += PAGE_SIZE - rem; diff --git a/kernel/kernel/Memory/kmalloc.cpp b/kernel/kernel/Memory/kmalloc.cpp index 7f7e645119..83c1720f81 100644 --- a/kernel/kernel/Memory/kmalloc.cpp +++ b/kernel/kernel/Memory/kmalloc.cpp @@ -1,9 +1,8 @@ #include #include +#include #include -#include - #define MB (1 << 20) extern uint8_t g_kernel_end[]; @@ -424,7 +423,7 @@ BAN::Optional kmalloc_paddr_of(Kernel::vaddr_t vaddr) using namespace Kernel; if ((vaddr_t)s_kmalloc_storage <= vaddr && vaddr < (vaddr_t)s_kmalloc_storage + sizeof(s_kmalloc_storage)) - return V2P(vaddr); + return vaddr - KERNEL_OFFSET + g_boot_info.kernel_paddr; return {}; }