From e5f2d11063104615c33edd32dc9e7bce5ca445b4 Mon Sep 17 00:00:00 2001 From: Amelia Coutard Date: Sat, 5 Aug 2023 02:22:22 +0200 Subject: [PATCH] Implemented ports and processes better. --- kernel/src/kernel.cpp | 15 ++++++----- kernel/src/ring3.cpp | 16 ++++++------ kernel/src/ring3.hpp | 22 ++++++---------- kernel/src/utils.cpp | 12 +++++++++ kernel/src/utils.hpp | 60 +++++++++++++++++++++++++++++++++++-------- 5 files changed, 87 insertions(+), 38 deletions(-) diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index 2035138..5b70c4c 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -41,15 +41,20 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr 1024 * 1024 * 1024, "Error: processes array too big."); { - const auto index = os::paging::calc_page_table_indices((void*)0xFFFF'C000'0000'0000).pml4e; + const auto index = os::paging::calc_page_table_indices(&os::processes).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); os::memset((void*)PDPT_alloc.ptr, 0, 0x1000); set_base_address(PML4T.contents[index], os::phys_ptr(PDPT_alloc.ptr.get_phys_addr())); } + os::paging::setup_page(PML4T, (void*)0xFFFF'C000'0000'0000, 1, 0); // The startup module. + std::int64_t module_process = os::processes.create(); + { struct { os::phys_ptr start_address = nullptr; @@ -57,8 +62,6 @@ extern "C" void kmain(unsigned long magic, os::phys_ptrtype != multiboot2::info::type_t::end; it = multiboot2::next(it)) { switch (it->type) { @@ -82,7 +85,7 @@ 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(!module_specified, "Multiple modules specified in the multiboot. This is unsupported."); module_specified = true; - os::elf::load_elf(os::get_process(0), + os::elf::load_elf(os::get_process(module_process), (std::byte*)multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it) - multiboot2::modules_mod_start(it), PML4T); @@ -192,5 +195,5 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr& os::processes = *reinterpret_cast*>(0xFFFF'C000'0000'0000); +std::int64_t os::current_pid; +os::process& os::get_process(std::int64_t pid) { + return processes.get(pid); } -std::uint64_t os::current_pid; diff --git a/kernel/src/ring3.hpp b/kernel/src/ring3.hpp index 32e17ed..252e7c1 100644 --- a/kernel/src/ring3.hpp +++ b/kernel/src/ring3.hpp @@ -40,7 +40,7 @@ struct __attribute__((packed)) tss { struct process; extern "C" void ftl_to_userspace(void* program, std::byte* stack); -void run_first_process(); +void run_first_process(std::int64_t pid); extern "C" void load_tss(); extern "C" void syscall_64bit_handler(); @@ -54,14 +54,13 @@ void enable_syscalls(); struct port { bool exists; - std::uint64_t : 0; bool is_open; std::uint64_t other_pid; std::uint64_t other_port; }; struct process { - phys_ptr PML4T; + phys_ptr PML4T = nullptr; std::uint64_t rax; std::uint64_t rbx; std::uint64_t rcx; @@ -79,19 +78,14 @@ struct process { std::uint64_t r14; std::uint64_t r15; std::uint64_t rip; - port ports[2043]; + incrementing_int64_map ports; + // char test[65536]; }; -static_assert(0xFFFF'C000'0000'0000 + sizeof(process) * 2048 < 0xFFFF'FFFF'8000'0000); -extern "C" process& get_process(std::uint64_t pid); +static_assert(0xFFFF'C000'0000'0000 + sizeof(incrementing_int64_map) < 0xFFFF'FFFF'8000'0000); -inline bool process_exists(std::uint64_t pid) { - return pid < 2048; -} -inline bool port_exists(std::uint64_t pid, std::uint64_t port) { - return port < 2043 && process_exists(pid) && get_process(pid).ports[port].exists; -} - -extern "C" std::uint64_t current_pid; +extern incrementing_int64_map& processes; +extern "C" std::int64_t current_pid; +extern "C" process& get_process(std::int64_t pid); } // namespace os diff --git a/kernel/src/utils.cpp b/kernel/src/utils.cpp index 326de3b..d1b997b 100644 --- a/kernel/src/utils.cpp +++ b/kernel/src/utils.cpp @@ -50,3 +50,15 @@ std::uint64_t os::get_msr(std::uint32_t msr) { void os::set_msr(std::uint32_t msr, std::uint64_t v) { asm volatile ("wrmsr" : : "a"(v & 0xFFFFFFFF), "d"((v >> 32) & 0xFFFFFFFF), "c"(msr)); } +extern "C" void* os::memset(void* dest, int c, size_t n) { + while (n-- > 0) { + reinterpret_cast(dest)[n] = std::byte(c); + } + return dest; +} +extern "C" void* os::memcpy(void* dest, const void* src, size_t n) { + while (n-- > 0) { + reinterpret_cast(dest)[n] = reinterpret_cast(src)[n]; + } + return dest; +} diff --git a/kernel/src/utils.hpp b/kernel/src/utils.hpp index c203c80..95c4109 100644 --- a/kernel/src/utils.hpp +++ b/kernel/src/utils.hpp @@ -15,6 +15,8 @@ #include #include +#include +#include "serial.hpp" namespace os { @@ -30,17 +32,55 @@ void set_msr(std::uint32_t msr, std::uint64_t v); template T clamp(T min, T v, T max) { return v < min ? min : max < v ? max : v; } -inline void* memset(void* dest, int c, size_t n) { - while (n-- > 0) { - reinterpret_cast(dest)[n] = std::byte(c); +extern "C" void* memset(void* dest, int c, size_t n); +extern "C" void* memcpy(void* dest, const void* src, size_t n); + +template +struct incrementing_int64_map { +public: + incrementing_int64_map() {} + incrementing_int64_map(const incrementing_int64_map& other) = delete; + incrementing_int64_map& operator=(const incrementing_int64_map& other) = delete; + ~incrementing_int64_map() { + for (std::int64_t i = 0; i < n; i++) { + if (present(i)) { remove(i); } + } } - return dest; -} -inline void* memcpy(void* dest, const void* src, size_t n) { - while (n-- > 0) { - reinterpret_cast(dest)[n] = reinterpret_cast(src)[n]; + + bool has_room() { + return n < max_n; } - return dest; -} + bool present(std::int64_t index) { + return 0 <= index && index < n && elems[index].present; + } + std::int64_t create() { + os::assert(has_room(), "Too many allocated elems in incrementing_int64_map."); + elems[n].present = true; + new(elems[n].buffer) T; + return n++; + } + void remove(std::int64_t index) { + os::assert(present(index), "Tried removing non-existant element of incrementing_int64_map."); + get(index).~T(); + elems[index].present = false; + } + T& get(std::int64_t index) { + os::assert(present(index), "Tried getting non-existant element of incrementing_int64_map."); + return *reinterpret_cast(&elems[index].buffer[0]); + } + const T& get(std::int64_t index) const { + os::assert(present(index), "Tried getting non-existant element of incrementing_int64_map."); + return *reinterpret_cast(&elems[index].buffer[0]); + } + +private: + struct elem_t { + bool present; + alignas(T) std::byte buffer[sizeof(T)]; + }; + std::int64_t n = 0; + static constexpr std::int64_t max_n = 4096; + elem_t elems[max_n]; +}; } // namespace os -- 2.47.0