From f25014a8edc5bfa2a04114d8982f6f64ec270b3b Mon Sep 17 00:00:00 2001 From: apio Date: Thu, 29 Sep 2022 19:17:43 +0200 Subject: [PATCH] refine syscalls --- kernel/include/sys/Syscall.h | 18 ++++++++++++++++++ kernel/include/thread/Scheduler.h | 1 - kernel/src/interrupts/Entry.cpp | 6 ++---- kernel/src/interrupts/Install.cpp | 14 ++++---------- kernel/src/interrupts/InterruptEntry.asm | 5 +---- kernel/src/main.asm | 13 +++++++++---- kernel/src/sys/Syscall.cpp | 24 ++++++++++++++++++++++++ kernel/src/sys/sched.cpp | 21 +++++++++++++++++++++ kernel/src/sys/stdio.cpp | 8 ++++++++ kernel/src/thread/Scheduler.cpp | 16 +++------------- 10 files changed, 90 insertions(+), 36 deletions(-) create mode 100644 kernel/include/sys/Syscall.h create mode 100644 kernel/src/sys/Syscall.cpp create mode 100644 kernel/src/sys/sched.cpp create mode 100644 kernel/src/sys/stdio.cpp diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h new file mode 100644 index 00000000..b298d554 --- /dev/null +++ b/kernel/include/sys/Syscall.h @@ -0,0 +1,18 @@ +#pragma once +#include "interrupts/Context.h" +#include + +#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); \ No newline at end of file diff --git a/kernel/include/thread/Scheduler.h b/kernel/include/thread/Scheduler.h index 7ce7d263..6359dabe 100644 --- a/kernel/include/thread/Scheduler.h +++ b/kernel/include/thread/Scheduler.h @@ -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(); diff --git a/kernel/src/interrupts/Entry.cpp b/kernel/src/interrupts/Entry.cpp index 754a8c6a..1d579474 100644 --- a/kernel/src/interrupts/Entry.cpp +++ b/kernel/src/interrupts/Entry.cpp @@ -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; } \ No newline at end of file diff --git a/kernel/src/interrupts/Install.cpp b/kernel/src/interrupts/Install.cpp index ee266353..8c33012c 100644 --- a/kernel/src/interrupts/Install.cpp +++ b/kernel/src/interrupts/Install.cpp @@ -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); } \ No newline at end of file diff --git a/kernel/src/interrupts/InterruptEntry.asm b/kernel/src/interrupts/InterruptEntry.asm index 8a10aefd..7ee280e0 100644 --- a/kernel/src/interrupts/InterruptEntry.asm +++ b/kernel/src/interrupts/InterruptEntry.asm @@ -133,7 +133,4 @@ IRQ 44, 12 IRQ 45, 13 IRQ 46, 14 IRQ 47, 15 -SOFT 48 -SOFT 49 -SOFT 50 -SOFT 51 \ No newline at end of file +SOFT 66 \ No newline at end of file diff --git a/kernel/src/main.asm b/kernel/src/main.asm index 8d0b102e..c4c514cd 100644 --- a/kernel/src/main.asm +++ b/kernel/src/main.asm @@ -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 \ No newline at end of file diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp new file mode 100644 index 00000000..dadb8eac --- /dev/null +++ b/kernel/src/sys/Syscall.cpp @@ -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; + } +} \ No newline at end of file diff --git a/kernel/src/sys/sched.cpp b/kernel/src/sys/sched.cpp new file mode 100644 index 00000000..b198cad1 --- /dev/null +++ b/kernel/src/sys/sched.cpp @@ -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); +} \ No newline at end of file diff --git a/kernel/src/sys/stdio.cpp b/kernel/src/sys/stdio.cpp new file mode 100644 index 00000000..1d4c6d9f --- /dev/null +++ b/kernel/src/sys/stdio.cpp @@ -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); +} \ No newline at end of file diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index ebb05340..46413039 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -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()