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