From f60d40f3bf4dfe8ed6f63a27367d323319a4ef97 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Fri, 25 Jun 2021 16:22:43 +0200 Subject: ring3 --- kernel/gdt.c | 20 +++++++------------- kernel/gdt.h | 12 ++++++++++++ kernel/main.c | 16 ++++++++++++++++ kernel/util.c | 9 +++++++++ kernel/util.h | 4 ++++ 5 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 kernel/util.c create mode 100644 kernel/util.h (limited to 'kernel') diff --git a/kernel/gdt.c b/kernel/gdt.c index 8d1ac65..8a29032 100644 --- a/kernel/gdt.c +++ b/kernel/gdt.c @@ -1,4 +1,6 @@ +#include #include +#include #include extern void stack_top; // platform/boot.s @@ -36,16 +38,6 @@ struct lgdt_arg { uint32_t base; } __attribute__((packed)); -enum { - SEG_null, - SEG_r0data, - SEG_r0code, - SEG_r3data, - SEG_r3code, - SEG_TSS, - - SEG_end -}; static struct gdt_entry GDT[SEG_end]; static struct tss_entry TSS; static struct lgdt_arg lgdt_arg; // probably doesn't need to be global @@ -84,7 +76,7 @@ static void gdt_prepare() { GDT[SEG_r3data].ring = 3; // tss - // TODO memset(&TSS, 0, sizeof(TSS)); + memset(&TSS, 0, sizeof(TSS)); TSS.ss0 = SEG_r0data << SEG_r3data; // kernel data segment TSS.esp0 = (uint32_t) &stack_top; @@ -108,13 +100,15 @@ static void gdt_prepare() { static void gdt_load() { lgdt_arg.limit = sizeof(GDT) - 1; lgdt_arg.base = (uint32_t) &GDT; - asm("lgdt (%0)" : : "b" (&lgdt_arg)); + asm("lgdt (%0)" : : "r" (&lgdt_arg) : "memory"); + + asm("ltr %%ax" : : "a" (SEG_TSS << 3 | 3) : "memory"); } static void gdt_check() { tty_write("checking gdt...", 15); asm("mov %0, %%ds;" - : : "r" (SEG_r0data << 3)); + : : "r" (SEG_r0data << 3) : "memory"); tty_write("ok", 2); } diff --git a/kernel/gdt.h b/kernel/gdt.h index 9ae366c..9e5a6a5 100644 --- a/kernel/gdt.h +++ b/kernel/gdt.h @@ -1,3 +1,15 @@ #pragma once +enum { + SEG_null, + // order dictated by SYSENTER + SEG_r0code, + SEG_r0data, + SEG_r3code, + SEG_r3data, + SEG_TSS, + + SEG_end +}; + void gdt_init(); diff --git a/kernel/main.c b/kernel/main.c index d2f0693..e63ca14 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,8 +1,24 @@ #include #include +#include + +extern void stack_top; + +void r3_test(); void kmain() { tty_clear(); gdt_init(); + sysenter_setup(); + + tty_write("user...", 7); + sysexit(r3_test, &stack_top); +} + +void r3_test() { + tty_write("in ring3", 8); + asm("cli"); // privileged instruction, should cause a GP + tty_write(" oh no", 6); // shouldn't happen + for (;;) {} } diff --git a/kernel/util.c b/kernel/util.c new file mode 100644 index 0000000..da3ac9d --- /dev/null +++ b/kernel/util.c @@ -0,0 +1,9 @@ +#include +#include + +void *memset(void *s, int c, size_t n) { + uint8_t *s2 = s; + for (size_t i = 0; i < n; n++) + s2[i] = c; + return s; +} diff --git a/kernel/util.h b/kernel/util.h new file mode 100644 index 0000000..688ac63 --- /dev/null +++ b/kernel/util.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void *memset(void *s, int c, size_t n); -- cgit v1.2.3