diff --git a/Kernel/Arch/aarch64/MMU.cpp b/Kernel/Arch/aarch64/MMU.cpp index 80496be6ab7..24b3396c24f 100644 --- a/Kernel/Arch/aarch64/MMU.cpp +++ b/Kernel/Arch/aarch64/MMU.cpp @@ -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(); diff --git a/Kernel/Arch/aarch64/PageDirectory.cpp b/Kernel/Arch/aarch64/PageDirectory.cpp index bb99f3abcf6..2204dd69311 100644 --- a/Kernel/Arch/aarch64/PageDirectory.cpp +++ b/Kernel/Arch/aarch64/PageDirectory.cpp @@ -73,7 +73,7 @@ ErrorOr> 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() diff --git a/Kernel/Arch/aarch64/RPi/Framebuffer.cpp b/Kernel/Arch/aarch64/RPi/Framebuffer.cpp index 35611c70373..de5e942ed22 100644 --- a/Kernel/Arch/aarch64/RPi/Framebuffer.cpp +++ b/Kernel/Arch/aarch64/RPi/Framebuffer.cpp @@ -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; } } diff --git a/Kernel/Arch/aarch64/RPi/MMIO.h b/Kernel/Arch/aarch64/RPi/MMIO.h index edcefcd5553..5edbb22bafa 100644 --- a/Kernel/Arch/aarch64/RPi/MMIO.h +++ b/Kernel/Arch/aarch64/RPi/MMIO.h @@ -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 T volatile* peripheral(FlatPtr offset) { return (T volatile*)peripheral_address(offset); } diff --git a/Kernel/Arch/aarch64/pre_init.cpp b/Kernel/Arch/aarch64/pre_init.cpp index da1278e63ff..4bf2ff39ba6 100644 --- a/Kernel/Arch/aarch64/pre_init.cpp +++ b/Kernel/Arch/aarch64/pre_init.cpp @@ -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. diff --git a/Kernel/Arch/init.cpp b/Kernel/Arch/init.cpp index cf1e4958e47..91bc63b62e9 100644 --- a/Kernel/Arch/init.cpp +++ b/Kernel/Arch/init.cpp @@ -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 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(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(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().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); } } diff --git a/Kernel/Arch/riscv64/CPU.cpp b/Kernel/Arch/riscv64/CPU.cpp deleted file mode 100644 index 521ec1e6545..00000000000 --- a/Kernel/Arch/riscv64/CPU.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2024, Leon Albrecht - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include - -namespace Kernel { - -BootInfo s_boot_info; - -} diff --git a/Kernel/Arch/riscv64/CPU.h b/Kernel/Arch/riscv64/CPU.h index 8c3f0afc5a9..0cc62c6b6b8 100644 --- a/Kernel/Arch/riscv64/CPU.h +++ b/Kernel/Arch/riscv64/CPU.h @@ -6,13 +6,5 @@ #pragma once -#include - #include VALIDATE_IS_RISCV64() - -namespace Kernel { - -extern BootInfo s_boot_info; - -} diff --git a/Kernel/Arch/riscv64/MMU.cpp b/Kernel/Arch/riscv64/MMU.cpp index 5d63dc06d52..f233524f20f 100644 --- a/Kernel/Arch/riscv64/MMU.cpp +++ b/Kernel/Arch/riscv64/MMU.cpp @@ -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(insert_page_table(allocator, root_table, kernel_pt1024_base)) }; - *adjust_by_mapping_base(&boot_pd_kernel_pt1023) = bit_cast(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(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(get_page_directory(root_table, VirtualAddress { *adjust_by_mapping_base(&kernel_mapping_base) })); + auto kernel_page_directory = bit_cast(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(root_table) }; + *adjust_by_mapping_base(&g_boot_info.boot_pdpt) = PhysicalAddress { bit_cast(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(page_tables_phys_start)), adjust_by_mapping_base(reinterpret_cast(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(satp), &enable_paging_level0_table[enable_paging_vpn_0]); + enable_paging(g_boot_info, bit_cast(satp), &enable_paging_level0_table[enable_paging_vpn_0]); } } diff --git a/Kernel/Arch/riscv64/PageDirectory.cpp b/Kernel/Arch/riscv64/PageDirectory.cpp index 4cdba33f602..de66c07e673 100644 --- a/Kernel/Arch/riscv64/PageDirectory.cpp +++ b/Kernel/Arch/riscv64/PageDirectory.cpp @@ -43,7 +43,7 @@ ErrorOr> 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() diff --git a/Kernel/Arch/x86_64/Interrupts/APIC.cpp b/Kernel/Arch/x86_64/Interrupts/APIC.cpp index de78d2708e5..3c2007546d4 100644 --- a/Kernel/Arch/x86_64/Interrupts/APIC.cpp +++ b/Kernel/Arch/x86_64/Interrupts/APIC.cpp @@ -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 diff --git a/Kernel/Arch/x86_64/PageDirectory.cpp b/Kernel/Arch/x86_64/PageDirectory.cpp index 398c968873d..db630d98be8 100644 --- a/Kernel/Arch/x86_64/PageDirectory.cpp +++ b/Kernel/Arch/x86_64/PageDirectory.cpp @@ -70,12 +70,12 @@ ErrorOr> 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() diff --git a/Kernel/Boot/BootInfo.h b/Kernel/Boot/BootInfo.h index 7ba21c4a652..2a625b6c2d9 100644 --- a/Kernel/Boot/BootInfo.h +++ b/Kernel/Boot/BootInfo.h @@ -6,38 +6,10 @@ #pragma once -#include -#include -#include -#include +#include + +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; diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 20333574b96..abb84522c79 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -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 diff --git a/Kernel/Devices/GPU/Management.cpp b/Kernel/Devices/GPU/Management.cpp index f6116a11540..9ea1c40e5f7 100644 --- a/Kernel/Devices/GPU/Management.cpp +++ b/Kernel/Devices/GPU/Management.cpp @@ -119,14 +119,14 @@ UNMAP_AFTER_INIT ErrorOr 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) { diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp index 2e6abf8da04..2b0800b64f1 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp @@ -55,7 +55,7 @@ UNMAP_AFTER_INIT NonnullRefPtr 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)); diff --git a/Kernel/KSyms.cpp b/Kernel/KSyms.cpp index 461d11ead59..c6c163aa4a3 100644 --- a/Kernel/KSyms.cpp +++ b/Kernel/KSyms.cpp @@ -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 { - 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); } } diff --git a/Kernel/Memory/MemoryManager.cpp b/Kernel/Memory/MemoryManager.cpp index 926e99230d9..72df5c45c38 100644 --- a/Kernel/Memory/MemoryManager.cpp +++ b/Kernel/Memory/MemoryManager.cpp @@ -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 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(quickmap_page(boot_pd_kernel)); + auto* pd = reinterpret_cast(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); diff --git a/Kernel/Memory/MemoryManager.h b/Kernel/Memory/MemoryManager.h index aa760f521ea..f63ad6ffa15 100644 --- a/Kernel/Memory/MemoryManager.h +++ b/Kernel/Memory/MemoryManager.h @@ -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 { diff --git a/Kernel/Memory/Region.h b/Kernel/Memory/Region.h index df168d3f3f9..82b08d0fe79 100644 --- a/Kernel/Memory/Region.h +++ b/Kernel/Memory/Region.h @@ -108,7 +108,7 @@ public: ErrorOr 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&); diff --git a/Kernel/Prekernel/Arch/ArchSpecificBootInfo.h b/Kernel/Prekernel/Arch/ArchSpecificBootInfo.h new file mode 100644 index 00000000000..0ba59acd365 --- /dev/null +++ b/Kernel/Prekernel/Arch/ArchSpecificBootInfo.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024, Sönke Holz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#if ARCH(X86_64) +# include +#elif ARCH(AARCH64) +# include +#elif ARCH(RISCV64) +# include +#else +# error Unknown architecture +#endif diff --git a/Kernel/Prekernel/Arch/aarch64/ArchSpecificBootInfo.h b/Kernel/Prekernel/Arch/aarch64/ArchSpecificBootInfo.h new file mode 100644 index 00000000000..b0f3ed76c1f --- /dev/null +++ b/Kernel/Prekernel/Arch/aarch64/ArchSpecificBootInfo.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024, Sönke Holz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#include +VALIDATE_IS_AARCH64() + +namespace Kernel { + +struct ArchSpecificBootInfo { +}; + +} diff --git a/Kernel/Prekernel/Arch/riscv64/ArchSpecificBootInfo.h b/Kernel/Prekernel/Arch/riscv64/ArchSpecificBootInfo.h new file mode 100644 index 00000000000..f05c902f0cd --- /dev/null +++ b/Kernel/Prekernel/Arch/riscv64/ArchSpecificBootInfo.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024, Sönke Holz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#include +VALIDATE_IS_RISCV64() + +namespace Kernel { + +struct ArchSpecificBootInfo { + FlatPtr boot_hart_id; +}; + +} diff --git a/Kernel/Prekernel/Arch/x86_64/ArchSpecificBootInfo.h b/Kernel/Prekernel/Arch/x86_64/ArchSpecificBootInfo.h new file mode 100644 index 00000000000..59d2b8fae16 --- /dev/null +++ b/Kernel/Prekernel/Arch/x86_64/ArchSpecificBootInfo.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024, Sönke Holz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#include +VALIDATE_IS_X86() + +namespace Kernel { + +struct ArchSpecificBootInfo { + u32 gdt64ptr; + u16 code64_sel; +}; + +} diff --git a/Kernel/Prekernel/Prekernel.h b/Kernel/Prekernel/Prekernel.h index 40b302b6e73..b09de3f82f0 100644 --- a/Kernel/Prekernel/Prekernel.h +++ b/Kernel/Prekernel/Prekernel.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Gunnar Beutner + * Copyright (c) 2024, Sönke Holz * * SPDX-License-Identifier: BSD-2-Clause */ @@ -10,6 +11,7 @@ # include # include # include +# include #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 diff --git a/Kernel/Prekernel/init.cpp b/Kernel/Prekernel/init.cpp index 13f4ffbeed0..e3d89cc4588 100644 --- a/Kernel/Prekernel/init.cpp +++ b/Kernel/Prekernel/init.cpp @@ -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(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(+start_of_prekernel_image) }; + info.boot_method_specific.multiboot1.end_of_prekernel_image = PhysicalAddress { bit_cast(+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(+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(+boot_pdpt) }; + info.boot_method_specific.multiboot1.boot_pd0 = PhysicalAddress { bit_cast(+boot_pd0) }; + info.boot_pd_kernel = PhysicalAddress { bit_cast(+boot_pd_kernel) }; + info.boot_pd_kernel_pt1023 = bit_cast(adjust_by_mapping_base(boot_pd_kernel_pt1023)); + + char const* cmdline_ptr = bit_cast(adjust_by_mapping_base(kernel_cmdline)); + info.cmdline = StringView { cmdline_ptr, __builtin_strlen(cmdline_ptr) }; asm( "mov %0, %%rax\n" diff --git a/Kernel/Sections.h b/Kernel/Sections.h index 12c759c5d33..cbb86915b03 100644 --- a/Kernel/Sections.h +++ b/Kernel/Sections.h @@ -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) diff --git a/Kernel/Security/AddressSanitizer.cpp b/Kernel/Security/AddressSanitizer.cpp index 7352f4eca20..0a989713930 100644 --- a/Kernel/Security/AddressSanitizer.cpp +++ b/Kernel/Security/AddressSanitizer.cpp @@ -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; diff --git a/Kernel/Tasks/Process.cpp b/Kernel/Tasks/Process.cpp index dc4d610177d..9c850fa848c 100644 --- a/Kernel/Tasks/Process.cpp +++ b/Kernel/Tasks/Process.cpp @@ -535,7 +535,7 @@ void Process::crash(int signal, Optional 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 {