Almost there!
This commit is contained in:
parent
83982a24e2
commit
24272c57ef
@ -13,8 +13,12 @@ namespace VMM
|
||||
void init(); // Fetch page table from cr3
|
||||
|
||||
void switch_to_user_address_space(AddressSpace& space);
|
||||
void switch_to_previous_user_address_space();
|
||||
void switch_back_to_kernel_address_space();
|
||||
|
||||
void enter_syscall_context();
|
||||
void exit_syscall_context();
|
||||
|
||||
void apply_address_space();
|
||||
|
||||
bool is_using_kernel_address_space();
|
||||
|
@ -57,6 +57,10 @@ extern "C" void _start()
|
||||
|
||||
kinfoln("Loaded IDT");
|
||||
|
||||
PIT::initialize(1000); // 1000 times per second
|
||||
|
||||
kinfoln("Prepared PIT");
|
||||
|
||||
Scheduler::init();
|
||||
|
||||
kinfoln("Prepared scheduler");
|
||||
@ -78,10 +82,6 @@ extern "C" void _start()
|
||||
|
||||
Init::finish_kernel_boot();
|
||||
|
||||
PIT::initialize(1000); // 1000 times per second
|
||||
|
||||
kinfoln("Prepared PIT");
|
||||
|
||||
PIC::remap();
|
||||
PIC::enable_master(0b11111100); // enable keyboard and PIT
|
||||
PIC::enable_slave(0b11111111);
|
||||
|
@ -22,6 +22,27 @@ void VMM::switch_to_user_address_space(AddressSpace& space)
|
||||
current_pml4 = user_address_space->get_pml4();
|
||||
}
|
||||
|
||||
void VMM::switch_to_previous_user_address_space()
|
||||
{
|
||||
current_pml4 = user_address_space->get_pml4();
|
||||
}
|
||||
|
||||
void VMM::enter_syscall_context()
|
||||
{
|
||||
if (current_pml4 != kernel_pml4)
|
||||
{
|
||||
current_pml4 = kernel_pml4;
|
||||
apply_address_space();
|
||||
switch_to_previous_user_address_space();
|
||||
}
|
||||
}
|
||||
|
||||
void VMM::exit_syscall_context()
|
||||
{
|
||||
if (current_pml4 != user_address_space->get_pml4()) { switch_to_previous_user_address_space(); }
|
||||
apply_address_space();
|
||||
}
|
||||
|
||||
void VMM::apply_address_space()
|
||||
{
|
||||
asm volatile("mov %0, %%cr3" : : "r"(current_pml4));
|
||||
|
@ -1,11 +1,13 @@
|
||||
#include "sys/Syscall.h"
|
||||
#include "errno.h"
|
||||
#include "io/Serial.h"
|
||||
#include "memory/VMM.h"
|
||||
#include "thread/Scheduler.h"
|
||||
|
||||
void Syscall::entry(Context* context)
|
||||
{
|
||||
asm volatile("cli");
|
||||
VMM::enter_syscall_context();
|
||||
switch (context->rax)
|
||||
{
|
||||
case SYS_exit: sys_exit(context, (int)context->rdi); break;
|
||||
@ -24,4 +26,5 @@ void Syscall::entry(Context* context)
|
||||
case SYS_exec: sys_exec(context, (const char*)context->rdi); break;
|
||||
default: context->rax = -ENOSYS; break;
|
||||
}
|
||||
VMM::exit_syscall_context();
|
||||
}
|
@ -94,9 +94,15 @@ ELFImage* ELFLoader::load_elf_from_vfs(VFS::Node* node)
|
||||
Utilities::round_down_to_nearest_page(phdr.p_vaddr), pages, MAP_READ_WRITE) +
|
||||
(phdr.p_vaddr % PAGE_SIZE));
|
||||
|
||||
VMM::apply_address_space();
|
||||
|
||||
VFS::read(node, phdr.p_offset, phdr.p_filesz, (char*)buffer);
|
||||
memset((void*)((uint64_t)buffer + phdr.p_filesz), 0, phdr.p_memsz - phdr.p_filesz);
|
||||
|
||||
VMM::switch_back_to_kernel_address_space();
|
||||
VMM::apply_address_space();
|
||||
VMM::switch_to_previous_user_address_space();
|
||||
|
||||
MemoryManager::protect(buffer, pages, phdr.p_flags & 2 ? MAP_READ_WRITE | MAP_USER : MAP_USER);
|
||||
|
||||
image = (ELFImage*)krealloc(image, (sizeof(ELFImage) - sizeof(ELFSection)) +
|
||||
|
@ -55,6 +55,7 @@ void Scheduler::init()
|
||||
// the other registers will be saved next task switch
|
||||
|
||||
frequency = 1000 / PIT::frequency();
|
||||
kdbgln("frequency: %ld", frequency);
|
||||
}
|
||||
|
||||
void Scheduler::add_kernel_task(void (*task)(void))
|
||||
@ -182,7 +183,12 @@ void Scheduler::reap_task(Task* task)
|
||||
task_num--;
|
||||
Task* exiting_task = task;
|
||||
ASSERT(task->id != 0); // WHY IN THE WORLD WOULD WE BE REAPING THE IDLE TASK?
|
||||
if (exiting_task->is_user_task()) { VMM::switch_to_user_address_space(exiting_task->address_space); }
|
||||
if (exiting_task->is_user_task())
|
||||
{
|
||||
VMM::switch_back_to_kernel_address_space();
|
||||
VMM::apply_address_space();
|
||||
VMM::switch_to_user_address_space(exiting_task->address_space);
|
||||
}
|
||||
kinfoln("reaping task %ld, exited with code %ld", exiting_task->id, exiting_task->exit_status);
|
||||
if (exiting_task->allocated_stack)
|
||||
MemoryManager::release_pages((void*)exiting_task->allocated_stack, TASK_PAGES_IN_STACK);
|
||||
@ -194,6 +200,7 @@ void Scheduler::reap_task(Task* task)
|
||||
if (exiting_task->is_user_task())
|
||||
{
|
||||
VMM::switch_back_to_kernel_address_space();
|
||||
VMM::apply_address_space();
|
||||
Interrupts::push_and_enable();
|
||||
exiting_task->address_space.destroy();
|
||||
Interrupts::pop();
|
||||
|
Loading…
Reference in New Issue
Block a user