diff --git a/src/kernel/buffer_cache.cpp b/src/kernel/buffer_cache.cpp index f975f5f..d83f24f 100644 --- a/src/kernel/buffer_cache.cpp +++ b/src/kernel/buffer_cache.cpp @@ -5,8 +5,6 @@ #include "page_manager.h" #include "vm_space.h" -extern vm_space g_kernel_space; - using memory::frame_size; using memory::kernel_stack_pages; using memory::kernel_buffer_pages; diff --git a/src/kernel/memory_bootstrap.cpp b/src/kernel/memory_bootstrap.cpp index 62262a7..b582c8e 100644 --- a/src/kernel/memory_bootstrap.cpp +++ b/src/kernel/memory_bootstrap.cpp @@ -9,6 +9,7 @@ #include "frame_allocator.h" #include "io.h" #include "log.h" +#include "objects/process.h" #include "objects/vm_area.h" #include "page_manager.h" #include "vm_space.h" @@ -38,9 +39,6 @@ page_manager &g_page_manager = __g_page_manager_storage.value; static kutil::no_construct __g_frame_allocator_storage; frame_allocator &g_frame_allocator = __g_frame_allocator_storage.value; -static kutil::no_construct __g_kernel_space_storage; -vm_space &g_kernel_space = __g_kernel_space_storage.value; - void * operator new(size_t size) { return g_kernel_heap.allocate(size); } void * operator new [] (size_t size) { return g_kernel_heap.allocate(size); } void operator delete (void *p) noexcept { return g_kernel_heap.free(p); } @@ -111,7 +109,8 @@ memory_initialize_pre_ctors(args::header *kargs) // Create the page manager new (&g_page_manager) page_manager {g_frame_allocator, kpml4}; - vm_space &vm = *new (&g_kernel_space) vm_space {kpml4}; + process *kp = process::create_kernel_process(kpml4); + vm_space &vm = kp->space(); vm.allow(memory::heap_start, memory::kernel_max_heap, true); } diff --git a/src/kernel/objects/process.cpp b/src/kernel/objects/process.cpp index 020779b..90546bb 100644 --- a/src/kernel/objects/process.cpp +++ b/src/kernel/objects/process.cpp @@ -1,29 +1,48 @@ #include "j6/signals.h" #include "kutil/assert.h" +#include "kutil/no_construct.h" #include "cpu.h" #include "objects/process.h" #include "objects/thread.h" #include "page_manager.h" +// This object is initialized _before_ global constructors are called, +// so we don't want it to have a global constructor at all, lest it +// overwrite the previous initialization. +static kutil::no_construct __g_kernel_process_storage; +process &g_kernel_process = __g_kernel_process_storage.value; + + kutil::vector process::s_processes; process::process() : - kobject(kobject::type::process), - m_next_handle(0), - m_state(state::running) + kobject {kobject::type::process}, + m_next_handle {0}, + m_state {state::running} { s_processes.append(this); } +process::process(page_table *kpml4) : + kobject {kobject::type::process}, + m_space {kpml4}, + m_next_handle {0}, + m_state {state::running} +{ +} + process::~process() { s_processes.remove_swap(this); } -process & -process::current() +process & process::current() { return *bsp_cpu_data.p; } +process & process::kernel_process() { return g_kernel_process; } + +process * +process::create_kernel_process(page_table *pml4) { - return *bsp_cpu_data.p; + return new (&g_kernel_process) process {pml4}; } void diff --git a/src/kernel/objects/process.h b/src/kernel/objects/process.h index 064a0e9..0c00a9b 100644 --- a/src/kernel/objects/process.h +++ b/src/kernel/objects/process.h @@ -63,12 +63,19 @@ public: /// \returns True if this thread ending has ended the process bool thread_exited(thread *th); + /// Get the process object that owns kernel threads and the + /// kernel address space + static process & kernel_process(); + /// Create the special kernel process that owns kernel tasks - /// \arg pml4 The kernel-only pml4 - /// \arg idle_rsp The idle thread's rsp - static process * create_kernel_process(page_table *pml4, uintptr_t idle_rsp); + /// \arg pml4 The kernel-only pml4 + /// \returns The kernel process object + static process * create_kernel_process(page_table *pml4); private: + // This constructor is called by create_kernel_process + process(page_table *kpml4); + uint32_t m_return_code; vm_space m_space; diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index 61f2de1..e6c05f2 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -42,8 +42,7 @@ scheduler::scheduler(lapic *apic) : s_instance = this; page_table *pml4 = page_manager::get_pml4(); - process *kp = new process; - m_kernel_process = kp; + process *kp = &process::kernel_process(); log::debug(logs::task, "Kernel process koid %llx", kp->koid()); @@ -193,8 +192,7 @@ scheduler::load_process(const char *name, const void *data, size_t size) void scheduler::create_kernel_task(void (*task)(), uint8_t priority, bool constant) { - page_table *pml4 = page_manager::get()->get_kernel_pml4(); - thread *th = m_kernel_process->create_thread(priority, false); + thread *th = process::kernel_process().create_thread(priority, false); auto *tcb = th->tcb(); th->add_thunk_kernel(reinterpret_cast(task)); diff --git a/src/kernel/vm_space.cpp b/src/kernel/vm_space.cpp index 90d8d5b..556d9d1 100644 --- a/src/kernel/vm_space.cpp +++ b/src/kernel/vm_space.cpp @@ -1,4 +1,5 @@ #include "log.h" +#include "objects/process.h" #include "objects/thread.h" #include "objects/vm_area.h" #include "page_manager.h" @@ -52,8 +53,7 @@ vm_space::~vm_space() vm_space & vm_space::kernel_space() { - extern vm_space &g_kernel_space; - return g_kernel_space; + return process::kernel_process().space(); } bool