From: Amelia Coutard <eliottulio.coutard@gmail.com> Date: Thu, 13 Oct 2022 14:47:08 +0000 (+0200) Subject: Made ftl_to_userspace jump to a loaded module at linear address 0x1000, instead of... X-Git-Url: https://git.ameliathe1st.gay/?a=commitdiff_plain;h=aab73ccaa51c082e412aeaf66a4bfe5091494da7;p=voyage-au-centre-des-fichiers.git Made ftl_to_userspace jump to a loaded module at linear address 0x1000, instead of a function in the higher-half --- diff --git a/grub.cfg b/grub.cfg index 8eccea2..11f6906 100644 --- a/grub.cfg +++ b/grub.cfg @@ -1,3 +1,4 @@ menuentry "Amycros" { multiboot2 /boot/kernel.elf64 + module2 /boot/test-module test-module } diff --git a/src/boot.S b/src/boot.S index fe2f52f..cd329af 100644 --- a/src/boot.S +++ b/src/boot.S @@ -17,6 +17,11 @@ multiboot_header_start: .int 0 .int 0 .int 32 + /* Modules alignment tag: */ + .align 8 + .short 6 + .short 0 + .int 8 /* End tag: */ .align 8 .short 0 diff --git a/src/kernel.cpp b/src/kernel.cpp index 76d5167..c48b654 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -20,6 +20,10 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s } } + struct { + os::phys_ptr<os::paging::page> start_address = nullptr; + os::phys_ptr<os::paging::page> end_address = nullptr; + } test_module; { struct { os::phys_ptr<os::paging::page> start_address = nullptr; @@ -45,17 +49,27 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s } } break; + case multiboot2::info::type_t::modules: + os::print(multiboot2::modules_mod_start(it) / 0x1000 * 0x1000); + os::print("->"); + os::print(multiboot2::modules_mod_end(it) / 0x1000 * 0x1000); + os::print(": "); + os::print(multiboot2::modules_string(it)); + os::printc('\n'); + test_module.start_address = os::phys_ptr<os::paging::page>(multiboot2::modules_mod_start(it) / 0x1000 * 0x1000); + test_module.end_address = os::phys_ptr<os::paging::page>(multiboot2::modules_mod_end(it) / 0x1000 * 0x1000); // [s,e], not [s,e[ + break; default: break; } } // kernel_start and kernel_end are aligned to 4K by the linker script. - const os::phys_ptr<os::paging::page> s = ([]() { + const os::phys_ptr<os::paging::page> kernel_s = ([]() { os::phys_ptr<os::paging::page> ptr = nullptr; asm("mov $_kernel_phys_start,%0" : "=ri"(ptr)); return ptr; })(); - const os::phys_ptr<os::paging::page> e = ([]() { + const os::phys_ptr<os::paging::page> kernel_e = ([]() { os::phys_ptr<os::paging::page> ptr = nullptr; asm("mov $_kernel_phys_end,%0" : "=ri"(ptr)); return ptr - 1; // [s, e], not [s, e[ @@ -63,20 +77,41 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s // Remove kernel from available RAM: for (std::size_t i = 0; i < available_ram_length; i++) { - if (e < available_ram[i].start_address || available_ram[i].end_address < s) { + if (kernel_e < available_ram[i].start_address || available_ram[i].end_address < kernel_s) { continue; } - if (s <= available_ram[i].start_address && available_ram[i].end_address <= e) { + if (kernel_s <= available_ram[i].start_address && available_ram[i].end_address <= kernel_e) { available_ram[i] = available_ram[--available_ram_length]; - } else if (s <= available_ram[i].start_address) { - available_ram[i].start_address = e + 1; // Since e < end_address, new start_address <= end_address. - } else if (available_ram[i].end_address <= e) { - available_ram[i].end_address = s - 1; // Since start_address < s, start_address <= new end_address. + i--; + } else if (kernel_s <= available_ram[i].start_address) { + available_ram[i].start_address = kernel_e + 1; // Since e < end_address, new start_address <= end_address. + } else if (available_ram[i].end_address <= kernel_e) { + available_ram[i].end_address = kernel_s - 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 = s - 1; - available_ram[available_ram_length].start_address = e + 1; + available_ram[i].end_address = kernel_s - 1; + available_ram[available_ram_length].start_address = kernel_e + 1; + available_ram_length++; + } + } + // Remove module from available RAM: + for (std::size_t i = 0; i < available_ram_length; i++) { + if (test_module.end_address < available_ram[i].start_address || available_ram[i].end_address < test_module.start_address) { + continue; + } + if (test_module.start_address <= available_ram[i].start_address && available_ram[i].end_address <= test_module.end_address) { + available_ram[i] = available_ram[--available_ram_length]; + i--; + } else if (test_module.start_address <= available_ram[i].start_address) { + available_ram[i].start_address = test_module.end_address + 1; // Since e < end_address, new start_address <= end_address. + } else if (available_ram[i].end_address <= test_module.end_address) { + available_ram[i].end_address = test_module.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.start_address - 1; + available_ram[available_ram_length].start_address = test_module.end_address + 1; available_ram_length++; } } @@ -133,9 +168,37 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s os::enable_interrupts(isr_info, idt); } - get_base_address(PML4T.contents[0])->contents[0].page.P = false; - get_base_address(PML4T.contents[0])->contents[1].page.P = false; + // Unmap low RAM, and free corresponding page. PML4T.contents[0].P = false; + os::paging::page_allocator.deallocate({.ptr = os::phys_ptr<os::paging::page>(get_base_address(PML4T.contents[0]).get_phys_addr()), .size = 1}); + os::paging::page_allocator.print_all(); + // Map test_module to virtual address 0x0000'0000'0000'1000. + { + os::phys_ptr<os::paging::PT> PT {os::paging::page_allocator.allocate(1).ptr.get_phys_addr()}; + os::phys_ptr<os::paging::PDT> PDT {os::paging::page_allocator.allocate(1).ptr.get_phys_addr()}; + os::phys_ptr<os::paging::PDPT> PDPT{os::paging::page_allocator.allocate(1).ptr.get_phys_addr()}; + PML4T.contents[0] = { .P = 1, .R_W = 0, .U_S = 1, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}; + PDPT->contents[0] = {.non_page = {.P = 1, .R_W = 0, .U_S = 1, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}}; + PDT->contents[0] = {.non_page = {.P = 1, .R_W = 0, .U_S = 1, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}}; + PT->contents[1] = { .P = 1, .R_W = 0, .U_S = 1, .PWT = 0, .PCD = 0, .PAT = 0, .G = 0, .base_address = 0, .NX = 0}; + set_base_address(PML4T.contents[0], PDPT); + set_base_address(PDPT->contents[0], PDT); + set_base_address(PDT->contents[0], PT); + set_page_base_address(PT->contents[1], test_module.start_address); + } + asm volatile("invlpg (%0)" ::"r" (0x1000) : "memory"); + + os::paging::on_all_pages(PML4T, [](os::paging::page* virt, os::phys_ptr<os::paging::page> phys, std::size_t size) { + if (std::uint64_t(virt) >= 0xFFFF'8000'0000'0000) { + return; + } + os::print(std::uint64_t(virt)); + os::print("->"); + os::print(std::uint64_t(phys.get_phys_addr())); + os::print(" ("); + os::print(size); + os::print(")\n"); + }); // Allow userspaaaaaaaaace in ring 3. Otherwise, we just immediately page fault. // Will make it a module soon-ish. @@ -152,13 +215,3 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s os::print("Trying move to ring 3:\n"); os::ftl_to_userspace(); } - -extern "C" std::uint64_t syscall(std::uint64_t in1); - -extern "C" void userspaaaaaaaaace() { - syscall('a'); - syscall('b'); - syscall('c'); - syscall('\n'); - while (true) { asm volatile("nop"); } -} diff --git a/src/multiboot2.hpp b/src/multiboot2.hpp index 9fd7c12..1428e5e 100644 --- a/src/multiboot2.hpp +++ b/src/multiboot2.hpp @@ -108,6 +108,16 @@ inline std::uint32_t memory_map_type(os::phys_ptr<const info> ptr, std::size_t index) { return *reinterpret_cast<const std::uint32_t*>(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 16]); } + + inline std::uint32_t modules_mod_start(os::phys_ptr<const info> ptr) { + return *reinterpret_cast<const std::uint32_t*>(&ptr->rest[0]); + } + inline std::uint32_t modules_mod_end(os::phys_ptr<const info> ptr) { + return *reinterpret_cast<const std::uint32_t*>(&ptr->rest[4]); + } + inline const char* modules_string(os::phys_ptr<const info> ptr) { + return reinterpret_cast<const char*>(&ptr->rest[8]); + } #endif // __cplusplus #ifdef __cplusplus diff --git a/src/ring3.S b/src/ring3.S index 3e21c2e..48bf822 100644 --- a/src/ring3.S +++ b/src/ring3.S @@ -2,7 +2,7 @@ .globl ftl_to_userspace ftl_to_userspace: - mov $userspaaaaaaaaace, %rcx + mov $0x1000, %rcx mov $0x202, %r11 # EFLAGS sysretq @@ -19,9 +19,3 @@ load_tss: mov $GDT.TSS, %ax ltr %ax ret - -.globl syscall -syscall: - mov %rcx, %r10 - syscall - ret