mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
Kernel: Move boot info variables into a shared struct
This commit reorganizes the BootInfo struct definition so it can be shared for all architectures. The existing free extern "C" boot info variables have been removed and replaced with a global BootInfo struct, 'g_boot_info'. On x86-64, the BootInfo is directly copied from the Prekernel-provided struct. On AArch64 and RISC-V, BootInfo is populated during pre_init.
This commit is contained in:
1 parent
8c1e0ae059
commit
4f8490b5ff
29 files changed
+316
-274
No files matched your search
@@ -160,10 +160,10 @@ static void setup_quickmap_page_table(PageBumpAllocator& allocator, u64* root_ta
|
||||
{
|
||||
// FIXME: Rename boot_pd_kernel_pt1023 to quickmap_page_table
|
||||
// FIXME: Rename KERNEL_PT1024_BASE to quickmap_page_table_address
|
||||
auto kernel_pt1024_base = VirtualAddress(*adjust_by_mapping_base(&kernel_mapping_base) + KERNEL_PT1024_OFFSET);
|
||||
auto kernel_pt1024_base = VirtualAddress(*adjust_by_mapping_base(&g_boot_info.kernel_mapping_base) + KERNEL_PT1024_OFFSET);
|
||||
|
||||
auto quickmap_page_table = PhysicalAddress((PhysicalPtr)insert_page_table(allocator, root_table, kernel_pt1024_base));
|
||||
*adjust_by_mapping_base(&boot_pd_kernel_pt1023) = (PageTableEntry*)quickmap_page_table.offset(calculate_physical_to_link_time_address_offset()).get();
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_pd_kernel_pt1023) = (PageTableEntry*)quickmap_page_table.offset(calculate_physical_to_link_time_address_offset()).get();
|
||||
}
|
||||
|
||||
static void build_mappings(PageBumpAllocator& allocator, u64* root_table)
|
||||
@@ -279,17 +279,17 @@ static u64* get_page_directory_table(u64* root_table, VirtualAddress virtual_add
|
||||
|
||||
static void setup_kernel_page_directory(u64* root_table)
|
||||
{
|
||||
auto kernel_page_directory = (PhysicalPtr)get_page_directory(root_table, VirtualAddress { *adjust_by_mapping_base(&kernel_mapping_base) });
|
||||
auto kernel_page_directory = (PhysicalPtr)get_page_directory(root_table, VirtualAddress { *adjust_by_mapping_base(&g_boot_info.kernel_mapping_base) });
|
||||
if (!kernel_page_directory)
|
||||
panic_without_mmu("Could not find kernel page directory!"sv);
|
||||
|
||||
*adjust_by_mapping_base(&boot_pd_kernel) = PhysicalAddress(kernel_page_directory);
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_pd_kernel) = PhysicalAddress(kernel_page_directory);
|
||||
|
||||
// FIXME: Rename boot_pml4t to something architecture agnostic.
|
||||
*adjust_by_mapping_base(&boot_pml4t) = PhysicalAddress((PhysicalPtr)root_table);
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_pml4t) = PhysicalAddress((PhysicalPtr)root_table);
|
||||
|
||||
// FIXME: Rename to directory_table or similar
|
||||
*adjust_by_mapping_base(&boot_pdpt) = PhysicalAddress((PhysicalPtr)get_page_directory_table(root_table, VirtualAddress { *adjust_by_mapping_base(&kernel_mapping_base) }));
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_pdpt) = PhysicalAddress((PhysicalPtr)get_page_directory_table(root_table, VirtualAddress { *adjust_by_mapping_base(&g_boot_info.kernel_mapping_base) }));
|
||||
}
|
||||
|
||||
void init_page_tables(PhysicalPtr fdt_ptr)
|
||||
@@ -307,9 +307,14 @@ void init_page_tables(PhysicalPtr fdt_ptr)
|
||||
adjust_by_mapping_base(DeviceTree::s_fdt_storage)[o] = fdt_storage[o];
|
||||
}
|
||||
|
||||
*adjust_by_mapping_base(&physical_to_virtual_offset) = calculate_physical_to_link_time_address_offset();
|
||||
*adjust_by_mapping_base(&kernel_mapping_base) = KERNEL_MAPPING_BASE;
|
||||
*adjust_by_mapping_base(&kernel_load_base) = KERNEL_MAPPING_BASE;
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_method) = BootMethod::Multiboot1;
|
||||
adjust_by_mapping_base(&g_boot_info.boot_method_specific)->pre_init.~PreInitBootInfo();
|
||||
new (adjust_by_mapping_base(&g_boot_info.boot_method_specific.multiboot1)) Multiboot1BootInfo;
|
||||
|
||||
*adjust_by_mapping_base(&g_boot_info.flattened_devicetree_paddr) = PhysicalAddress { fdt_ptr };
|
||||
*adjust_by_mapping_base(&g_boot_info.physical_to_virtual_offset) = calculate_physical_to_link_time_address_offset();
|
||||
*adjust_by_mapping_base(&g_boot_info.kernel_mapping_base) = KERNEL_MAPPING_BASE;
|
||||
*adjust_by_mapping_base(&g_boot_info.kernel_load_base) = KERNEL_MAPPING_BASE;
|
||||
|
||||
PageBumpAllocator allocator(adjust_by_mapping_base((u64*)page_tables_phys_start), adjust_by_mapping_base((u64*)page_tables_phys_end));
|
||||
auto root_table = allocator.take_page();
|
||||
|
||||
@@ -73,7 +73,7 @@ ErrorOr<NonnullLockRefPtr<PageDirectory>> PageDirectory::try_create_for_userspac
|
||||
directory->m_root_table = TRY(MM.allocate_physical_page());
|
||||
|
||||
directory->m_directory_table = TRY(MM.allocate_physical_page());
|
||||
auto kernel_pd_index = (kernel_mapping_base >> 30) & 0x1ffu;
|
||||
auto kernel_pd_index = (g_boot_info.kernel_mapping_base >> 30) & 0x1ffu;
|
||||
for (size_t i = 0; i < kernel_pd_index; i++) {
|
||||
directory->m_directory_pages[i] = TRY(MM.allocate_physical_page());
|
||||
}
|
||||
@@ -107,15 +107,17 @@ PageDirectory::PageDirectory() = default;
|
||||
|
||||
UNMAP_AFTER_INIT void PageDirectory::allocate_kernel_directory()
|
||||
{
|
||||
VERIFY(g_boot_info.boot_method == BootMethod::Multiboot1);
|
||||
|
||||
// Adopt the page tables already set up by boot.S
|
||||
dmesgln("MM: boot_pml4t @ {}", boot_pml4t);
|
||||
m_root_table = PhysicalRAMPage::create(boot_pml4t, 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 = PhysicalRAMPage::create(boot_pdpt, MayReturnToFreeList::No);
|
||||
m_directory_pages[0] = PhysicalRAMPage::create(boot_pd0, MayReturnToFreeList::No);
|
||||
m_directory_pages[(kernel_mapping_base >> 30) & 0x1ff] = PhysicalRAMPage::create(boot_pd_kernel, MayReturnToFreeList::No);
|
||||
dmesgln("MM: boot_pml4t @ {}", g_boot_info.boot_pml4t);
|
||||
m_root_table = PhysicalRAMPage::create(g_boot_info.boot_pml4t, MayReturnToFreeList::No);
|
||||
dmesgln("MM: boot_pdpt @ {}", g_boot_info.boot_pdpt);
|
||||
dmesgln("MM: boot_pd0 @ {}", g_boot_info.boot_method_specific.multiboot1.boot_pd0);
|
||||
dmesgln("MM: boot_pd_kernel @ {}", g_boot_info.boot_pd_kernel);
|
||||
m_directory_table = PhysicalRAMPage::create(g_boot_info.boot_pdpt, MayReturnToFreeList::No);
|
||||
m_directory_pages[0] = PhysicalRAMPage::create(g_boot_info.boot_method_specific.multiboot1.boot_pd0, MayReturnToFreeList::No);
|
||||
m_directory_pages[(g_boot_info.kernel_mapping_base >> 30) & 0x1ff] = PhysicalRAMPage::create(g_boot_info.boot_pd_kernel, MayReturnToFreeList::No);
|
||||
}
|
||||
|
||||
PageDirectory::~PageDirectory()
|
||||
|
||||
@@ -118,16 +118,13 @@ void Framebuffer::initialize()
|
||||
{
|
||||
auto& framebuffer = the();
|
||||
if (framebuffer.initialized()) {
|
||||
multiboot_framebuffer_addr = PhysicalAddress((PhysicalPtr)framebuffer.gpu_buffer());
|
||||
multiboot_framebuffer_width = framebuffer.width();
|
||||
multiboot_framebuffer_height = framebuffer.height();
|
||||
multiboot_framebuffer_pitch = framebuffer.pitch();
|
||||
g_boot_info.boot_framebuffer.paddr = PhysicalAddress((PhysicalPtr)framebuffer.gpu_buffer());
|
||||
g_boot_info.boot_framebuffer.width = framebuffer.width();
|
||||
g_boot_info.boot_framebuffer.height = framebuffer.height();
|
||||
g_boot_info.boot_framebuffer.pitch = framebuffer.pitch();
|
||||
|
||||
// NOTE: The required pixel format for MULTIBOOT_FRAMEBUFFER_TYPE_RGB is actually BGRx8888.
|
||||
VERIFY(framebuffer.pixel_order() == PixelOrder::BGR);
|
||||
multiboot_framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
|
||||
|
||||
multiboot_flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO;
|
||||
g_boot_info.boot_framebuffer.type = BootFramebufferType::BGRx8888;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
// FIXME: The MMIO region is currently mapped at kernel_mapping_base + peripheral_base_address(),
|
||||
// but the code should be changed to use the MemoryManager to map the physical memory instead
|
||||
// of pre-mapping the whole MMIO region.
|
||||
u32 volatile* peripheral_address(FlatPtr offset) { return (u32 volatile*)(kernel_mapping_base + m_base_address.get() + offset); }
|
||||
u32 volatile* peripheral_address(FlatPtr offset) { return (u32 volatile*)(g_boot_info.kernel_mapping_base + m_base_address.get() + offset); }
|
||||
template<class T>
|
||||
T volatile* peripheral(FlatPtr offset) { return (T volatile*)peripheral_address(offset); }
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ extern "C" [[noreturn]] void pre_init(PhysicalPtr fdt_ptr)
|
||||
// in high virtual memory.
|
||||
asm volatile(
|
||||
"mov x0, %[base] \n"
|
||||
"add sp, sp, x0 \n" ::[base] "r"(physical_to_virtual_offset)
|
||||
"add sp, sp, x0 \n" ::[base] "r"(g_boot_info.physical_to_virtual_offset)
|
||||
: "x0");
|
||||
|
||||
// We can now unmap the identity map as everything is running in high virtual memory at this point.
|
||||
|
||||
+20
-57
@@ -135,61 +135,24 @@ ALWAYS_INLINE static Processor& bsp_processor()
|
||||
// Once multi-tasking is ready, we spawn a new thread that starts in the
|
||||
// init_stage2() function. Initialization continues there.
|
||||
|
||||
extern "C" {
|
||||
READONLY_AFTER_INIT PhysicalAddress start_of_prekernel_image;
|
||||
READONLY_AFTER_INIT PhysicalAddress end_of_prekernel_image;
|
||||
READONLY_AFTER_INIT size_t physical_to_virtual_offset;
|
||||
READONLY_AFTER_INIT FlatPtr kernel_mapping_base;
|
||||
READONLY_AFTER_INIT FlatPtr kernel_load_base;
|
||||
READONLY_AFTER_INIT PhysicalAddress boot_pml4t;
|
||||
READONLY_AFTER_INIT PhysicalAddress boot_pdpt;
|
||||
READONLY_AFTER_INIT PhysicalAddress boot_pd0;
|
||||
READONLY_AFTER_INIT PhysicalAddress boot_pd_kernel;
|
||||
READONLY_AFTER_INIT Memory::PageTableEntry* boot_pd_kernel_pt1023;
|
||||
READONLY_AFTER_INIT StringView kernel_cmdline;
|
||||
READONLY_AFTER_INIT u32 multiboot_flags;
|
||||
READONLY_AFTER_INIT multiboot_memory_map_t* multiboot_memory_map;
|
||||
READONLY_AFTER_INIT size_t multiboot_memory_map_count;
|
||||
READONLY_AFTER_INIT PhysicalAddress multiboot_framebuffer_addr;
|
||||
READONLY_AFTER_INIT u32 multiboot_framebuffer_pitch;
|
||||
READONLY_AFTER_INIT u32 multiboot_framebuffer_width;
|
||||
READONLY_AFTER_INIT u32 multiboot_framebuffer_height;
|
||||
READONLY_AFTER_INIT u8 multiboot_framebuffer_bpp;
|
||||
READONLY_AFTER_INIT u8 multiboot_framebuffer_type;
|
||||
READONLY_AFTER_INIT PhysicalAddress multiboot_module_physical_ptr;
|
||||
READONLY_AFTER_INIT size_t multiboot_module_length;
|
||||
}
|
||||
|
||||
Atomic<Graphics::Console*> g_boot_console;
|
||||
|
||||
#if ARCH(X86_64)
|
||||
extern "C" u32 gdt64ptr;
|
||||
extern "C" u16 code64_sel;
|
||||
#endif
|
||||
|
||||
READONLY_AFTER_INIT static StringView s_kernel_cmdline;
|
||||
|
||||
READONLY_AFTER_INIT constinit BootInfo g_boot_info;
|
||||
|
||||
extern "C" [[noreturn]] UNMAP_AFTER_INIT NO_SANITIZE_COVERAGE void init([[maybe_unused]] BootInfo const& boot_info)
|
||||
{
|
||||
#if ARCH(X86_64)
|
||||
start_of_prekernel_image = PhysicalAddress { boot_info.start_of_prekernel_image };
|
||||
end_of_prekernel_image = PhysicalAddress { boot_info.end_of_prekernel_image };
|
||||
physical_to_virtual_offset = boot_info.physical_to_virtual_offset;
|
||||
kernel_mapping_base = boot_info.kernel_mapping_base;
|
||||
kernel_load_base = boot_info.kernel_load_base;
|
||||
gdt64ptr = boot_info.gdt64ptr;
|
||||
code64_sel = boot_info.code64_sel;
|
||||
boot_pml4t = PhysicalAddress { boot_info.boot_pml4t };
|
||||
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 = (Memory::PageTableEntry*)boot_info.boot_pd_kernel_pt1023;
|
||||
char const* cmdline = (char const*)boot_info.kernel_cmdline;
|
||||
kernel_cmdline = StringView { cmdline, strlen(cmdline) };
|
||||
multiboot_flags = boot_info.multiboot_flags;
|
||||
multiboot_memory_map = (multiboot_memory_map_t*)boot_info.multiboot_memory_map;
|
||||
multiboot_memory_map_count = boot_info.multiboot_memory_map_count;
|
||||
multiboot_module_physical_ptr = PhysicalAddress { boot_info.multiboot_module_physical_ptr };
|
||||
multiboot_module_length = boot_info.multiboot_module_length;
|
||||
multiboot_framebuffer_addr = PhysicalAddress { boot_info.multiboot_framebuffer_addr };
|
||||
multiboot_framebuffer_pitch = boot_info.multiboot_framebuffer_pitch;
|
||||
multiboot_framebuffer_width = boot_info.multiboot_framebuffer_width;
|
||||
multiboot_framebuffer_height = boot_info.multiboot_framebuffer_height;
|
||||
multiboot_framebuffer_bpp = boot_info.multiboot_framebuffer_bpp;
|
||||
multiboot_framebuffer_type = boot_info.multiboot_framebuffer_type;
|
||||
g_boot_info = boot_info;
|
||||
gdt64ptr = boot_info.arch_specific.gdt64ptr;
|
||||
code64_sel = boot_info.arch_specific.code64_sel;
|
||||
s_kernel_cmdline = boot_info.cmdline;
|
||||
#elif ARCH(AARCH64) || ARCH(RISCV64)
|
||||
if (!DeviceTree::verify_fdt())
|
||||
// We are too early in the boot process to print anything, so just hang if the FDT is invalid.
|
||||
@@ -197,23 +160,23 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT NO_SANITIZE_COVERAGE void init([[maybe_
|
||||
|
||||
auto maybe_command_line = DeviceTree::get_command_line_from_fdt();
|
||||
if (maybe_command_line.is_error())
|
||||
kernel_cmdline = "serial_debug"sv;
|
||||
s_kernel_cmdline = "serial_debug"sv;
|
||||
else
|
||||
kernel_cmdline = maybe_command_line.value();
|
||||
s_kernel_cmdline = maybe_command_line.value();
|
||||
#endif
|
||||
|
||||
setup_serial_debug();
|
||||
|
||||
// We need to copy the command line before kmalloc is initialized,
|
||||
// as it may overwrite parts of multiboot!
|
||||
CommandLine::early_initialize(kernel_cmdline);
|
||||
CommandLine::early_initialize(s_kernel_cmdline);
|
||||
|
||||
new (&bsp_processor()) Processor();
|
||||
bsp_processor().early_initialize(0);
|
||||
|
||||
#if ARCH(RISCV64)
|
||||
// We implicitly assume the boot hart is hart 0 above and below
|
||||
VERIFY(boot_info.mhartid == 0);
|
||||
VERIFY(boot_info.arch_specific.boot_hart_id == 0);
|
||||
#endif
|
||||
|
||||
// Invoke the constructors needed for the kernel heap
|
||||
@@ -239,8 +202,8 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT NO_SANITIZE_COVERAGE void init([[maybe_
|
||||
// If the bootloader didn't provide a framebuffer, then set up an initial text console.
|
||||
// We do so we can see the output on the screen as soon as possible.
|
||||
if (!kernel_command_line().is_early_boot_console_disabled()) {
|
||||
if ((multiboot_flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) && !multiboot_framebuffer_addr.is_null() && multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) {
|
||||
g_boot_console = &try_make_lock_ref_counted<Graphics::BootFramebufferConsole>(multiboot_framebuffer_addr, multiboot_framebuffer_width, multiboot_framebuffer_height, multiboot_framebuffer_pitch).value().leak_ref();
|
||||
if (!g_boot_info.boot_framebuffer.paddr.is_null() && g_boot_info.boot_framebuffer.type == BootFramebufferType::BGRx8888) {
|
||||
g_boot_console = &try_make_lock_ref_counted<Graphics::BootFramebufferConsole>(g_boot_info.boot_framebuffer.paddr, g_boot_info.boot_framebuffer.width, g_boot_info.boot_framebuffer.height, g_boot_info.boot_framebuffer.pitch).value().leak_ref();
|
||||
} else {
|
||||
dbgln("No early framebuffer console available, initializing dummy console");
|
||||
g_boot_console = &try_make_lock_ref_counted<Graphics::BootDummyConsole>().value().leak_ref();
|
||||
@@ -488,7 +451,7 @@ UNMAP_AFTER_INIT void setup_serial_debug()
|
||||
// serial_debug will output all the dbgln() data to COM1 at
|
||||
// 8-N-1 57600 baud. this is particularly useful for debugging the boot
|
||||
// process on live hardware.
|
||||
if (kernel_cmdline.contains("serial_debug"sv)) {
|
||||
if (s_kernel_cmdline.contains("serial_debug"sv)) {
|
||||
set_serial_debug_enabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Leon Albrecht <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Arch/riscv64/CPU.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
BootInfo s_boot_info;
|
||||
|
||||
}
|
||||
@@ -6,13 +6,5 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Kernel/Prekernel/Prekernel.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
VALIDATE_IS_RISCV64()
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
extern BootInfo s_boot_info;
|
||||
|
||||
}
|
||||
+14
-11
@@ -142,10 +142,10 @@ static UNMAP_AFTER_INIT void insert_entries_for_memory_range(PageBumpAllocator&
|
||||
|
||||
static UNMAP_AFTER_INIT void setup_quickmap_page_table(PageBumpAllocator& allocator, u64* root_table)
|
||||
{
|
||||
auto kernel_pt1024_base = VirtualAddress { *adjust_by_mapping_base(&kernel_mapping_base) + KERNEL_PT1024_OFFSET };
|
||||
auto kernel_pt1024_base = VirtualAddress { *adjust_by_mapping_base(&g_boot_info.kernel_mapping_base) + KERNEL_PT1024_OFFSET };
|
||||
|
||||
auto quickmap_page_table = PhysicalAddress { bit_cast<PhysicalPtr>(insert_page_table(allocator, root_table, kernel_pt1024_base)) };
|
||||
*adjust_by_mapping_base(&boot_pd_kernel_pt1023) = bit_cast<PageTableEntry*>(quickmap_page_table.offset(calculate_physical_to_link_time_address_offset()).get());
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_pd_kernel_pt1023) = bit_cast<PageTableEntry*>(quickmap_page_table.offset(calculate_physical_to_link_time_address_offset()).get());
|
||||
}
|
||||
|
||||
static UNMAP_AFTER_INIT void build_mappings(PageBumpAllocator& allocator, u64* root_table)
|
||||
@@ -163,16 +163,16 @@ static UNMAP_AFTER_INIT void build_mappings(PageBumpAllocator& allocator, u64* r
|
||||
|
||||
static UNMAP_AFTER_INIT void setup_kernel_page_directory(u64* root_table)
|
||||
{
|
||||
auto kernel_page_directory = bit_cast<PhysicalPtr>(get_page_directory(root_table, VirtualAddress { *adjust_by_mapping_base(&kernel_mapping_base) }));
|
||||
auto kernel_page_directory = bit_cast<PhysicalPtr>(get_page_directory(root_table, VirtualAddress { *adjust_by_mapping_base(&g_boot_info.kernel_mapping_base) }));
|
||||
if (kernel_page_directory == 0)
|
||||
panic_without_mmu("Could not find kernel page directory!"sv);
|
||||
|
||||
*adjust_by_mapping_base(&boot_pd_kernel) = PhysicalAddress { kernel_page_directory };
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_pd_kernel) = PhysicalAddress { kernel_page_directory };
|
||||
|
||||
// There is no level 4 table in Sv39
|
||||
*adjust_by_mapping_base(&boot_pml4t) = PhysicalAddress { 0 };
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_pml4t) = PhysicalAddress { 0 };
|
||||
|
||||
*adjust_by_mapping_base(&boot_pdpt) = PhysicalAddress { bit_cast<PhysicalPtr>(root_table) };
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_pdpt) = PhysicalAddress { bit_cast<PhysicalPtr>(root_table) };
|
||||
}
|
||||
|
||||
// This function has to fit into one page as it will be identity mapped.
|
||||
@@ -239,11 +239,14 @@ static UNMAP_AFTER_INIT void setup_kernel_page_directory(u64* root_table)
|
||||
adjust_by_mapping_base(DeviceTree::s_fdt_storage)[o] = fdt_storage[o];
|
||||
}
|
||||
|
||||
*adjust_by_mapping_base(&physical_to_virtual_offset) = calculate_physical_to_link_time_address_offset();
|
||||
*adjust_by_mapping_base(&kernel_mapping_base) = KERNEL_MAPPING_BASE;
|
||||
*adjust_by_mapping_base(&kernel_load_base) = KERNEL_MAPPING_BASE;
|
||||
*adjust_by_mapping_base(&g_boot_info.boot_method) = BootMethod::PreInit;
|
||||
|
||||
*adjust_by_mapping_base(&s_boot_info) = { .mhartid = mhartid, .fdt_phys_addr = fdt_phys_addr };
|
||||
*adjust_by_mapping_base(&g_boot_info.flattened_devicetree_paddr) = PhysicalAddress { fdt_phys_addr };
|
||||
*adjust_by_mapping_base(&g_boot_info.physical_to_virtual_offset) = calculate_physical_to_link_time_address_offset();
|
||||
*adjust_by_mapping_base(&g_boot_info.kernel_mapping_base) = KERNEL_MAPPING_BASE;
|
||||
*adjust_by_mapping_base(&g_boot_info.kernel_load_base) = KERNEL_MAPPING_BASE;
|
||||
|
||||
*adjust_by_mapping_base(&g_boot_info.arch_specific.boot_hart_id) = mhartid;
|
||||
|
||||
PageBumpAllocator allocator(adjust_by_mapping_base(reinterpret_cast<u64*>(page_tables_phys_start)), adjust_by_mapping_base(reinterpret_cast<u64*>(page_tables_phys_end)));
|
||||
auto* root_table = allocator.take_page();
|
||||
@@ -267,7 +270,7 @@ static UNMAP_AFTER_INIT void setup_kernel_page_directory(u64* root_table)
|
||||
.MODE = RISCV64::CSR::SATP::Mode::Sv39,
|
||||
};
|
||||
|
||||
enable_paging(s_boot_info, bit_cast<FlatPtr>(satp), &enable_paging_level0_table[enable_paging_vpn_0]);
|
||||
enable_paging(g_boot_info, bit_cast<FlatPtr>(satp), &enable_paging_level0_table[enable_paging_vpn_0]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,7 @@ ErrorOr<NonnullLockRefPtr<PageDirectory>> PageDirectory::try_create_for_userspac
|
||||
directory->m_process = &process;
|
||||
|
||||
directory->m_directory_table = TRY(MM.allocate_physical_page());
|
||||
auto kernel_pd_index = (kernel_mapping_base >> VPN_2_OFFSET) & PAGE_TABLE_INDEX_MASK;
|
||||
auto kernel_pd_index = (g_boot_info.kernel_mapping_base >> VPN_2_OFFSET) & PAGE_TABLE_INDEX_MASK;
|
||||
for (size_t i = 0; i < kernel_pd_index; i++) {
|
||||
directory->m_directory_pages[i] = TRY(MM.allocate_physical_page());
|
||||
}
|
||||
@@ -97,10 +97,10 @@ PageDirectory::PageDirectory() = default;
|
||||
|
||||
UNMAP_AFTER_INIT void PageDirectory::allocate_kernel_directory()
|
||||
{
|
||||
dmesgln("MM: boot_pdpt @ {}", boot_pdpt);
|
||||
dmesgln("MM: boot_pd_kernel @ {}", boot_pd_kernel);
|
||||
m_directory_table = PhysicalRAMPage::create(boot_pdpt, MayReturnToFreeList::No);
|
||||
m_directory_pages[(kernel_mapping_base >> VPN_2_OFFSET) & PAGE_TABLE_INDEX_MASK] = PhysicalRAMPage::create(boot_pd_kernel, MayReturnToFreeList::No);
|
||||
dmesgln("MM: boot_pdpt @ {}", g_boot_info.boot_pdpt);
|
||||
dmesgln("MM: boot_pd_kernel @ {}", g_boot_info.boot_pd_kernel);
|
||||
m_directory_table = PhysicalRAMPage::create(g_boot_info.boot_pdpt, MayReturnToFreeList::No);
|
||||
m_directory_pages[(g_boot_info.kernel_mapping_base >> VPN_2_OFFSET) & PAGE_TABLE_INDEX_MASK] = PhysicalRAMPage::create(g_boot_info.boot_pd_kernel, MayReturnToFreeList::No);
|
||||
}
|
||||
|
||||
PageDirectory::~PageDirectory()
|
||||
|
||||
@@ -384,7 +384,7 @@ UNMAP_AFTER_INIT void APIC::setup_ap_boot_environment()
|
||||
auto const& idtr = get_idtr();
|
||||
*APIC_INIT_VAR_PTR(FlatPtr, apic_startup_region_ptr, ap_cpu_idtr) = FlatPtr(&idtr);
|
||||
|
||||
*APIC_INIT_VAR_PTR(FlatPtr, apic_startup_region_ptr, ap_cpu_kernel_map_base) = FlatPtr(kernel_mapping_base);
|
||||
*APIC_INIT_VAR_PTR(FlatPtr, apic_startup_region_ptr, ap_cpu_kernel_map_base) = FlatPtr(g_boot_info.kernel_mapping_base);
|
||||
*APIC_INIT_VAR_PTR(FlatPtr, apic_startup_region_ptr, ap_cpu_kernel_entry_function) = FlatPtr(&init_ap);
|
||||
|
||||
// Store the BSP's CR0 and CR4 values for the APs to use
|
||||
|
||||
@@ -70,12 +70,12 @@ ErrorOr<NonnullLockRefPtr<PageDirectory>> PageDirectory::try_create_for_userspac
|
||||
directory->m_pml4t = TRY(MM.allocate_physical_page());
|
||||
|
||||
directory->m_directory_table = TRY(MM.allocate_physical_page());
|
||||
auto kernel_pd_index = (kernel_mapping_base >> 30) & 0x1ffu;
|
||||
auto kernel_pd_index = (g_boot_info.kernel_mapping_base >> 30) & 0x1ffu;
|
||||
for (size_t i = 0; i < kernel_pd_index; i++) {
|
||||
directory->m_directory_pages[i] = TRY(MM.allocate_physical_page());
|
||||
}
|
||||
|
||||
// Share the top 1 GiB of kernel-only mappings (>=kernel_mapping_base)
|
||||
// Share the top 1 GiB of kernel-only mappings (>=g_boot_info.kernel_mapping_base)
|
||||
directory->m_directory_pages[kernel_pd_index] = MM.kernel_page_directory().m_directory_pages[kernel_pd_index];
|
||||
|
||||
{
|
||||
@@ -128,15 +128,17 @@ PageDirectory::PageDirectory() = default;
|
||||
|
||||
UNMAP_AFTER_INIT void PageDirectory::allocate_kernel_directory()
|
||||
{
|
||||
VERIFY(g_boot_info.boot_method == BootMethod::Multiboot1);
|
||||
|
||||
// Adopt the page tables already set up by boot.S
|
||||
dmesgln("MM: boot_pml4t @ {}", boot_pml4t);
|
||||
m_pml4t = PhysicalRAMPage::create(boot_pml4t, 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 = PhysicalRAMPage::create(boot_pdpt, MayReturnToFreeList::No);
|
||||
m_directory_pages[0] = PhysicalRAMPage::create(boot_pd0, MayReturnToFreeList::No);
|
||||
m_directory_pages[(kernel_mapping_base >> 30) & 0x1ff] = PhysicalRAMPage::create(boot_pd_kernel, MayReturnToFreeList::No);
|
||||
dmesgln("MM: boot_pml4t @ {}", g_boot_info.boot_pml4t);
|
||||
m_pml4t = PhysicalRAMPage::create(g_boot_info.boot_pml4t, MayReturnToFreeList::No);
|
||||
dmesgln("MM: boot_pdpt @ {}", g_boot_info.boot_pdpt);
|
||||
dmesgln("MM: boot_pd0 @ {}", g_boot_info.boot_method_specific.multiboot1.boot_pd0);
|
||||
dmesgln("MM: boot_pd_kernel @ {}", g_boot_info.boot_pd_kernel);
|
||||
m_directory_table = PhysicalRAMPage::create(g_boot_info.boot_pdpt, MayReturnToFreeList::No);
|
||||
m_directory_pages[0] = PhysicalRAMPage::create(g_boot_info.boot_method_specific.multiboot1.boot_pd0, MayReturnToFreeList::No);
|
||||
m_directory_pages[(g_boot_info.kernel_mapping_base >> 30) & 0x1ff] = PhysicalRAMPage::create(g_boot_info.boot_pd_kernel, MayReturnToFreeList::No);
|
||||
}
|
||||
|
||||
PageDirectory::~PageDirectory()
|
||||
|
||||
+5
-33
@@ -6,38 +6,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/StringView.h>
|
||||
#include <Kernel/Boot/Multiboot.h>
|
||||
#include <Kernel/Memory/PhysicalAddress.h>
|
||||
#include <Kernel/Memory/VirtualAddress.h>
|
||||
#include <Kernel/Prekernel/Prekernel.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
extern BootInfo g_boot_info;
|
||||
|
||||
namespace Kernel::Memory {
|
||||
class PageTableEntry;
|
||||
}
|
||||
|
||||
extern "C" PhysicalAddress start_of_prekernel_image;
|
||||
extern "C" PhysicalAddress end_of_prekernel_image;
|
||||
extern "C" size_t physical_to_virtual_offset;
|
||||
extern "C" FlatPtr kernel_mapping_base;
|
||||
extern "C" FlatPtr kernel_load_base;
|
||||
#if ARCH(X86_64)
|
||||
extern "C" u32 gdt64ptr;
|
||||
extern "C" u16 code64_sel;
|
||||
#endif
|
||||
extern "C" PhysicalAddress boot_pml4t;
|
||||
extern "C" PhysicalAddress boot_pdpt;
|
||||
extern "C" PhysicalAddress boot_pd0;
|
||||
extern "C" PhysicalAddress boot_pd_kernel;
|
||||
extern "C" Kernel::Memory::PageTableEntry* boot_pd_kernel_pt1023;
|
||||
extern "C" StringView kernel_cmdline;
|
||||
extern "C" u32 multiboot_flags;
|
||||
extern "C" multiboot_memory_map_t* multiboot_memory_map;
|
||||
extern "C" size_t multiboot_memory_map_count;
|
||||
extern "C" PhysicalAddress multiboot_module_physical_ptr;
|
||||
extern "C" size_t multiboot_module_length;
|
||||
extern "C" PhysicalAddress multiboot_framebuffer_addr;
|
||||
extern "C" u32 multiboot_framebuffer_pitch;
|
||||
extern "C" u32 multiboot_framebuffer_width;
|
||||
extern "C" u32 multiboot_framebuffer_height;
|
||||
extern "C" u8 multiboot_framebuffer_bpp;
|
||||
extern "C" u8 multiboot_framebuffer_type;
|
||||
@@ -537,7 +537,6 @@ elseif("${SERENITY_ARCH}" STREQUAL "riscv64")
|
||||
|
||||
Arch/riscv64/archctl.cpp
|
||||
Arch/riscv64/boot.S
|
||||
Arch/riscv64/CPU.cpp
|
||||
Arch/riscv64/CurrentTime.cpp
|
||||
Arch/riscv64/DebugOutput.cpp
|
||||
Arch/riscv64/Delay.cpp
|
||||
|
||||
@@ -119,14 +119,14 @@ UNMAP_AFTER_INIT ErrorOr<void> GraphicsManagement::determine_and_initialize_grap
|
||||
|
||||
UNMAP_AFTER_INIT void GraphicsManagement::initialize_preset_resolution_generic_display_connector()
|
||||
{
|
||||
VERIFY(!multiboot_framebuffer_addr.is_null());
|
||||
VERIFY(multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB);
|
||||
VERIFY(!g_boot_info.boot_framebuffer.paddr.is_null());
|
||||
VERIFY(g_boot_info.boot_framebuffer.type == BootFramebufferType::BGRx8888);
|
||||
dmesgln("Graphics: Using a preset resolution from the bootloader, without knowing the PCI device");
|
||||
m_preset_resolution_generic_display_connector = MUST(GenericDisplayConnector::create_with_preset_resolution(
|
||||
multiboot_framebuffer_addr,
|
||||
multiboot_framebuffer_width,
|
||||
multiboot_framebuffer_height,
|
||||
multiboot_framebuffer_pitch));
|
||||
g_boot_info.boot_framebuffer.paddr,
|
||||
g_boot_info.boot_framebuffer.width,
|
||||
g_boot_info.boot_framebuffer.height,
|
||||
g_boot_info.boot_framebuffer.pitch));
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
|
||||
@@ -163,8 +163,8 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool boot_framebuffer_usable = !multiboot_framebuffer_addr.is_null()
|
||||
&& multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
|
||||
bool boot_framebuffer_usable = !g_boot_info.boot_framebuffer.paddr.is_null()
|
||||
&& g_boot_info.boot_framebuffer.type == BootFramebufferType::BGRx8888;
|
||||
|
||||
bool use_boot_framebuffer = graphics_subsystem_mode == CommandLine::GraphicsSubsystemMode::Limited
|
||||
&& boot_framebuffer_usable;
|
||||
@@ -212,8 +212,8 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
|
||||
// Note: If we failed to find any graphics device to be used natively, but the
|
||||
// bootloader prepared a framebuffer for us to use, then just create a DisplayConnector
|
||||
// for it so the user can still use the system in graphics mode.
|
||||
// Prekernel sets the framebuffer address to 0 if MULTIBOOT_INFO_FRAMEBUFFER_INFO
|
||||
// is not present, as there is likely never a valid framebuffer at this physical address.
|
||||
// Prekernel sets the framebuffer address to 0 if no framebuffer is present,
|
||||
// as there is likely never a valid framebuffer at this physical address.
|
||||
// Note: We only support RGB framebuffers. Any other format besides RGBX (and RGBA) or BGRX (and BGRA) is obsolete
|
||||
// and is not useful for us.
|
||||
if (m_graphics_devices.is_empty() && boot_framebuffer_usable) {
|
||||
|
||||
@@ -55,7 +55,7 @@ UNMAP_AFTER_INIT NonnullRefPtr<SysFSGlobalKernelStatsDirectory> SysFSGlobalKerne
|
||||
|
||||
{
|
||||
auto builder = TRY(KBufferBuilder::try_create());
|
||||
MUST(builder.appendff("{}", kernel_load_base));
|
||||
MUST(builder.appendff("{}", g_boot_info.kernel_load_base));
|
||||
auto load_base_buffer = builder.build();
|
||||
VERIFY(load_base_buffer);
|
||||
list.append(SysFSSystemConstantInformation::must_create(*global_kernel_stats_directory, load_base_buffer.release_nonnull(), S_IRUSR, SysFSSystemConstantInformation::ReadableByJailedProcesses::No, SysFSSystemConstantInformation::NodeName::LoadBase));
|
||||
|
||||
+6
-6
@@ -88,9 +88,9 @@ UNMAP_AFTER_INIT static void load_kernel_symbols_from_data(Bytes buffer)
|
||||
|
||||
// FIXME: Remove this ifdef once the aarch64 kernel is loaded by the Prekernel.
|
||||
// Currently, the aarch64 kernel is linked at a high virtual memory address, instead
|
||||
// of zero, so the address of a symbol does not need to be offset by the kernel_load_base.
|
||||
// of zero, so the address of a symbol does not need to be offset by the g_boot_info.kernel_load_base.
|
||||
#if ARCH(X86_64)
|
||||
ksym.address = kernel_load_base + address;
|
||||
ksym.address = g_boot_info.kernel_load_base + address;
|
||||
#elif ARCH(AARCH64) || ARCH(RISCV64)
|
||||
ksym.address = address;
|
||||
#else
|
||||
@@ -137,7 +137,7 @@ NEVER_INLINE static void dump_backtrace_impl(FlatPtr frame_pointer, bool use_ksy
|
||||
MUST(AK::unwind_stack_from_frame_pointer(
|
||||
frame_pointer,
|
||||
[](FlatPtr address) -> ErrorOr<FlatPtr> {
|
||||
if (address < kernel_mapping_base)
|
||||
if (address < g_boot_info.kernel_mapping_base)
|
||||
return EINVAL;
|
||||
|
||||
FlatPtr value;
|
||||
@@ -168,14 +168,14 @@ NEVER_INLINE static void dump_backtrace_impl(FlatPtr frame_pointer, bool use_ksy
|
||||
if (!symbol.address)
|
||||
break;
|
||||
if (!symbol.symbol) {
|
||||
PRINT_LINE("Kernel + {:p}", symbol.address - kernel_load_base);
|
||||
PRINT_LINE("Kernel + {:p}", symbol.address - g_boot_info.kernel_load_base);
|
||||
continue;
|
||||
}
|
||||
size_t offset = symbol.address - symbol.symbol->address;
|
||||
if (symbol.symbol->address == g_highest_kernel_symbol_address && offset > 4096)
|
||||
PRINT_LINE("Kernel + {:p}", symbol.address - kernel_load_base);
|
||||
PRINT_LINE("Kernel + {:p}", symbol.address - g_boot_info.kernel_load_base);
|
||||
else
|
||||
PRINT_LINE("Kernel + {:p} {} +{:#x}", symbol.address - kernel_load_base, symbol.symbol->name, offset);
|
||||
PRINT_LINE("Kernel + {:p} {} +{:#x}", symbol.address - g_boot_info.kernel_load_base, symbol.symbol->name, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,11 +76,11 @@ bool MemoryManager::is_initialized()
|
||||
static UNMAP_AFTER_INIT VirtualRange kernel_virtual_range()
|
||||
{
|
||||
#if ARCH(X86_64)
|
||||
size_t kernel_range_start = kernel_mapping_base + 2 * MiB; // The first 2 MiB are used for mapping the pre-kernel
|
||||
size_t kernel_range_start = g_boot_info.kernel_mapping_base + 2 * MiB; // The first 2 MiB are used for mapping the pre-kernel
|
||||
return VirtualRange { VirtualAddress(kernel_range_start), KERNEL_PD_END - kernel_range_start };
|
||||
#elif ARCH(AARCH64) || ARCH(RISCV64)
|
||||
// NOTE: This is not the same as x86_64, because the aarch64 and riscv64 kernels currently don't use the pre-kernel.
|
||||
return VirtualRange { VirtualAddress(kernel_mapping_base), KERNEL_PD_END - kernel_mapping_base };
|
||||
return VirtualRange { VirtualAddress(g_boot_info.kernel_mapping_base), KERNEL_PD_END - g_boot_info.kernel_mapping_base };
|
||||
#else
|
||||
# error Unknown architecture
|
||||
#endif
|
||||
@@ -140,8 +140,10 @@ UNMAP_AFTER_INIT void MemoryManager::unmap_prekernel()
|
||||
{
|
||||
SpinlockLocker page_lock(kernel_page_directory().get_lock());
|
||||
|
||||
auto start = start_of_prekernel_image.page_base().get();
|
||||
auto end = end_of_prekernel_image.page_base().get();
|
||||
VERIFY(g_boot_info.boot_method == BootMethod::Multiboot1);
|
||||
|
||||
auto start = g_boot_info.boot_method_specific.multiboot1.start_of_prekernel_image.page_base().get();
|
||||
auto end = g_boot_info.boot_method_specific.multiboot1.end_of_prekernel_image.page_base().get();
|
||||
|
||||
for (auto i = start; i <= end; i += PAGE_SIZE)
|
||||
release_pte(kernel_page_directory(), VirtualAddress(i), i == end ? IsLastPTERelease::Yes : IsLastPTERelease::No);
|
||||
@@ -577,15 +579,17 @@ UNMAP_AFTER_INIT void MemoryManager::parse_memory_map_fdt(MemoryManager::GlobalD
|
||||
|
||||
UNMAP_AFTER_INIT void MemoryManager::parse_memory_map_multiboot(MemoryManager::GlobalData& global_data)
|
||||
{
|
||||
VERIFY(g_boot_info.boot_method == BootMethod::Multiboot1);
|
||||
|
||||
// Register used memory regions that we know of.
|
||||
if (multiboot_flags & 0x4 && !multiboot_module_physical_ptr.is_null()) {
|
||||
dmesgln("MM: Multiboot module @ {}, length={}", multiboot_module_physical_ptr, multiboot_module_length);
|
||||
VERIFY(multiboot_module_length != 0);
|
||||
global_data.used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::BootModule, multiboot_module_physical_ptr, multiboot_module_physical_ptr.offset(multiboot_module_length) });
|
||||
if (g_boot_info.boot_method_specific.multiboot1.flags & 0x4 && !g_boot_info.boot_method_specific.multiboot1.module_physical_ptr.is_null()) {
|
||||
dmesgln("MM: Multiboot module @ {}, length={}", g_boot_info.boot_method_specific.multiboot1.module_physical_ptr, g_boot_info.boot_method_specific.multiboot1.module_length);
|
||||
VERIFY(g_boot_info.boot_method_specific.multiboot1.module_length != 0);
|
||||
global_data.used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::BootModule, g_boot_info.boot_method_specific.multiboot1.module_physical_ptr, g_boot_info.boot_method_specific.multiboot1.module_physical_ptr.offset(g_boot_info.boot_method_specific.multiboot1.module_length) });
|
||||
}
|
||||
|
||||
auto* mmap_begin = multiboot_memory_map;
|
||||
auto* mmap_end = multiboot_memory_map + multiboot_memory_map_count;
|
||||
auto const* mmap_begin = g_boot_info.boot_method_specific.multiboot1.memory_map;
|
||||
auto const* mmap_end = g_boot_info.boot_method_specific.multiboot1.memory_map + g_boot_info.boot_method_specific.multiboot1.memory_map_count;
|
||||
|
||||
struct ContiguousPhysicalVirtualRange {
|
||||
PhysicalAddress lower;
|
||||
@@ -593,15 +597,11 @@ UNMAP_AFTER_INIT void MemoryManager::parse_memory_map_multiboot(MemoryManager::G
|
||||
};
|
||||
|
||||
Optional<ContiguousPhysicalVirtualRange> last_contiguous_physical_range;
|
||||
for (auto* mmap = mmap_begin; mmap < mmap_end; mmap++) {
|
||||
for (auto const* mmap = mmap_begin; mmap < mmap_end; mmap++) {
|
||||
// We have to copy these onto the stack, because we take a reference to these when printing them out,
|
||||
// and doing so on a packed struct field is UB.
|
||||
auto address = mmap->addr;
|
||||
auto length = mmap->len;
|
||||
ArmedScopeGuard write_back_guard = [&]() {
|
||||
mmap->addr = address;
|
||||
mmap->len = length;
|
||||
};
|
||||
auto const address = mmap->addr;
|
||||
auto const length = mmap->len;
|
||||
|
||||
dmesgln("MM: Multiboot mmap: address={:p}, length={}, type={}", address, length, mmap->type);
|
||||
|
||||
@@ -663,14 +663,11 @@ UNMAP_AFTER_INIT void MemoryManager::initialize_physical_pages()
|
||||
highest_physical_address = range_end;
|
||||
}
|
||||
|
||||
#if ARCH(X86_64)
|
||||
// Map multiboot framebuffer
|
||||
if ((multiboot_flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) && !multiboot_framebuffer_addr.is_null() && multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) {
|
||||
PhysicalAddress multiboot_framebuffer_addr_end = multiboot_framebuffer_addr.offset(multiboot_framebuffer_height * multiboot_framebuffer_pitch);
|
||||
if (multiboot_framebuffer_addr_end > highest_physical_address)
|
||||
highest_physical_address = multiboot_framebuffer_addr_end;
|
||||
if (!g_boot_info.boot_framebuffer.paddr.is_null() && g_boot_info.boot_framebuffer.type != BootFramebufferType::None) {
|
||||
PhysicalAddress boot_framebuffer_paddr_end = g_boot_info.boot_framebuffer.paddr.offset(g_boot_info.boot_framebuffer.height * g_boot_info.boot_framebuffer.pitch);
|
||||
if (boot_framebuffer_paddr_end > highest_physical_address)
|
||||
highest_physical_address = boot_framebuffer_paddr_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Calculate how many total physical pages the array will have
|
||||
m_physical_page_entries_count = PhysicalAddress::physical_page_index(highest_physical_address.get()) + 1;
|
||||
@@ -764,7 +761,7 @@ UNMAP_AFTER_INIT void MemoryManager::initialize_physical_pages()
|
||||
|
||||
// Hook the page table into the kernel page directory
|
||||
u32 page_directory_index = (virtual_page_base_for_this_pt >> 21) & 0x1ff;
|
||||
auto* pd = reinterpret_cast<PageDirectoryEntry*>(quickmap_page(boot_pd_kernel));
|
||||
auto* pd = reinterpret_cast<PageDirectoryEntry*>(quickmap_page(g_boot_info.boot_pd_kernel));
|
||||
PageDirectoryEntry& pde = pd[page_directory_index];
|
||||
|
||||
VERIFY(!pde.is_present()); // Nothing should be using this PD yet
|
||||
@@ -1386,7 +1383,7 @@ PageDirectoryEntry* MemoryManager::quickmap_pd(PageDirectory& directory, size_t
|
||||
VirtualAddress vaddr(KERNEL_QUICKMAP_PD_PER_CPU_BASE + Processor::current_id() * PAGE_SIZE);
|
||||
size_t pte_index = (vaddr.get() - KERNEL_PT1024_BASE) / PAGE_SIZE;
|
||||
|
||||
auto& pte = boot_pd_kernel_pt1023[pte_index];
|
||||
auto& pte = g_boot_info.boot_pd_kernel_pt1023[pte_index];
|
||||
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());
|
||||
@@ -1405,7 +1402,7 @@ PageTableEntry* MemoryManager::quickmap_pt(PhysicalAddress pt_paddr)
|
||||
VirtualAddress vaddr(KERNEL_QUICKMAP_PT_PER_CPU_BASE + Processor::current_id() * PAGE_SIZE);
|
||||
size_t pte_index = (vaddr.get() - KERNEL_PT1024_BASE) / PAGE_SIZE;
|
||||
|
||||
auto& pte = ((PageTableEntry*)boot_pd_kernel_pt1023)[pte_index];
|
||||
auto& pte = g_boot_info.boot_pd_kernel_pt1023[pte_index];
|
||||
if (pte.physical_page_base() != pt_paddr.get()) {
|
||||
pte.set_physical_page_base(pt_paddr.get());
|
||||
pte.set_present(true);
|
||||
@@ -1425,7 +1422,7 @@ u8* MemoryManager::quickmap_page(PhysicalAddress const& physical_address)
|
||||
VirtualAddress vaddr(KERNEL_QUICKMAP_PER_CPU_BASE + Processor::current_id() * PAGE_SIZE);
|
||||
u32 pte_idx = (vaddr.get() - KERNEL_PT1024_BASE) / PAGE_SIZE;
|
||||
|
||||
auto& pte = ((PageTableEntry*)boot_pd_kernel_pt1023)[pte_idx];
|
||||
auto& pte = g_boot_info.boot_pd_kernel_pt1023[pte_idx];
|
||||
if (pte.physical_page_base() != physical_address.get()) {
|
||||
pte.set_physical_page_base(physical_address.get());
|
||||
pte.set_present(true);
|
||||
@@ -1443,7 +1440,7 @@ void MemoryManager::unquickmap_page()
|
||||
VERIFY(mm_data.m_quickmap_in_use.is_locked());
|
||||
VirtualAddress vaddr(KERNEL_QUICKMAP_PER_CPU_BASE + Processor::current_id() * PAGE_SIZE);
|
||||
u32 pte_idx = (vaddr.get() - KERNEL_PT1024_BASE) / PAGE_SIZE;
|
||||
auto& pte = ((PageTableEntry*)boot_pd_kernel_pt1023)[pte_idx];
|
||||
auto& pte = g_boot_info.boot_pd_kernel_pt1023[pte_idx];
|
||||
pte.clear();
|
||||
flush_tlb_local(vaddr);
|
||||
mm_data.m_quickmap_in_use.unlock(mm_data.m_quickmap_previous_interrupts_state);
|
||||
|
||||
@@ -36,7 +36,7 @@ constexpr FlatPtr page_round_down(FlatPtr x)
|
||||
|
||||
inline FlatPtr virtual_to_low_physical(FlatPtr virtual_)
|
||||
{
|
||||
return virtual_ - physical_to_virtual_offset;
|
||||
return virtual_ - g_boot_info.physical_to_virtual_offset;
|
||||
}
|
||||
|
||||
enum class UsedMemoryRangeType {
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
ErrorOr<void> set_write_combine(bool);
|
||||
|
||||
[[nodiscard]] bool is_user() const { return !is_kernel(); }
|
||||
[[nodiscard]] bool is_kernel() const { return vaddr().get() < USER_RANGE_BASE || vaddr().get() >= kernel_mapping_base; }
|
||||
[[nodiscard]] bool is_kernel() const { return vaddr().get() < USER_RANGE_BASE || vaddr().get() >= g_boot_info.kernel_mapping_base; }
|
||||
|
||||
PageFaultResponse handle_fault(PageFault const&);
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Sönke Holz <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Platform.h>
|
||||
|
||||
#if ARCH(X86_64)
|
||||
# include <Kernel/Prekernel/Arch/x86_64/ArchSpecificBootInfo.h>
|
||||
#elif ARCH(AARCH64)
|
||||
# include <Kernel/Prekernel/Arch/aarch64/ArchSpecificBootInfo.h>
|
||||
#elif ARCH(RISCV64)
|
||||
# include <Kernel/Prekernel/Arch/riscv64/ArchSpecificBootInfo.h>
|
||||
#else
|
||||
# error Unknown architecture
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Sönke Holz <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
VALIDATE_IS_AARCH64()
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
struct ArchSpecificBootInfo {
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Sönke Holz <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
VALIDATE_IS_RISCV64()
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
struct ArchSpecificBootInfo {
|
||||
FlatPtr boot_hart_id;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Sönke Holz <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
VALIDATE_IS_X86()
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
struct ArchSpecificBootInfo {
|
||||
u32 gdt64ptr;
|
||||
u16 code64_sel;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Gunnar Beutner <[email protected]>
|
||||
* Copyright (c) 2024, Sönke Holz <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
@@ -10,6 +11,7 @@
|
||||
# include <Kernel/Boot/Multiboot.h>
|
||||
# include <Kernel/Memory/PhysicalAddress.h>
|
||||
# include <Kernel/Memory/VirtualAddress.h>
|
||||
# include <Kernel/Prekernel/Arch/ArchSpecificBootInfo.h>
|
||||
#endif
|
||||
|
||||
#define MAX_KERNEL_SIZE 0x4000000
|
||||
@@ -25,41 +27,73 @@ extern "C" multiboot_info_t* multiboot_info_ptr;
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
# if ARCH(X86_64)
|
||||
struct [[gnu::packed]] BootInfo {
|
||||
u32 start_of_prekernel_image;
|
||||
u32 end_of_prekernel_image;
|
||||
u64 physical_to_virtual_offset;
|
||||
u64 kernel_mapping_base;
|
||||
u64 kernel_load_base;
|
||||
u32 gdt64ptr;
|
||||
u16 code64_sel;
|
||||
u32 boot_pml4t;
|
||||
u32 boot_pdpt;
|
||||
u32 boot_pd0;
|
||||
u32 boot_pd_kernel;
|
||||
u64 boot_pd_kernel_pt1023;
|
||||
u64 kernel_cmdline;
|
||||
u32 multiboot_flags;
|
||||
u64 multiboot_memory_map;
|
||||
u32 multiboot_memory_map_count;
|
||||
u64 multiboot_module_physical_ptr;
|
||||
u32 multiboot_module_length;
|
||||
u64 multiboot_framebuffer_addr;
|
||||
u32 multiboot_framebuffer_pitch;
|
||||
u32 multiboot_framebuffer_width;
|
||||
u32 multiboot_framebuffer_height;
|
||||
u8 multiboot_framebuffer_bpp;
|
||||
u8 multiboot_framebuffer_type;
|
||||
namespace Memory {
|
||||
class PageTableEntry;
|
||||
}
|
||||
|
||||
struct Multiboot1BootInfo {
|
||||
u32 flags { 0 };
|
||||
multiboot_memory_map_t const* memory_map { 0 };
|
||||
u32 memory_map_count { 0 };
|
||||
PhysicalAddress module_physical_ptr { 0 };
|
||||
u32 module_length { 0 };
|
||||
|
||||
PhysicalAddress start_of_prekernel_image { 0 };
|
||||
PhysicalAddress end_of_prekernel_image { 0 };
|
||||
|
||||
PhysicalAddress boot_pd0 { 0 };
|
||||
};
|
||||
# elif ARCH(AARCH64)
|
||||
struct BootInfo { };
|
||||
# elif ARCH(RISCV64)
|
||||
|
||||
struct PreInitBootInfo {
|
||||
};
|
||||
|
||||
enum class BootMethod {
|
||||
Multiboot1,
|
||||
PreInit,
|
||||
};
|
||||
|
||||
enum class BootFramebufferType {
|
||||
None,
|
||||
BGRx8888,
|
||||
};
|
||||
|
||||
struct BootFramebufferInfo {
|
||||
PhysicalAddress paddr { 0 };
|
||||
size_t pitch { 0 };
|
||||
size_t width { 0 };
|
||||
size_t height { 0 };
|
||||
u8 bpp { 0 };
|
||||
BootFramebufferType type { BootFramebufferType::None };
|
||||
};
|
||||
|
||||
union BootMethodSpecificBootInfo {
|
||||
PreInitBootInfo pre_init {};
|
||||
Multiboot1BootInfo multiboot1;
|
||||
};
|
||||
|
||||
struct BootInfo {
|
||||
FlatPtr mhartid;
|
||||
PhysicalPtr fdt_phys_addr;
|
||||
ArchSpecificBootInfo arch_specific {};
|
||||
|
||||
BootMethodSpecificBootInfo boot_method_specific {};
|
||||
BootMethod boot_method { BootMethod::PreInit };
|
||||
|
||||
PhysicalAddress flattened_devicetree_paddr { 0 };
|
||||
size_t flattened_devicetree_size { 0 };
|
||||
|
||||
size_t physical_to_virtual_offset { 0 };
|
||||
FlatPtr kernel_mapping_base { 0 };
|
||||
FlatPtr kernel_load_base { 0 };
|
||||
|
||||
PhysicalAddress boot_pml4t { 0 };
|
||||
PhysicalAddress boot_pdpt { 0 };
|
||||
PhysicalAddress boot_pd_kernel { 0 };
|
||||
|
||||
Memory::PageTableEntry* boot_pd_kernel_pt1023 { 0 };
|
||||
|
||||
StringView cmdline;
|
||||
|
||||
BootFramebufferInfo boot_framebuffer {};
|
||||
};
|
||||
# endif
|
||||
|
||||
}
|
||||
#endif
|
||||
+31
-21
@@ -175,22 +175,30 @@ extern "C" [[noreturn]] void init()
|
||||
return (decltype(ptr))((FlatPtr)ptr + kernel_mapping_base);
|
||||
};
|
||||
|
||||
info.multiboot_flags = multiboot_info_ptr->flags;
|
||||
info.multiboot_memory_map = adjust_by_mapping_base((FlatPtr)multiboot_info_ptr->mmap_addr);
|
||||
info.multiboot_memory_map_count = multiboot_info_ptr->mmap_length / sizeof(multiboot_memory_map_t);
|
||||
info.boot_method = BootMethod::Multiboot1;
|
||||
info.boot_method_specific.pre_init.~PreInitBootInfo();
|
||||
new (&info.boot_method_specific.multiboot1) Multiboot1BootInfo;
|
||||
|
||||
info.boot_method_specific.multiboot1.flags = multiboot_info_ptr->flags;
|
||||
info.boot_method_specific.multiboot1.memory_map = bit_cast<multiboot_memory_map_t const*>(adjust_by_mapping_base((FlatPtr)multiboot_info_ptr->mmap_addr));
|
||||
info.boot_method_specific.multiboot1.memory_map_count = multiboot_info_ptr->mmap_length / sizeof(multiboot_memory_map_t);
|
||||
|
||||
if (initrd_module_start != 0 && initrd_module_end != 0) {
|
||||
info.multiboot_module_physical_ptr = initrd_module_start;
|
||||
info.multiboot_module_length = initrd_module_end - initrd_module_start;
|
||||
info.boot_method_specific.multiboot1.module_physical_ptr = PhysicalAddress { initrd_module_start };
|
||||
info.boot_method_specific.multiboot1.module_length = initrd_module_end - initrd_module_start;
|
||||
}
|
||||
|
||||
if ((multiboot_info_ptr->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) != 0) {
|
||||
info.multiboot_framebuffer_addr = multiboot_info_ptr->framebuffer_addr;
|
||||
info.multiboot_framebuffer_pitch = multiboot_info_ptr->framebuffer_pitch;
|
||||
info.multiboot_framebuffer_width = multiboot_info_ptr->framebuffer_width;
|
||||
info.multiboot_framebuffer_height = multiboot_info_ptr->framebuffer_height;
|
||||
info.multiboot_framebuffer_bpp = multiboot_info_ptr->framebuffer_bpp;
|
||||
info.multiboot_framebuffer_type = multiboot_info_ptr->framebuffer_type;
|
||||
info.boot_framebuffer.paddr = PhysicalAddress { multiboot_info_ptr->framebuffer_addr };
|
||||
info.boot_framebuffer.pitch = multiboot_info_ptr->framebuffer_pitch;
|
||||
info.boot_framebuffer.width = multiboot_info_ptr->framebuffer_width;
|
||||
info.boot_framebuffer.height = multiboot_info_ptr->framebuffer_height;
|
||||
info.boot_framebuffer.bpp = multiboot_info_ptr->framebuffer_bpp;
|
||||
|
||||
if (multiboot_info_ptr->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB)
|
||||
info.boot_framebuffer.type = BootFramebufferType::BGRx8888;
|
||||
else
|
||||
info.boot_framebuffer.type = BootFramebufferType::None;
|
||||
}
|
||||
|
||||
reload_cr3();
|
||||
@@ -213,21 +221,23 @@ extern "C" [[noreturn]] void init()
|
||||
__builtin_memset((u8*)kernel_load_base + kernel_program_header.p_vaddr + kernel_program_header.p_filesz, 0, kernel_program_header.p_memsz - kernel_program_header.p_filesz);
|
||||
}
|
||||
|
||||
info.start_of_prekernel_image = (PhysicalPtr)start_of_prekernel_image;
|
||||
info.end_of_prekernel_image = (PhysicalPtr)end_of_prekernel_image;
|
||||
info.boot_method_specific.multiboot1.start_of_prekernel_image = PhysicalAddress { bit_cast<PhysicalPtr>(+start_of_prekernel_image) };
|
||||
info.boot_method_specific.multiboot1.end_of_prekernel_image = PhysicalAddress { bit_cast<PhysicalPtr>(+end_of_prekernel_image) };
|
||||
info.physical_to_virtual_offset = kernel_load_base - kernel_physical_base;
|
||||
info.kernel_mapping_base = kernel_mapping_base;
|
||||
info.kernel_load_base = kernel_load_base;
|
||||
#if ARCH(X86_64)
|
||||
info.gdt64ptr = (PhysicalPtr)gdt64ptr;
|
||||
info.code64_sel = code64_sel;
|
||||
info.boot_pml4t = (PhysicalPtr)boot_pml4t;
|
||||
info.arch_specific.gdt64ptr = (PhysicalPtr)gdt64ptr;
|
||||
info.arch_specific.code64_sel = code64_sel;
|
||||
info.boot_pml4t = PhysicalAddress { bit_cast<PhysicalPtr>(+boot_pml4t) };
|
||||
#endif
|
||||
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_mapping_base(boot_pd_kernel_pt1023);
|
||||
info.kernel_cmdline = (FlatPtr)adjust_by_mapping_base(kernel_cmdline);
|
||||
info.boot_pdpt = PhysicalAddress { bit_cast<PhysicalPtr>(+boot_pdpt) };
|
||||
info.boot_method_specific.multiboot1.boot_pd0 = PhysicalAddress { bit_cast<PhysicalPtr>(+boot_pd0) };
|
||||
info.boot_pd_kernel = PhysicalAddress { bit_cast<PhysicalPtr>(+boot_pd_kernel) };
|
||||
info.boot_pd_kernel_pt1023 = bit_cast<Memory::PageTableEntry*>(adjust_by_mapping_base(boot_pd_kernel_pt1023));
|
||||
|
||||
char const* cmdline_ptr = bit_cast<char const*>(adjust_by_mapping_base(kernel_cmdline));
|
||||
info.cmdline = StringView { cmdline_ptr, __builtin_strlen(cmdline_ptr) };
|
||||
|
||||
asm(
|
||||
"mov %0, %%rax\n"
|
||||
|
||||
+3
-3
@@ -17,9 +17,9 @@
|
||||
|
||||
#define KERNEL_MAPPING_BASE 0x2000000000
|
||||
|
||||
#define KERNEL_PD_END (kernel_mapping_base + KERNEL_PD_SIZE)
|
||||
#define KERNEL_PD_END (g_boot_info.kernel_mapping_base + KERNEL_PD_SIZE)
|
||||
#define KERNEL_PT1024_OFFSET 0x3FE00000
|
||||
#define KERNEL_PT1024_BASE (kernel_mapping_base + KERNEL_PT1024_OFFSET)
|
||||
#define KERNEL_PT1024_BASE (g_boot_info.kernel_mapping_base + KERNEL_PT1024_OFFSET)
|
||||
|
||||
#define KERNEL_MAX_CPU_COUNT 64
|
||||
#define KERNEL_QUICKMAP_PT_PER_CPU_BASE (KERNEL_PT1024_BASE + (1 * KERNEL_MAX_CPU_COUNT * PAGE_SIZE))
|
||||
@@ -27,4 +27,4 @@
|
||||
#define KERNEL_QUICKMAP_PER_CPU_BASE (KERNEL_PT1024_BASE + (3 * KERNEL_MAX_CPU_COUNT * PAGE_SIZE))
|
||||
|
||||
#define USER_RANGE_BASE 0x10000
|
||||
#define USER_RANGE_CEILING (kernel_mapping_base - 0x2000000)
|
||||
#define USER_RANGE_CEILING (g_boot_info.kernel_mapping_base - 0x2000000)
|
||||
@@ -98,7 +98,7 @@ static bool kasan_initialized = false;
|
||||
void init(FlatPtr shadow_base)
|
||||
{
|
||||
kasan_shadow_base = shadow_base;
|
||||
kasan_shadow_offset = shadow_base - (kernel_mapping_base >> kasan_shadow_scale_offset);
|
||||
kasan_shadow_offset = shadow_base - (g_boot_info.kernel_mapping_base >> kasan_shadow_scale_offset);
|
||||
kasan_initialized = true;
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ static void shadow_va_check(FlatPtr address, size_t size, AccessType access_type
|
||||
return;
|
||||
if (!kasan_initialized) [[unlikely]]
|
||||
return;
|
||||
if (address < kernel_mapping_base || address >= kasan_shadow_base) [[unlikely]]
|
||||
if (address < g_boot_info.kernel_mapping_base || address >= kasan_shadow_base) [[unlikely]]
|
||||
return;
|
||||
|
||||
bool valid = false;
|
||||
|
||||
@@ -535,7 +535,7 @@ void Process::crash(int signal, Optional<RegisterState const&> regs, bool out_of
|
||||
if (out_of_memory) {
|
||||
dbgln("\033[31;1mOut of memory\033[m, killing: {}", *this);
|
||||
} else {
|
||||
if (ip >= kernel_load_base && g_kernel_symbols_available.was_set()) {
|
||||
if (ip >= g_boot_info.kernel_load_base && g_kernel_symbols_available.was_set()) {
|
||||
auto const* symbol = symbolicate_kernel_address(ip);
|
||||
dbgln("\033[31;1m{:p} {} +{}\033[0m\n", ip, (symbol ? symbol->name : "(k?)"), (symbol ? ip - symbol->address : 0));
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user