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!
This commit is contained in:
parent
0c7c249935
commit
26211bd49f
@ -1,8 +1,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
sleep(6);
|
||||||
|
|
||||||
FILE* syms = fopen("/sys/moon.sym", "r");
|
FILE* syms = fopen("/sys/moon.sym", "r");
|
||||||
if (!syms)
|
if (!syms)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,8 @@ struct AddressSpace
|
|||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
PageTable* get_pml4()
|
PageTable* get_pml4()
|
||||||
{
|
{
|
||||||
return m_pml4;
|
return m_pml4;
|
||||||
|
@ -74,6 +74,7 @@ extern "C" void _start()
|
|||||||
});
|
});
|
||||||
|
|
||||||
Scheduler::load_user_task("/bin/init");
|
Scheduler::load_user_task("/bin/init");
|
||||||
|
Scheduler::load_user_task("/bin/sym");
|
||||||
|
|
||||||
kinfoln("Prepared scheduler tasks");
|
kinfoln("Prepared scheduler tasks");
|
||||||
|
|
||||||
|
@ -68,5 +68,63 @@ void AddressSpace::destroy()
|
|||||||
pages_freed++;
|
pages_freed++;
|
||||||
PMM::free_page(m_pml4);
|
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);
|
kdbgln("Reclaimed %ld pages from address space!", pages_freed);
|
||||||
}
|
}
|
@ -8,6 +8,7 @@
|
|||||||
#include "interrupts/Interrupts.h"
|
#include "interrupts/Interrupts.h"
|
||||||
#include "io/IO.h"
|
#include "io/IO.h"
|
||||||
#include "log/Log.h"
|
#include "log/Log.h"
|
||||||
|
#include "memory/VMM.h"
|
||||||
#include "misc/hang.h"
|
#include "misc/hang.h"
|
||||||
#include "std/string.h"
|
#include "std/string.h"
|
||||||
|
|
||||||
@ -85,6 +86,11 @@ static void try_idt_triple_fault()
|
|||||||
[[noreturn]] void reboot()
|
[[noreturn]] void reboot()
|
||||||
{
|
{
|
||||||
Interrupts::disable();
|
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");
|
kinfoln("Attempting reboot using ACPI");
|
||||||
try_acpi_reboot();
|
try_acpi_reboot();
|
||||||
kinfoln("Attempting reboot using keyboard RESET pulsing");
|
kinfoln("Attempting reboot using keyboard RESET pulsing");
|
||||||
|
@ -12,9 +12,12 @@
|
|||||||
#include "sys/elf/ELFLoader.h"
|
#include "sys/elf/ELFLoader.h"
|
||||||
#include "thread/Scheduler.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)
|
if (!kpathname)
|
||||||
{
|
{
|
||||||
context->rax = -EFAULT;
|
context->rax = -EFAULT;
|
||||||
@ -73,13 +76,11 @@ void sys_exec(Context* context, const char* pathname)
|
|||||||
// At this point, pretty much nothing can fail.
|
// At this point, pretty much nothing can fail.
|
||||||
|
|
||||||
VMM::switch_back_to_kernel_address_space();
|
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::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);
|
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
|
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);
|
kfree(kpathname);
|
||||||
|
|
||||||
return;
|
return;*/
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user