From 6a1c1ee62a2ef7eb5dd65aa331dcc54822fcf112 Mon Sep 17 00:00:00 2001 From: Amelia Coutard Date: Mon, 13 Mar 2023 15:14:51 +0100 Subject: [PATCH] Moved the loading of the elf program before the aquisition of most physical memory, in order to allow for freeing the corresponding multiboot module more easily --- kernel/src/kernel.cpp | 69 +++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index 2e4146e..244eb1c 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -24,6 +24,8 @@ extern "C" os::tss TSS; extern "C" char interrupt_stack_top; extern "C" os::paging::PML4T PML4T; +os::paging::page bootstrap_pages_for_memory[32]; // 32 pages = 128 KiB + extern "C" void kmain(unsigned long magic, os::phys_ptr info) { os::assert(magic == 0x36D76289, "Incorrect magic number: wasn't booted with multiboot2."); os::assert(os::cpu_has_msr(), "MSRs aren't supported."); @@ -34,10 +36,20 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr(reinterpret_cast(bootstrap_pages_for_memory) - 0xFFFF'FFFF'8000'0000), + .size = sizeof(bootstrap_pages_for_memory) / sizeof(bootstrap_pages_for_memory[0]) + }); + + // Allocate this page so that I only ever need to update the mapping once when I create a new process or port. + { + const auto index = os::paging::calc_page_table_indices((void*)0xFFFF'C000'0000'0000).pml4e; + PML4T.contents[index] = {.P = 1, .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}; + const auto PDPT_alloc = os::paging::page_allocator.allocate(1); + set_base_address(PML4T.contents[index], os::phys_ptr(PDPT_alloc.ptr.get_phys_addr())); + } + + os::process test_module_process = { nullptr, 0, 0 }; { struct { os::phys_ptr start_address = nullptr; @@ -65,13 +77,18 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr{}: {}\n", multiboot2::modules_mod_start(it) / 0x1000 * 0x1000, multiboot2::modules_mod_end(it) / 0x1000 * 0x1000, multiboot2::modules_string(it)); - test_module.start_address = multiboot2::modules_mod_start(it); - test_module.end_address = multiboot2::modules_mod_end(it); + os::assert(test_module_process.PML4T == nullptr, "Multiple modules specified in the multiboot. This is unsupported."); + test_module_process = + os::elf::load_elf(&*os::phys_ptr(multiboot2::modules_mod_start(it)), + multiboot2::modules_mod_end(it) - multiboot2::modules_mod_start(it), + PML4T); break; default: break; } } + os::assert(test_module_process.PML4T != nullptr, "No modules specified in the multiboot. This is unsupported."); + // kernel_start and kernel_end are aligned to 4K by the linker script. const os::phys_ptr kernel_s = ([]() { os::phys_ptr ptr = nullptr; @@ -104,35 +121,8 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr start_address; - os::phys_ptr end_address; - } test_module_block{ - os::phys_ptr(test_module.start_address / 0x1000 * 0x1000), - os::phys_ptr(test_module.end_address / 0x1000 * 0x1000) - }; - // Remove module from available RAM: - for (std::size_t i = 0; i < available_ram_length; i++) { - if (test_module_block.end_address < available_ram[i].start_address || available_ram[i].end_address < test_module_block.start_address) { - continue; - } - if (test_module_block.start_address <= available_ram[i].start_address && available_ram[i].end_address <= test_module_block.end_address) { - available_ram[i] = available_ram[--available_ram_length]; - i--; - } else if (test_module_block.start_address <= available_ram[i].start_address) { - available_ram[i].start_address = test_module_block.end_address + 1; // Since e < end_address, new start_address <= end_address. - } else if (available_ram[i].end_address <= test_module_block.end_address) { - available_ram[i].end_address = test_module_block.start_address - 1; // Since start_address < s, start_address <= new end_address. - } else { - os::assert(available_ram_length < 50, "Too much available RAM sections to initialise correctly. Will fix eventually, probably."); - available_ram[available_ram_length] = available_ram[i]; - available_ram[i].end_address = test_module_block.start_address - 1; - available_ram[available_ram_length].start_address = test_module_block.end_address + 1; - available_ram_length++; - } - } - // Add available RAM to the page allocator (warning: overrides the multiboot info structure): + // Add available RAM to the page allocator (warning: overrides the multiboot info structure and the multiboot modules): for (std::size_t i = 0; i < available_ram_length; i++) { os::paging::page_allocator.deallocate({ .ptr = available_ram[i].start_address, @@ -186,17 +176,6 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr(get_base_address(PML4T.contents[0]).get_phys_addr()), .size = 1}); os::invlpg((void*)0x0); - // Allocate this page so that I only ever need to update the mapping once when I create a new process or port. - { - const auto index = os::paging::calc_page_table_indices((void*)0xFFFF'C000'0000'0000).pml4e; - PML4T.contents[index] = {.P = 1, .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}; - const auto PDPT_alloc = os::paging::page_allocator.allocate(1); - set_base_address(PML4T.contents[index], os::phys_ptr(PDPT_alloc.ptr.get_phys_addr())); - } - - auto test_module_process = - os::elf::load_elf(&*os::phys_ptr(test_module.start_address), test_module.end_address - test_module.start_address, PML4T); - os::print("Loading ring 3 interrupts stack.\n"); os::set_ring0_stack(TSS, std::uint64_t(&interrupt_stack_top)); os::print("Loading TSS.\n"); -- 2.47.0