]> git.ameliathe1st.gay Git - voyage-au-centre-des-fichiers.git/commitdiff
Made ftl_to_userspace jump to a loaded module at linear address 0x1000, instead of...
authorAmelia Coutard <eliottulio.coutard@gmail.com>
Thu, 13 Oct 2022 14:47:08 +0000 (16:47 +0200)
committerAmelia Coutard <eliottulio.coutard@gmail.com>
Thu, 13 Oct 2022 14:47:08 +0000 (16:47 +0200)
grub.cfg
src/boot.S
src/kernel.cpp
src/multiboot2.hpp
src/ring3.S

index 8eccea2770fd97d688d3e94b034def6fbe0d2962..11f69062358c89d973c414e49429ec64f048c91b 100644 (file)
--- a/grub.cfg
+++ b/grub.cfg
@@ -1,3 +1,4 @@
 menuentry "Amycros" {
        multiboot2 /boot/kernel.elf64
+       module2 /boot/test-module test-module
 }
index fe2f52fcda8fc85113b83ccb1b7969366da9bf42..cd329afc84d4781f2f141a420d45c01d674e3097 100644 (file)
@@ -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
index 76d516738c96104ac369188a4393109e0f68bc29..c48b654d5b8cad160eaf2c7893fc62556d861635 100644 (file)
@@ -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"); }
-}
index 9fd7c12f9127319d0f6b52ee9f3b7fb81d204340..1428e5e5c920af9b526ca54652ade128b96bb677 100644 (file)
        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
index 3e21c2e2302fa2046cc1749fcde0d8ac443e1ae1..48bf822abdfef43d1d925da252697918badbaa09 100644 (file)
@@ -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