From 7d5a9792e57b4088cce5cc97837eb04016b57a4d Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Thu, 31 Oct 2019 00:49:00 +0100 Subject: Implemented basic syscalls and user mode Doesn't completely work right now --- src/kernel/syscall/syscall.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/kernel/syscall/syscall.h | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/kernel/syscall/syscall.c create mode 100644 src/kernel/syscall/syscall.h (limited to 'src/kernel/syscall') diff --git a/src/kernel/syscall/syscall.c b/src/kernel/syscall/syscall.c new file mode 100644 index 0000000..d1dbd6b --- /dev/null +++ b/src/kernel/syscall/syscall.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include + +DEFN_SYSCALL1(vesa_draw_string, 0, const char *); + +DEFN_SYSCALL1(vesa_draw_number, 1, int); + +DEFN_SYSCALL1(serial_write, 2, const char *); + +static void *syscalls[3] = { + &vesa_draw_string, + &vesa_draw_number, + &serial_write, +}; +uint32_t num_syscalls = 3; + +void syscall_handler(struct regs *r) { + if (r->eax >= num_syscalls) + return; + + void *location = syscalls[r->eax]; + + int ret; + asm volatile (" \ + push %1; \ + push %2; \ + push %3; \ + push %4; \ + push %5; \ + call *%6; \ + pop %%ebx; \ + pop %%ebx; \ + pop %%ebx; \ + pop %%ebx; \ + pop %%ebx; \ + " : "=a" (ret) : "r" (r->edi), "r" (r->esi), "r" (r->edx), "r" (r->ecx), "r" (r->ebx), "r" (location)); + r->eax = ret; +} + +void syscalls_install() { + irq_install_handler(0x80, &syscall_handler); +} diff --git a/src/kernel/syscall/syscall.h b/src/kernel/syscall/syscall.h new file mode 100644 index 0000000..d35c4e6 --- /dev/null +++ b/src/kernel/syscall/syscall.h @@ -0,0 +1,44 @@ +#ifndef MELVIX_SYSCALL_H +#define MELVIX_SYSCALL_H + +#include + +void syscalls_install(); + +void syscall_handler(struct regs *r); + +#define DECL_SYSCALL0(fn) int syscall_##fn(); +#define DECL_SYSCALL1(fn, p1) int syscall_##fn(p1); +#define DECL_SYSCALL2(fn, p1, p2) int syscall_##fn(p1,p2); +#define DECL_SYSCALL3(fn, p1, p2, p3) int syscall_##fn(p1,p2,p3); +#define DECL_SYSCALL4(fn, p1, p2, p3, p4) int syscall_##fn(p1,p2,p3,p4); +#define DECL_SYSCALL5(fn, p1, p2, p3, p4, p5) int syscall_##fn(p1,p2,p3,p4,p5); + +#define DEFN_SYSCALL0(fn, num) \ +int syscall_##fn() { \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num)); \ + return a; \ +} + +#define DEFN_SYSCALL1(fn, num, P1) \ +int syscall_##fn(P1 p1) { \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1)); \ + return a; \ +} + +#define DEFN_SYSCALL2(fn, num, P1, P2) \ +int syscall_##fn(P1 p1, P2 p2) { \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2)); \ + return a; \ +} + +DECL_SYSCALL1(vesa_draw_string, const char *) + +DECL_SYSCALL1(vesa_draw_number, int) + +DECL_SYSCALL1(serial_write, const char *) + +#endif -- cgit v1.2.3 From 2c7b6e0431d6dfbaf385d30e87e7eb9fd4a0e61d Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Thu, 31 Oct 2019 15:19:12 +0100 Subject: Some user mode improvements --- src/kernel/boot.asm | 29 ++++++++++++++--------------- src/kernel/gdt/gdt.c | 2 +- src/kernel/graphics/vesa.c | 2 +- src/kernel/kernel.c | 3 ++- src/kernel/syscall/syscall.c | 3 ++- src/userspace/main.c | 6 ++++++ 6 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 src/userspace/main.c (limited to 'src/kernel/syscall') diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index 8f24066..2501ed9 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -51,23 +51,22 @@ stublet: %include "src/kernel/interact.asm" global switch_to_user +extern test_user switch_to_user: - cli - mov ax,0x23 - mov ds,ax - mov es,ax - mov fs,ax - mov gs,ax + sti + mov ax, 0x23 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax - mov eax,esp - push 0x23 - push eax - pushf - pop eax - or eax, 0x200 - push eax - push 0x1B - iret + mov eax, esp + push 0x23 + push eax + pushf + push 0x1B + push test_user + iret ; Store the stack SECTION .bss diff --git a/src/kernel/gdt/gdt.c b/src/kernel/gdt/gdt.c index b933950..1c69602 100644 --- a/src/kernel/gdt/gdt.c +++ b/src/kernel/gdt/gdt.c @@ -97,7 +97,7 @@ void gdt_install() { // Remove old GDT and install the new changes! gdt_flush(); - tss_flush(); // FAILS + tss_flush(); vga_log("Installed Global Descriptor Table", 2); } diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index 32ca717..858ed95 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -167,7 +167,7 @@ void set_optimal_resolution() { switch_to_vga(); } else vga_log("Mode detection succeeded", 11); - timer_wait(500); + // timer_wait(500); vbe_set_mode(highest); diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index dd15409..b133a0c 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -39,10 +39,11 @@ void kernel_main(struct multiboot *mboot_ptr) { initrd_test(); // User mode! + info("Switching to user mode..."); syscalls_install(); switch_to_user(); - syscall_serial_write("Hello, user world!\n"); + panic("This should NOT happen!"); // asm volatile ("div %0" :: "r"(0)); // Exception testing x/0 loop: diff --git a/src/kernel/syscall/syscall.c b/src/kernel/syscall/syscall.c index d1dbd6b..dec3e8e 100644 --- a/src/kernel/syscall/syscall.c +++ b/src/kernel/syscall/syscall.c @@ -18,6 +18,7 @@ static void *syscalls[3] = { uint32_t num_syscalls = 3; void syscall_handler(struct regs *r) { + serial_write("SYSCALL"); if (r->eax >= num_syscalls) return; @@ -41,5 +42,5 @@ void syscall_handler(struct regs *r) { } void syscalls_install() { - irq_install_handler(0x80, &syscall_handler); + irq_install_handler(0x80, syscall_handler); } diff --git a/src/userspace/main.c b/src/userspace/main.c new file mode 100644 index 0000000..d332d8e --- /dev/null +++ b/src/userspace/main.c @@ -0,0 +1,6 @@ +#include + +void test_user() { + asm volatile ("hlt"); + syscall_serial_write("Hello, user world!\n"); +} \ No newline at end of file -- cgit v1.2.3