From a6598886f0f46eab06c624cabadf82403c4c22cc Mon Sep 17 00:00:00 2001 From: Alexander Myltsev Date: Wed, 14 Dec 2022 16:50:10 +0300 Subject: [PATCH] Add two syscalls. --- Makefile | 4 ++-- cpu/idt.c | 22 ++++++++++++++++++++++ cpu/isr.h | 1 - cpu/vectors.S | 4 ++-- proc.c | 6 ++++++ proc.h | 1 + syscall.h | 9 +++++++++ user/crt.c | 9 ++++++++- user/greet.c | 7 +++++++ 9 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 syscall.h create mode 100644 user/greet.c diff --git a/Makefile b/Makefile index 9615153..2e8fc22 100644 --- a/Makefile +++ b/Makefile @@ -47,8 +47,8 @@ debug-nox: image.bin -ex "break _start" \ -ex "continue" -fs.img: kernel.bin tools/mkfs user/false - tools/mkfs $@ $< user/false +fs.img: kernel.bin tools/mkfs user/false user/greet + tools/mkfs $@ $< user/false user/greet LDFLAGS=-m elf_i386 diff --git a/cpu/idt.c b/cpu/idt.c index 60cf250..4b4137c 100644 --- a/cpu/idt.c +++ b/cpu/idt.c @@ -1,5 +1,7 @@ #include "isr.h" #include "gdt.h" +#include "../syscall.h" +#include "../proc.h" #include "../drivers/port.h" #include "../console.h" @@ -83,6 +85,26 @@ void register_interrupt_handler(uint8_t i, isr_t handler) { } void trap(registers_t *r) { + if (r->int_no == T_SYSCALL) { + switch (r->eax) { + case SYS_exit: + if (r->ebx == 0) { + printk("* success\n"); + } else { + printk("* failure\n"); + } + killproc(); + case SYS_greet: + printk("Hello world!\n"); + r->eax = 0; + break; + default: + printk("Unknown syscall\n"); + r->eax = -1; + } + return; + } + if (r->int_no < 32) { const char* msg = "Reserved"; if (r->int_no < ARRLEN(exception_messages)) { diff --git a/cpu/isr.h b/cpu/isr.h index e7d52fd..de12f30 100644 --- a/cpu/isr.h +++ b/cpu/isr.h @@ -18,7 +18,6 @@ enum { IRQ13, IRQ14, IRQ15, - T_SYSCALL = 0x84, }; /* Struct which aggregates many registers. diff --git a/cpu/vectors.S b/cpu/vectors.S index 21ddded..b1131fb 100644 --- a/cpu/vectors.S +++ b/cpu/vectors.S @@ -8,8 +8,8 @@ alltraps: pushl %gs pushal - //mov $10, %ax - //mov %ax, %ds + mov $0x10, %ax + mov %ax, %ds # Call trap(tf), where tf=%esp pushl %esp diff --git a/proc.c b/proc.c index 6b19510..48d9800 100644 --- a/proc.c +++ b/proc.c @@ -67,3 +67,9 @@ void run_elf(const char* name) { // process has finished } + +_Noreturn void killproc() { + void* task_stack; + swtch(&task_stack, vm->kernel_thread); + __builtin_unreachable(); +} diff --git a/proc.h b/proc.h index 86a4322..54ede88 100644 --- a/proc.h +++ b/proc.h @@ -1,3 +1,4 @@ #pragma once void run_elf(const char* name); +_Noreturn void killproc(); diff --git a/syscall.h b/syscall.h new file mode 100644 index 0000000..4c9ba03 --- /dev/null +++ b/syscall.h @@ -0,0 +1,9 @@ +#pragma once + +enum { + T_SYSCALL = 0x84, + SYS_exit = 0, + SYS_greet = 1, +}; + +int syscall(int call, int arg); diff --git a/user/crt.c b/user/crt.c index 17320ea..5032810 100644 --- a/user/crt.c +++ b/user/crt.c @@ -1,8 +1,15 @@ +#include "../syscall.h" + int main(); +int syscall(int call, int arg) { + asm("int $0x84": "+a"(call) : "b"(arg)); + return call; +} + _Noreturn void _exit(int exit_status) { - asm("int $0x84": : "a"(0), "b"(exit_status)); + syscall(SYS_exit, exit_status); __builtin_unreachable(); } diff --git a/user/greet.c b/user/greet.c new file mode 100644 index 0000000..28b539b --- /dev/null +++ b/user/greet.c @@ -0,0 +1,7 @@ +#include "../syscall.h" + +int main(void) { + syscall(SYS_greet, 0); + syscall(SYS_greet, 0); + return 0; +}