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