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_yield(Context* context);
void task_tick(Context* context); void task_tick(Context* context);
void task_sleep(Context* context);
void reap_task(Task* task); void reap_task(Task* task);
void reap_tasks(); void reap_tasks();

View File

@ -9,6 +9,7 @@
#include "misc/hang.h" #include "misc/hang.h"
#include "panic/Panic.h" #include "panic/Panic.h"
#include "std/stdio.h" #include "std/stdio.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h" #include "thread/Scheduler.h"
#include "trace/StackTracer.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 == 8) { int_panic(context, "Double fault, halting"); }
if (context->number == 48) { Scheduler::task_yield(context); } if (context->number == 66) { Syscall::entry(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 == 256) { kwarnln("Unused interrupt"); } if (context->number == 256) { kwarnln("Unused interrupt"); }
return; return;
} }

View File

@ -45,10 +45,7 @@ extern "C"
void isr45(); void isr45();
void isr46(); void isr46();
void isr47(); void isr47();
void isr48(); void isr66();
void isr49();
void isr50();
void isr51();
} }
#define INSTALL_TRAP(x) IDT::add_handler(x, (void*)&isr##x, IDT_TA_TrapGate) #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(45);
INSTALL_ISR(46); INSTALL_ISR(46);
INSTALL_ISR(47); 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"); 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 45, 13
IRQ 46, 14 IRQ 46, 14
IRQ 47, 15 IRQ 47, 15
SOFT 48 SOFT 66
SOFT 49
SOFT 50
SOFT 51

View File

@ -8,17 +8,22 @@ _main:
global _userspace global _userspace
_userspace: _userspace:
mov rdi, 4000 ; 4000 ms / 4 seconds mov rdi, 4000 ; 4000 ms / 4 seconds
int 33h ; Sleep mov rax, 2 ; sys_sleep
int 42h ; syscall
mov rcx, 10 mov rcx, 10
.loop: .loop:
dec rcx dec rcx
mov rdi, .message 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 mov rdi, 200 ; 200 ms / 0.2 seconds
int 33h ; Sleep mov rax, 2
int 42h ; syscall
cmp rcx, 0 cmp rcx, 0
jne .loop jne .loop
cli ; WE ARE IN RING 3!! So this should GPF and the kernel should exit us as "misbehaved" 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: .message:
db "hello from userspace!", 0xA, 0 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; 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() void Scheduler::yield()
{ {
asm volatile("int $48"); asm volatile("int $0x42" : : "a"(1));
} }
void Scheduler::exit() void Scheduler::exit()
{ {
asm volatile("int $49"); asm volatile("int $0x42" : : "a"(0));
} }
void Scheduler::sleep(unsigned long ms) void Scheduler::sleep(unsigned long ms)
{ {
asm volatile("int $51" : : "D"(ms)); asm volatile("int $0x42" : : "D"(ms), "a"(2));
} }
Task* Scheduler::current_task() Task* Scheduler::current_task()