Prekernel: Use physical addresses for some of the BootInfo parameters

The kernel would just turn those virtual addresses into physical
addresses later on, so let's just use physical addresses right from the
start.
This commit is contained in:
Gunnar Beutner 2021-07-19 18:24:15 +02:00 committed by Andreas Kling
parent dd42093b93
commit be795d5812
Notes: sideshowbarker 2024-07-18 08:41:57 +09:00
6 changed files with 58 additions and 59 deletions

View file

@ -6,18 +6,20 @@
#pragma once
#include <Kernel/Arch/x86/PageDirectory.h>
#include <Kernel/PhysicalAddress.h>
#include <Kernel/VirtualAddress.h>
extern "C" u8 const* start_of_prekernel_image;
extern "C" u8 const* end_of_prekernel_image;
extern "C" PhysicalAddress start_of_prekernel_image;
extern "C" PhysicalAddress end_of_prekernel_image;
extern "C" __attribute__((section(".boot_bss"))) FlatPtr kernel_base;
#if ARCH(X86_64)
extern "C" u32 gdt64ptr;
extern "C" u16 code64_sel;
extern "C" FlatPtr boot_pml4t;
extern "C" PhysicalAddress boot_pml4t;
#endif
extern "C" FlatPtr boot_pdpt;
extern "C" FlatPtr boot_pd0;
extern "C" FlatPtr boot_pd_kernel;
extern "C" FlatPtr boot_pd_kernel_pt1023;
extern "C" PhysicalAddress boot_pdpt;
extern "C" PhysicalAddress boot_pd0;
extern "C" PhysicalAddress boot_pd_kernel;
extern "C" Kernel::PageTableEntry* boot_pd_kernel_pt1023;
extern "C" const char* kernel_cmdline;

View file

@ -8,6 +8,8 @@
#ifdef __cplusplus
# include <Kernel/Multiboot.h>
# include <Kernel/PhysicalAddress.h>
# include <Kernel/VirtualAddress.h>
#endif
#define MAX_KERNEL_SIZE 0x3000000
@ -16,20 +18,20 @@
namespace Kernel {
struct [[gnu::packed]] BootInfo {
u8 const* start_of_prekernel_image;
u8 const* end_of_prekernel_image;
FlatPtr kernel_base;
multiboot_info* multiboot_info_ptr;
u32 start_of_prekernel_image;
u32 end_of_prekernel_image;
u64 kernel_base;
u64 multiboot_info_ptr;
# if ARCH(X86_64)
u32 gdt64ptr;
u16 code64_sel;
FlatPtr boot_pml4t;
u32 boot_pml4t;
# endif
FlatPtr boot_pdpt;
FlatPtr boot_pd0;
FlatPtr boot_pd_kernel;
FlatPtr boot_pd_kernel_pt1023;
char const* kernel_cmdline;
u32 boot_pdpt;
u32 boot_pd0;
u32 boot_pd_kernel;
u64 boot_pd_kernel_pt1023;
u64 kernel_cmdline;
};
}
#endif

View file

@ -8,6 +8,7 @@
#include <AK/Types.h>
#include <Kernel/Multiboot.h>
#include <Kernel/PhysicalAddress.h>
#include <Kernel/Prekernel/Prekernel.h>
#include <Kernel/VirtualAddress.h>
#include <LibC/elf.h>
@ -138,20 +139,20 @@ extern "C" [[noreturn]] void init()
};
BootInfo info;
info.start_of_prekernel_image = adjust_by_load_base(start_of_prekernel_image);
info.end_of_prekernel_image = adjust_by_load_base(end_of_prekernel_image);
info.start_of_prekernel_image = (PhysicalPtr)start_of_prekernel_image;
info.end_of_prekernel_image = (PhysicalPtr)end_of_prekernel_image;
info.kernel_base = kernel_load_base;
info.multiboot_info_ptr = adjust_by_load_base(multiboot_info_ptr);
info.multiboot_info_ptr = (FlatPtr)adjust_by_load_base(multiboot_info_ptr);
#if ARCH(X86_64)
info.gdt64ptr = (FlatPtr)gdt64ptr;
info.gdt64ptr = (PhysicalPtr)gdt64ptr;
info.code64_sel = code64_sel;
info.boot_pml4t = (FlatPtr)adjust_by_load_base(boot_pml4t);
info.boot_pml4t = (PhysicalPtr)boot_pml4t;
#endif
info.boot_pdpt = (FlatPtr)adjust_by_load_base(boot_pdpt);
info.boot_pd0 = (FlatPtr)adjust_by_load_base(boot_pd0);
info.boot_pd_kernel = (FlatPtr)adjust_by_load_base(boot_pd_kernel);
info.boot_pdpt = (PhysicalPtr)boot_pdpt;
info.boot_pd0 = (PhysicalPtr)boot_pd0;
info.boot_pd_kernel = (PhysicalPtr)boot_pd_kernel;
info.boot_pd_kernel_pt1023 = (FlatPtr)adjust_by_load_base(boot_pd_kernel_pt1023);
info.kernel_cmdline = adjust_by_load_base(kernel_cmdline);
info.kernel_cmdline = (FlatPtr)adjust_by_load_base(kernel_cmdline);
asm(
#if ARCH(I386)

View file

@ -197,7 +197,7 @@ UNMAP_AFTER_INIT void MemoryManager::parse_memory_map()
// Register used memory regions that we know of.
m_used_memory_ranges.ensure_capacity(4);
m_used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::LowMemory, PhysicalAddress(0x00000000), PhysicalAddress(1 * MiB) });
m_used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::Prekernel, PhysicalAddress(virtual_to_low_physical(FlatPtr(start_of_prekernel_image))), PhysicalAddress(page_round_up(virtual_to_low_physical(FlatPtr(end_of_prekernel_image)))) });
m_used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::Prekernel, start_of_prekernel_image, end_of_prekernel_image });
m_used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::Kernel, PhysicalAddress(virtual_to_low_physical(FlatPtr(&start_of_kernel_image))), PhysicalAddress(page_round_up(virtual_to_low_physical(FlatPtr(&end_of_kernel_image)))) });
if (multiboot_info_ptr->flags & 0x4) {
@ -439,10 +439,8 @@ UNMAP_AFTER_INIT void MemoryManager::initialize_physical_pages()
unquickmap_page();
// Hook the page table into the kernel page directory
PhysicalAddress boot_pd_kernel_paddr(virtual_to_low_physical((FlatPtr)boot_pd_kernel));
u32 page_directory_index = (virtual_page_base_for_this_pt >> 21) & 0x1ff;
auto* pd = reinterpret_cast<PageDirectoryEntry*>(quickmap_page(boot_pd_kernel_paddr));
auto* pd = reinterpret_cast<PageDirectoryEntry*>(quickmap_page(boot_pd_kernel));
PageDirectoryEntry& pde = pd[page_directory_index];
VERIFY(!pde.is_present()); // Nothing should be using this PD yet
@ -991,7 +989,7 @@ PageDirectoryEntry* MemoryManager::quickmap_pd(PageDirectory& directory, size_t
{
VERIFY(s_mm_lock.own_lock());
auto& mm_data = get_data();
auto& pte = ((PageTableEntry*)boot_pd_kernel_pt1023)[(KERNEL_QUICKMAP_PD - KERNEL_PT1024_BASE) / PAGE_SIZE];
auto& pte = boot_pd_kernel_pt1023[(KERNEL_QUICKMAP_PD - KERNEL_PT1024_BASE) / PAGE_SIZE];
auto pd_paddr = directory.m_directory_pages[pdpt_index]->paddr();
if (pte.physical_page_base() != pd_paddr.get()) {
pte.set_physical_page_base(pd_paddr.get());

View file

@ -43,19 +43,15 @@ UNMAP_AFTER_INIT void PageDirectory::allocate_kernel_directory()
{
// Adopt the page tables already set up by boot.S
#if ARCH(X86_64)
PhysicalAddress boot_pml4t_paddr(virtual_to_low_physical((FlatPtr)boot_pml4t));
dmesgln("MM: boot_pml4t @ {}", boot_pml4t_paddr);
m_pml4t = PhysicalPage::create(boot_pml4t_paddr, MayReturnToFreeList::No);
dmesgln("MM: boot_pml4t @ {}", boot_pml4t);
m_pml4t = PhysicalPage::create(boot_pml4t, MayReturnToFreeList::No);
#endif
PhysicalAddress boot_pdpt_paddr(virtual_to_low_physical((FlatPtr)boot_pdpt));
PhysicalAddress boot_pd0_paddr(virtual_to_low_physical((FlatPtr)boot_pd0));
PhysicalAddress boot_pd_kernel_paddr(virtual_to_low_physical((FlatPtr)boot_pd_kernel));
dmesgln("MM: boot_pdpt @ {}", boot_pdpt_paddr);
dmesgln("MM: boot_pd0 @ {}", boot_pd0_paddr);
dmesgln("MM: boot_pd_kernel @ {}", boot_pd_kernel_paddr);
m_directory_table = PhysicalPage::create(boot_pdpt_paddr, MayReturnToFreeList::No);
m_directory_pages[0] = PhysicalPage::create(boot_pd0_paddr, MayReturnToFreeList::No);
m_directory_pages[(kernel_base >> 30) & 0x1ff] = PhysicalPage::create(boot_pd_kernel_paddr, MayReturnToFreeList::No);
dmesgln("MM: boot_pdpt @ {}", boot_pdpt);
dmesgln("MM: boot_pd0 @ {}", boot_pd0);
dmesgln("MM: boot_pd_kernel @ {}", boot_pd_kernel);
m_directory_table = PhysicalPage::create(boot_pdpt, MayReturnToFreeList::No);
m_directory_pages[0] = PhysicalPage::create(boot_pd0, MayReturnToFreeList::No);
m_directory_pages[(kernel_base >> 30) & 0x1ff] = PhysicalPage::create(boot_pd_kernel, MayReturnToFreeList::No);
}
PageDirectory::PageDirectory(const RangeAllocator* parent_range_allocator)

View file

@ -107,16 +107,16 @@ static Processor s_bsp_processor; // global but let's keep it "private"
// init_stage2() function. Initialization continues there.
extern "C" {
u8 const* start_of_prekernel_image;
u8 const* end_of_prekernel_image;
PhysicalAddress start_of_prekernel_image;
PhysicalAddress end_of_prekernel_image;
__attribute__((section(".boot_bss"))) FlatPtr kernel_base;
#if ARCH(X86_64)
FlatPtr boot_pml4t;
PhysicalAddress boot_pml4t;
#endif
FlatPtr boot_pdpt;
FlatPtr boot_pd0;
FlatPtr boot_pd_kernel;
FlatPtr boot_pd_kernel_pt1023;
PhysicalAddress boot_pdpt;
PhysicalAddress boot_pd0;
PhysicalAddress boot_pd_kernel;
PageTableEntry* boot_pd_kernel_pt1023;
const char* kernel_cmdline;
}
@ -124,20 +124,20 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
{
g_in_early_boot = true;
multiboot_info_ptr = boot_info.multiboot_info_ptr;
start_of_prekernel_image = boot_info.start_of_prekernel_image;
end_of_prekernel_image = boot_info.end_of_prekernel_image;
multiboot_info_ptr = (multiboot_info_t*)boot_info.multiboot_info_ptr;
start_of_prekernel_image = PhysicalAddress { boot_info.start_of_prekernel_image };
end_of_prekernel_image = PhysicalAddress { boot_info.end_of_prekernel_image };
kernel_base = boot_info.kernel_base;
#if ARCH(X86_64)
gdt64ptr = boot_info.gdt64ptr;
code64_sel = boot_info.code64_sel;
boot_pml4t = boot_info.boot_pml4t;
boot_pml4t = PhysicalAddress { boot_info.boot_pml4t };
#endif
boot_pdpt = boot_info.boot_pdpt;
boot_pd0 = boot_info.boot_pd0;
boot_pd_kernel = boot_info.boot_pd_kernel;
boot_pd_kernel_pt1023 = boot_info.boot_pd_kernel_pt1023;
kernel_cmdline = boot_info.kernel_cmdline;
boot_pdpt = PhysicalAddress { boot_info.boot_pdpt };
boot_pd0 = PhysicalAddress { boot_info.boot_pd0 };
boot_pd_kernel = PhysicalAddress { boot_info.boot_pd_kernel };
boot_pd_kernel_pt1023 = (PageTableEntry*)boot_info.boot_pd_kernel_pt1023;
kernel_cmdline = (char const*)boot_info.kernel_cmdline;
setup_serial_debug();