refine syscalls

This commit is contained in:
apio 2022-09-29 19:17:43 +02:00
parent 46f459337c
commit f25014a8ed
10 changed files with 90 additions and 36 deletions

View File

@ -0,0 +1,18 @@
#pragma once
#include "interrupts/Context.h"
#include <stddef.h>
#define SYS_exit 0
#define SYS_yield 1
#define SYS_sleep 2
#define SYS_write 3
namespace Syscall
{
void entry(Context* context);
}
void sys_exit(Context* context);
void sys_yield(Context* context);
void sys_sleep(Context* context, uint64_t ms);
void sys_write(Context* context, const char* addr, size_t size);

View File

@ -17,7 +17,6 @@ namespace Scheduler
void task_yield(Context* context);
void task_tick(Context* context);
void task_sleep(Context* context);
void reap_task(Task* task);
void reap_tasks();

View File

@ -9,6 +9,7 @@
#include "misc/hang.h"
#include "panic/Panic.h"
#include "std/stdio.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include "trace/StackTracer.h"
@ -54,10 +55,7 @@ extern "C" void common_handler(Context* context)
}
}
if (context->number == 8) { int_panic(context, "Double fault, halting"); }
if (context->number == 48) { Scheduler::task_yield(context); }
if (context->number == 49) { Scheduler::task_exit(context); }
if (context->number == 50) { Serial::print((const char*)context->rdi); }
if (context->number == 51) { Scheduler::task_sleep(context); }
if (context->number == 66) { Syscall::entry(context); }
if (context->number == 256) { kwarnln("Unused interrupt"); }
return;
}

View File

@ -45,10 +45,7 @@ extern "C"
void isr45();
void isr46();
void isr47();
void isr48();
void isr49();
void isr50();
void isr51();
void isr66();
}
#define INSTALL_TRAP(x) IDT::add_handler(x, (void*)&isr##x, IDT_TA_TrapGate)
@ -108,11 +105,8 @@ void Interrupts::install()
INSTALL_ISR(45);
INSTALL_ISR(46);
INSTALL_ISR(47);
kdbgln("Installing handler stubs for user-accessible syscalls 48, 49, 50, 51 (30h, 31h, 32h, 33h)");
INSTALL_USER_ISR(48);
INSTALL_USER_ISR(49);
INSTALL_USER_ISR(50);
INSTALL_USER_ISR(51);
kdbgln("Installing unused handler stubs for the rest of the IDT");
for (int i = 52; i < 256; i++) { INSTALL_UNUSED(i); }
for (int i = 48; i < 256; i++) { INSTALL_UNUSED(i); }
kdbgln("Installing syscall handler stub");
INSTALL_USER_ISR(66);
}

View File

@ -133,7 +133,4 @@ IRQ 44, 12
IRQ 45, 13
IRQ 46, 14
IRQ 47, 15
SOFT 48
SOFT 49
SOFT 50
SOFT 51
SOFT 66

View File

@ -8,17 +8,22 @@ _main:
global _userspace
_userspace:
mov rdi, 4000 ; 4000 ms / 4 seconds
int 33h ; Sleep
mov rax, 2 ; sys_sleep
int 42h ; syscall
mov rcx, 10
.loop:
dec rcx
mov rdi, .message
int 32h ; Print string
mov rsi, 22
mov rax, 3 ; sys_write
int 42h ; syscall
mov rdi, 200 ; 200 ms / 0.2 seconds
int 33h ; Sleep
mov rax, 2
int 42h ; syscall
cmp rcx, 0
jne .loop
cli ; WE ARE IN RING 3!! So this should GPF and the kernel should exit us as "misbehaved"
int 31h ; Exit current task
mov rax, 0
int 42h ; Exit current task
.message:
db "hello from userspace!", 0xA, 0

View File

@ -0,0 +1,24 @@
#include "sys/Syscall.h"
#include "io/Serial.h"
#include "thread/Scheduler.h"
void Syscall::entry(Context* context)
{
asm volatile("cli");
switch (context->rax)
{
case SYS_exit: // sys_exit
sys_exit(context);
break;
case SYS_yield: // sys_yield
sys_yield(context);
break;
case SYS_sleep: // sys_sleep
sys_sleep(context, context->rdi);
break;
case SYS_write: // sys_write
sys_write(context, (const char*)context->rdi, context->rsi);
break;
default: context->rax = -1; break;
}
}

21
kernel/src/sys/sched.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "thread/Scheduler.h"
void sys_exit(Context* context)
{
Scheduler::task_exit(context);
}
void sys_yield(Context* context)
{
context->rax = 0;
Scheduler::task_yield(context);
}
void sys_sleep(Context* context, uint64_t ms)
{
context->rax = 0;
Task* task = Scheduler::current_task();
task->task_sleep = ms;
task->state = task->Sleeping;
Scheduler::task_yield(context);
}

8
kernel/src/sys/stdio.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "interrupts/Context.h"
#include "io/Serial.h"
void sys_write(Context* context, const char* addr, size_t size)
{
context->rax = size;
Serial::write(addr, size);
}

View File

@ -253,29 +253,19 @@ void Scheduler::task_yield(Context* context)
return;
}
void Scheduler::task_sleep(Context* context)
{
ASSERT(Interrupts::is_in_handler());
Interrupts::disable();
Task* task = current_task();
task->task_sleep = context->rdi;
task->state = task->Sleeping;
task_yield(context);
}
void Scheduler::yield()
{
asm volatile("int $48");
asm volatile("int $0x42" : : "a"(1));
}
void Scheduler::exit()
{
asm volatile("int $49");
asm volatile("int $0x42" : : "a"(0));
}
void Scheduler::sleep(unsigned long ms)
{
asm volatile("int $51" : : "D"(ms));
asm volatile("int $0x42" : : "D"(ms), "a"(2));
}
Task* Scheduler::current_task()