From 26211bd49f3161e3380c5d4ad14ae86c74b7d93b Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 14 Oct 2022 16:46:00 +0200 Subject: [PATCH] It (almost) works now The only thing doing weird stuff is exec(), so that's commented out and throws ENOSYS right now. But we have two user tasks running in parallel, isolated from each other! --- apps/src/sym.c | 3 ++ kernel/include/memory/AddressSpace.h | 2 + kernel/src/main.cpp | 1 + kernel/src/memory/AddressSpace.cpp | 58 ++++++++++++++++++++++++++++ kernel/src/misc/reboot.cpp | 6 +++ kernel/src/sys/exec.cpp | 19 ++++----- 6 files changed, 80 insertions(+), 9 deletions(-) diff --git a/apps/src/sym.c b/apps/src/sym.c index d5ed3927..f170c691 100644 --- a/apps/src/sym.c +++ b/apps/src/sym.c @@ -1,8 +1,11 @@ #include #include +#include int main() { + sleep(6); + FILE* syms = fopen("/sys/moon.sym", "r"); if (!syms) { diff --git a/kernel/include/memory/AddressSpace.h b/kernel/include/memory/AddressSpace.h index 082ec607..a2af46fe 100644 --- a/kernel/include/memory/AddressSpace.h +++ b/kernel/include/memory/AddressSpace.h @@ -7,6 +7,8 @@ struct AddressSpace void destroy(); + void reset(); + PageTable* get_pml4() { return m_pml4; diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 1d1fa288..b066d9bc 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -74,6 +74,7 @@ extern "C" void _start() }); Scheduler::load_user_task("/bin/init"); + Scheduler::load_user_task("/bin/sym"); kinfoln("Prepared scheduler tasks"); diff --git a/kernel/src/memory/AddressSpace.cpp b/kernel/src/memory/AddressSpace.cpp index 541a73b4..714c1b77 100644 --- a/kernel/src/memory/AddressSpace.cpp +++ b/kernel/src/memory/AddressSpace.cpp @@ -68,5 +68,63 @@ void AddressSpace::destroy() pages_freed++; PMM::free_page(m_pml4); + kdbgln("Reclaimed %ld pages from address space!", pages_freed); +} + +void AddressSpace::reset() +{ + 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); + } + + VMM::install_kernel_page_directory_into_address_space(*this); + kdbgln("Reclaimed %ld pages from address space!", pages_freed); } \ No newline at end of file diff --git a/kernel/src/misc/reboot.cpp b/kernel/src/misc/reboot.cpp index 30800dda..8f134556 100644 --- a/kernel/src/misc/reboot.cpp +++ b/kernel/src/misc/reboot.cpp @@ -8,6 +8,7 @@ #include "interrupts/Interrupts.h" #include "io/IO.h" #include "log/Log.h" +#include "memory/VMM.h" #include "misc/hang.h" #include "std/string.h" @@ -85,6 +86,11 @@ static void try_idt_triple_fault() [[noreturn]] void reboot() { Interrupts::disable(); + if (!VMM::is_using_kernel_address_space()) + { + VMM::switch_back_to_kernel_address_space(); + VMM::apply_address_space(); + } kinfoln("Attempting reboot using ACPI"); try_acpi_reboot(); kinfoln("Attempting reboot using keyboard RESET pulsing"); diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index 6eeeb6e3..c160b804 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -12,9 +12,12 @@ #include "sys/elf/ELFLoader.h" #include "thread/Scheduler.h" -void sys_exec(Context* context, const char* pathname) +void sys_exec(Context* context, const char*) { - char* kpathname = Syscall::strdup_from_user(pathname); + context->rax = -ENOSYS; // FIXME: Make exec() work under separate address spaces. + return; + + /*char* kpathname = Syscall::strdup_from_user(pathname); if (!kpathname) { context->rax = -EFAULT; @@ -73,13 +76,11 @@ void sys_exec(Context* context, const char* pathname) // At this point, pretty much nothing can fail. VMM::switch_back_to_kernel_address_space(); - - task->address_space.destroy(); - task->address_space = AddressSpace::create(); - - VMM::switch_to_user_address_space(task->address_space); VMM::apply_address_space(); - VMM::enter_syscall_context(); + + 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 @@ -98,5 +99,5 @@ void sys_exec(Context* context, const char* pathname) kfree(kpathname); - return; + return;*/ } \ No newline at end of file