From d8f26cfbbae7b6addb3045cce8a0c8d762be3de6 Mon Sep 17 00:00:00 2001 From: Amelia Coutard Date: Mon, 27 Mar 2023 15:59:36 +0200 Subject: [PATCH] Made a first change to the setup of the processes, to allow for correct saving of the registers on a process switch. Not finished yet --- doc.txt | 5 ++--- kernel/src/elf64.cpp | 22 +++++++++++++------- kernel/src/elf64.hpp | 2 +- kernel/src/interrupts.cpp | 2 +- kernel/src/kernel.cpp | 17 ++++++++------- kernel/src/ring3.cpp | 9 ++++---- kernel/src/ring3.hpp | 44 +++++++++++++++++++++------------------ 7 files changed, 55 insertions(+), 46 deletions(-) diff --git a/doc.txt b/doc.txt index 800e7ae..79a69b2 100644 --- a/doc.txt +++ b/doc.txt @@ -12,9 +12,8 @@ isos documentation: 0000'7FFF'FFFF'0000 ↔ 0000'8000'0000'0000 - stack: 64KiB -- Invalid addresses -- FFFF'8000'0000'0000 ↔ FFFF'C000'0000'0000 - physical memory: 64TiB -FFFF'C000'0000'0000 ↔ FFFF'C000'0001'0000 - process information table: 64KiB, 2048 processes at most -FFFF'C000'0001'0000 ↔ FFFF'C000'0801'0000 - port information table: 128MiB, 4096 ports per process at most -FFFF'C000'0801'0000 ↔ FFFF'FFFF'8000'0000 - unmapped: 64TiB - 2GiB - 128MiB - 64KiB +FFFF'C000'0000'0000 ↔ FFFF'C000'1000'0000 - process information table: 256MiB, 2048 processes, 4093 ports/process +FFFF'C000'1000'0000 ↔ FFFF'FFFF'8000'0000 - unmapped: 64TiB - 2GiB - 128MiB - 64KiB FFFF'FFFF'8000'0000 ↔10000'0000'0000'0000 - kernel: 2GiB --------------------------- diff --git a/kernel/src/elf64.cpp b/kernel/src/elf64.cpp index 9f96106..acc4244 100644 --- a/kernel/src/elf64.cpp +++ b/kernel/src/elf64.cpp @@ -13,7 +13,7 @@ #include "elf64.hpp" -os::process os::elf::load_elf(std::byte* start, std::size_t length, const paging::PML4T& original_PML4T) { +void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length, const paging::PML4T& original_PML4T) { os::assert(length >= sizeof(os::elf::header), "Elf file isn't big enough to contain a header: there is an error."); // TODO: Check that the elf file sections are all fully inside the file. @@ -32,11 +32,19 @@ os::process os::elf::load_elf(std::byte* start, std::size_t length, const paging constexpr std::size_t stack_size = 16 * 0x1000 /* 64KiB */; std::byte* const stack = (std::byte*)0x0000'8000'0000'0000 - stack_size; - os::process result = { - .PML4T = phys_ptr(os::paging::page_allocator.allocate(1).ptr.get_phys_addr()), - .rip = std::uint64_t(elf_header.entry), - .rsp = std::uint64_t(stack + stack_size) - }; + + result.exists = true; + result.PML4T = phys_ptr(os::paging::page_allocator.allocate(1).ptr.get_phys_addr()); + result.rip = std::uint64_t(elf_header.entry); + result.rsp = std::uint64_t(stack + stack_size); + result.rbx = 0; + result.rbp = 0; + result.r12 = 0; + result.r13 = 0; + result.r14 = 0; + result.r15 = 0; + result.mxcsr = 0; + result.x87cw = 0; // Copy kernel mappings to the new virtual address space. memset(result.PML4T->contents, 0, 256 * sizeof(os::paging::PML4E)); @@ -64,6 +72,4 @@ os::process os::elf::load_elf(std::byte* start, std::size_t length, const paging memcpy(page, start + program_header.p_offset, clamp(0ul, program_header.p_filesz - i * 0x1000, 0x1000ul)); } } - - return result; } diff --git a/kernel/src/elf64.hpp b/kernel/src/elf64.hpp index 7f348b8..5615e0d 100644 --- a/kernel/src/elf64.hpp +++ b/kernel/src/elf64.hpp @@ -56,5 +56,5 @@ namespace os { namespace elf { }; static_assert(sizeof(program_header) == 56); - process load_elf(std::byte* start, std::size_t length, const paging::PML4T& original_PML4T); + void load_elf(os::process& result, std::byte* start, std::size_t length, const paging::PML4T& original_PML4T); } } // namespace os::elf diff --git a/kernel/src/interrupts.cpp b/kernel/src/interrupts.cpp index 8377345..4e584fb 100644 --- a/kernel/src/interrupts.cpp +++ b/kernel/src/interrupts.cpp @@ -109,7 +109,7 @@ extern "C" void int_general_protection_fault(std::uint32_t err_code) { extern "C" os::paging::PML4T PML4T; extern "C" void int_page_fault(std::uint32_t err_code, std::uint64_t vaddr) { if ( - (0xFFFF'C000'0000'0000 <= vaddr && vaddr < 0xFFFF'C000'0801'0000) // process/port info + (0xFFFF'C000'0000'0000 <= vaddr && vaddr < 0xFFFF'C000'1000'0000) // process/port info ) { // Kernel memory os::print("Allocating (Ring 0): {}\n", (void*)vaddr); os::paging::setup_page(PML4T, (void*)vaddr, true, false); diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index e31457a..1fd5a1c 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -50,7 +50,6 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr(PDPT_alloc.ptr.get_phys_addr())); } - os::process test_module_process = { nullptr, 0, 0 }; { struct { os::phys_ptr start_address = nullptr; @@ -58,6 +57,8 @@ extern "C" void kmain(unsigned long magic, os::phys_ptrtype != multiboot2::info::type_t::end; it = multiboot2::next(it)) { switch (it->type) { case multiboot2::info::type_t::memory_map: @@ -78,17 +79,17 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr{}: {}\n", multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it), multiboot2::modules_string(it)); - os::assert(test_module_process.PML4T == nullptr, "Multiple modules specified in the multiboot. This is unsupported."); - test_module_process = - os::elf::load_elf((std::byte*)multiboot2::modules_mod_start(it), - multiboot2::modules_mod_end(it) - multiboot2::modules_mod_start(it), - PML4T); + os::assert(!os::get_process(0).exists, "Multiple modules specified in the multiboot. This is unsupported."); + os::elf::load_elf(os::get_process(0), + (std::byte*)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."); + os::assert(os::get_process(0).exists, "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 = ([]() { @@ -189,5 +190,5 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr PML4T; std::uint64_t rip; + std::uint64_t rbx; std::uint64_t rsp; - std::uint64_t : 64; + std::uint64_t rbp; + std::uint64_t r12; + std::uint64_t r13; + std::uint64_t r14; + std::uint64_t r15; + std::uint64_t mxcsr; + std::uint64_t x87cw; + port ports[4093]; }; -static_assert(sizeof(process) == 32); - -// (¬0);0 -> port was closed on other side, via syscall or program termination -// 0 ;0 -> port doesn't exist -struct port { - std::uint64_t other_pid; - std::uint64_t other_port; -}; -static_assert(sizeof(port) == 16); +static_assert(sizeof(process) == 0x1000 * 32); inline process& get_process(std::uint64_t pid) { - os::assert(1 <= pid && pid <= 2048, "Invalid pid: {}.\n", pid); - return ((process*)0xFFFF'C000'0000'0000)[pid - 1]; + os::assert(pid < 2048, "Invalid pid: {}.\n", pid); + return ((process*)0xFFFF'C000'0000'0000)[pid]; } inline bool process_exists(std::uint64_t pid) { - return 1 <= pid && pid <= 2048 && get_process(pid).rsp != 0; -} -inline port& get_port(std::uint64_t pid, std::uint64_t port) { - os::assert(1 <= pid && pid <= 2048, "Invalid pid: {}.\n", pid); - os::assert(1 <= port && port <= 4096, "Invalid port: {}.\n", pid); - return ((os::port*)0xFFFF'C000'0001'0000)[(pid - 1) * 4096 + (port - 1)]; + return pid < 2048 && get_process(pid).exists; } inline bool port_exists(std::uint64_t pid, std::uint64_t port) { - return process_exists(pid) && 1 <= port && port <= 4096 && get_port(pid, port).other_pid != 0; + return port < 4093 && process_exists(pid) && get_process(pid).ports[port].exists; } extern std::uint64_t current_pid; -- 2.47.0