]> git.ameliathe1st.gay Git - voyage-au-centre-des-fichiers.git/commitdiff
Implemented ports and processes better.
authorAmelia Coutard <eliottulio.coutard@gmail.com>
Sat, 5 Aug 2023 00:22:22 +0000 (02:22 +0200)
committerAmelia Coutard <eliottulio.coutard@gmail.com>
Sat, 5 Aug 2023 00:22:22 +0000 (02:22 +0200)
kernel/src/kernel.cpp
kernel/src/ring3.cpp
kernel/src/ring3.hpp
kernel/src/utils.cpp
kernel/src/utils.hpp

index 2035138eeb41ccb04db731557a57725514833997..5b70c4c79e8a64424ec77fc698c8b4c2563b986e 100644 (file)
@@ -41,15 +41,20 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                .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.
+       // Allocate those pages so that I only ever need to update the mapping once when I create a new process or port.
+       // TODO: Not an emergency, but adapt in case we need multiple PML4Es. (*NOT* the case right now.)
+       static_assert(sizeof(os::processes) > 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<os::paging::PDPT>(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<os::paging::page> start_address = nullptr;
@@ -57,8 +62,6 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                } available_ram[50];
                std::size_t available_ram_length = 0;
 
-               os::paging::setup_page(PML4T, (void*)0xFFFF'C000'0000'0000, 1, 0); // The startup module.
-
                bool module_specified = false;
                for (auto it = multiboot2::next(info); it->type != 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<const multiboot2::info_s
                                os::print("{}->{}: {}\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<const multiboot2::info_s
        os::enable_syscalls();
 
        os::print("Moving to ring 3.\n");
-       os::run_first_process();
+       os::run_first_process(module_process);
 }
index c8b840086d0a2cb4fc31520a14d6834d070bf397..ddba192c17fd74f19813c1ed200c4c29855f33d9 100644 (file)
 #include "serial.hpp"
 #include "paging.hpp"
 
-void os::run_first_process() {
-       os::current_pid = 0;
-       os::paging::load_pml4t(os::get_process(0).PML4T);
-       os::ftl_to_userspace((void*)os::get_process(0).rip, (std::byte*)os::get_process(0).rsp);
+void os::run_first_process(std::int64_t pid) {
+       current_pid = pid;
+       os::paging::load_pml4t(os::get_process(current_pid).PML4T);
+       os::ftl_to_userspace((void*)os::get_process(current_pid).rip, (std::byte*)os::get_process(current_pid).rsp);
 }
 
 void os::set_ring0_stack(os::tss& tss, std::uint64_t stack) {
@@ -69,8 +69,8 @@ extern "C" void os::syscall_rax_error_handler() {
        os::assert(false, "Incorrect %rax for syscall.");
 }
 
-os::process& os::get_process(std::uint64_t pid) {
-       os::assert(pid < 2048, "Invalid pid: {}.\n", pid);
-       return ((process*)0xFFFF'C000'0000'0000)[pid];
+os::incrementing_int64_map<os::process>& os::processes = *reinterpret_cast<os::incrementing_int64_map<os::process>*>(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;
index 32e17ed4304218f80fd7962c9372e497eefbc8a4..252e7c1957a89a798e2478f36c91a753bb962267 100644 (file)
@@ -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<paging::PML4T> PML4T;
+       phys_ptr<paging::PML4T> 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<port> 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<process>) < 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<process>& processes;
+extern "C" std::int64_t current_pid;
+extern "C" process& get_process(std::int64_t pid);
 
 } // namespace os
index 326de3b0a62c360ce2650bf4f410aab049d4f850..d1b997ba27ffa7b2d124bca429513a933a35046a 100644 (file)
@@ -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<std::byte*>(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<std::byte*>(dest)[n] = reinterpret_cast<const std::byte*>(src)[n];
+       }
+       return dest;
+}
index c203c8089dea46cb92260928d379bcc9811b13f3..95c4109a6ec07ffc77b3c0c1792a1729f2304ba1 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <cstdint>
 #include <cstddef>
+#include <new>
+#include "serial.hpp"
 
 namespace os {
 
@@ -30,17 +32,55 @@ void set_msr(std::uint32_t msr, std::uint64_t v);
 template <typename T> 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<std::byte*>(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 <typename T>
+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<std::byte*>(dest)[n] = reinterpret_cast<const std::byte*>(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<T*>(&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<T*>(&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