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 5a318c68..29395851 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 15978e67..3ee39aeb 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 b00da9d5..3fe85a40 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 40300376..8991b0ca 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 8ba370f0..d59bee16 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 364635fb..f4587b1c 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 b494a0fb..465ba036 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 9a6ac1e8..491ff7ea 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 0db22c96..c522e070 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 7f7e6451..83c1720f 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 {}; }