From 1c3377fc98fa88fd5255c0b39e9bde8b00887bc7 Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 14 Oct 2022 18:17:57 +0200 Subject: [PATCH] Prepare for cloning address spaces, not there yet --- kernel/include/memory/AddressSpace.h | 10 +++- kernel/include/thread/Scheduler.h | 3 +- kernel/src/memory/AddressSpace.cpp | 69 +++++++--------------------- kernel/src/sys/exec.cpp | 4 -- kernel/src/thread/Scheduler.cpp | 10 +--- 5 files changed, 28 insertions(+), 68 deletions(-) diff --git a/kernel/include/memory/AddressSpace.h b/kernel/include/memory/AddressSpace.h index a2af46fe..b6158a07 100644 --- a/kernel/include/memory/AddressSpace.h +++ b/kernel/include/memory/AddressSpace.h @@ -7,13 +7,21 @@ struct AddressSpace void destroy(); - void reset(); + void detach(); + + AddressSpace clone(); PageTable* get_pml4() { return m_pml4; } + bool is_cloned() + { + return m_cloned; + } + private: PageTable* m_pml4; + bool m_cloned; }; \ No newline at end of file diff --git a/kernel/include/thread/Scheduler.h b/kernel/include/thread/Scheduler.h index 0b0321ac..ed2d7533 100644 --- a/kernel/include/thread/Scheduler.h +++ b/kernel/include/thread/Scheduler.h @@ -10,7 +10,8 @@ namespace Scheduler void exit(int status); void sleep(unsigned long ms); void add_kernel_task(void (*task)(void)); - void add_user_task(void* task); + + Task* create_user_task(); void load_user_task(const char* filename); diff --git a/kernel/src/memory/AddressSpace.cpp b/kernel/src/memory/AddressSpace.cpp index 714c1b77..558f09f1 100644 --- a/kernel/src/memory/AddressSpace.cpp +++ b/kernel/src/memory/AddressSpace.cpp @@ -15,6 +15,11 @@ AddressSpace AddressSpace::create() void AddressSpace::destroy() { + if (m_cloned) + { + kdbgln("Will not destroy a cloned address space, I don't own it"); + return; + } uint64_t pages_freed = 0; for (int i = 0; i < 512; i++) { @@ -71,60 +76,18 @@ void AddressSpace::destroy() kdbgln("Reclaimed %ld pages from address space!", pages_freed); } -void AddressSpace::reset() +void AddressSpace::detach() { - uint64_t pages_freed = 0; - for (int i = 0; i < 512; i++) - { - PageDirectoryEntry& pdp_pde = m_pml4->entries[i]; - if (!pdp_pde.present) continue; - if (pdp_pde.larger_pages) - { - pages_freed++; - PMM::free_page((void*)pdp_pde.get_address()); - continue; - } - PageTable* pdp = (PageTable*)pdp_pde.get_address(); - for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one - { - PageDirectoryEntry& pd_pde = pdp->entries[j]; - if (!pd_pde.present) continue; - if (pd_pde.larger_pages) - { - pages_freed++; - PMM::free_page((void*)pd_pde.get_address()); - continue; - } - PageTable* pd = (PageTable*)pd_pde.get_address(); - for (int k = 0; k < 512; k++) - { - PageDirectoryEntry& pt_pde = pd->entries[k]; - if (!pt_pde.present) continue; - if (pt_pde.larger_pages) - { - pages_freed++; - PMM::free_page((void*)pt_pde.get_address()); - continue; - } - PageTable* pt = (PageTable*)pt_pde.get_address(); - for (int l = 0; l < 512; l++) - { - PageDirectoryEntry& pde = pt->entries[l]; - if (!pde.present) continue; - pages_freed++; - PMM::free_page((void*)pde.get_address()); - } - pages_freed++; - PMM::free_page(pt); - } - pages_freed++; - PMM::free_page(pd); - } - pages_freed++; - PMM::free_page(pdp); - } - + if (!m_cloned) return; + m_pml4 = (PageTable*)PMM::request_page(); VMM::install_kernel_page_directory_into_address_space(*this); + m_cloned = false; +} - kdbgln("Reclaimed %ld pages from address space!", pages_freed); +AddressSpace AddressSpace::clone() +{ + AddressSpace result; + result.m_pml4 = m_pml4; + result.m_cloned = true; + return result; } \ No newline at end of file diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index a157d6e4..e38dfbef 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -75,10 +75,6 @@ void sys_exec(Context* context, const char* pathname) // At this point, pretty much nothing can fail. - // task->address_space.reset(); - - // VMM::switch_to_user_address_space(task->address_space); - ELFImage* image = ELFLoader::load_elf_from_vfs(program); ASSERT(image); // If check_elf_image succeeded, load_elf_from_vfs MUST succeed, unless something has gone terribly // wrong. diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 5ec334bd..9e90e1a3 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -87,21 +87,16 @@ void Scheduler::add_kernel_task(void (*task)(void)) new_task->id, new_task->regs.rsp, task_num); } -void Scheduler::add_user_task(void* task) +Task* Scheduler::create_user_task() { Task* new_task = new Task; ASSERT(new_task); memset(&new_task->regs, 0, sizeof(Context)); new_task->user_task = true; new_task->id = free_tid++; - new_task->regs.rip = (uint64_t)task; new_task->allocated_stack = (uint64_t)MemoryManager::get_pages( TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right? new_task->regs.rsp = get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK); - new_task->regs.cs = 0x18 | 0x03; - new_task->regs.ss = 0x20 | 0x03; - new_task->regs.ds = 0x20 | 0x03; - new_task->regs.rflags = (1 << 21) | (1 << 9); // enable interrupts new_task->task_sleep = 0; new_task->task_time = 0; new_task->cpu_time = 0; @@ -110,10 +105,7 @@ void Scheduler::add_user_task(void* task) base_task->prev_task = new_task; new_task->next_task = base_task; end_task = new_task; - new_task->state = new_task->Running; task_num++; - kinfoln("Adding user task: starts at %lx, tid %ld, stack at %lx, total tasks: %ld", new_task->regs.rip, - new_task->id, new_task->regs.rsp, task_num); } void Scheduler::load_user_task(const char* filename)