refine syscalls
This commit is contained in:
parent
46f459337c
commit
f25014a8ed
18
kernel/include/sys/Syscall.h
Normal file
18
kernel/include/sys/Syscall.h
Normal 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);
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
|
@ -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
|
24
kernel/src/sys/Syscall.cpp
Normal file
24
kernel/src/sys/Syscall.cpp
Normal 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
21
kernel/src/sys/sched.cpp
Normal 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
8
kernel/src/sys/stdio.cpp
Normal 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);
|
||||
}
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user