diff options
author | dzwdz | 2021-06-25 16:22:43 +0200 |
---|---|---|
committer | dzwdz | 2021-06-25 16:22:43 +0200 |
commit | f60d40f3bf4dfe8ed6f63a27367d323319a4ef97 (patch) | |
tree | 1cde54eb600106d0d1fc11927f55d5a03eb2b4aa /kernel | |
parent | 376325d08388d9103ca2f57aceb60c4a507a42aa (diff) |
ring3
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/gdt.c | 20 | ||||
-rw-r--r-- | kernel/gdt.h | 12 | ||||
-rw-r--r-- | kernel/main.c | 16 | ||||
-rw-r--r-- | kernel/util.c | 9 | ||||
-rw-r--r-- | kernel/util.h | 4 |
5 files changed, 48 insertions, 13 deletions
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 <kernel/gdt.h> #include <kernel/tty.h> +#include <kernel/util.h> #include <stdint.h> 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 <kernel/gdt.h> #include <kernel/tty.h> +#include <platform/sysenter.h> + +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 <kernel/util.h> +#include <stdint.h> + +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 <stddef.h> + +void *memset(void *s, int c, size_t n); |