From 87c135b010b9d4ee35c362076daa734b451049dc Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 25 Oct 2020 16:49:09 -0400 Subject: [PATCH] set up a GDT to stop using the one GRUB set up --- src/gdt.S | 16 ++++++++++++++++ src/gdt.c | 20 ++++++++++++++++++++ src/gdt.h | 9 +++++---- src/hos_main.c | 2 ++ 4 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 src/gdt.S create mode 100644 src/gdt.c diff --git a/src/gdt.S b/src/gdt.S new file mode 100644 index 0000000..b0dcfb9 --- /dev/null +++ b/src/gdt.S @@ -0,0 +1,16 @@ +.global gdt_set +.extern gdtr +.type gdt_set, @function +gdt_set: + lgdt gdtr + jmp $0x8, $gdt_set_reload +gdt_set_reload: + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + ret + +.size gdt_set, . - gdt_set diff --git a/src/gdt.c b/src/gdt.c new file mode 100644 index 0000000..0bba535 --- /dev/null +++ b/src/gdt.c @@ -0,0 +1,20 @@ +#include "gdt.h" + +static const gdt_entry_t gdt_entries[] = { + /* Null descriptor */ + 0u, + /* Code segment for kernel */ + gdt_build_entry(0u, 0xFFFFFu, 1u, 0u, 1u, 1u, 0u, 1u, 0u, 1u, 1u, 0u), + /* Data segment for kernel */ + gdt_build_entry(0u, 0xFFFFFu, 1u, 0u, 1u, 0u, 0u, 1u, 0u, 1u, 1u, 0u), +}; + +gdtr_t gdtr; + +void gdt_init(void) +{ + gdtr.size = sizeof(gdt_entries); + gdtr.offset_lower = (uintptr_t)gdt_entries & 0xFFFFu; + gdtr.offset_upper = (uintptr_t)gdt_entries >> 16u; + gdt_set(); +} diff --git a/src/gdt.h b/src/gdt.h index 24732f1..ef3bcc8 100644 --- a/src/gdt.h +++ b/src/gdt.h @@ -5,15 +5,13 @@ typedef struct { uint16_t size; - uint16_t offset_upper; uint16_t offset_lower; + uint16_t offset_upper; uint16_t _reserved; } gdtr_t; -#define gdt_build_gdtr(size, offset) \ - {(size), ((offset >> 16u) & 0xFFFFu), (offset & 0xFFFFu), 0u} typedef uint64_t gdt_entry_t; -#define gdt_build_entry(base, limit, p, privl, s, ex, dc, rw, ac, gr, sz, l) \ +#define gdt_build_entry(base, limit, pr, privl, s, ex, dc, rw, ac, gr, sz, l) \ (gdt_entry_t)( \ (((gdt_entry_t)base << 32) & 0xFF00000000000000ull) | /* Base 0:15 */ \ (((gdt_entry_t)gr & 0x1u) << 55) | /* Granularity (0 = bytes, 1 = blocks) */ \ @@ -30,4 +28,7 @@ typedef uint64_t gdt_entry_t; (((gdt_entry_t)base << 16) & 0x000000FFFFFF0000ull) | /* Base 0:23 */ \ ((gdt_entry_t)limit & 0x000000000000FFFFull)) /* Limit 0:15 */ +void gdt_init(void); +void gdt_set(void); + #endif diff --git a/src/hos_main.c b/src/hos_main.c index d002f47..0582d05 100644 --- a/src/hos_main.c +++ b/src/hos_main.c @@ -2,9 +2,11 @@ #include "fb.h" #include "mbinfo.h" #include "klog.h" +#include "gdt.h" void hos_main(uint32_t mbinfo_addr) { + gdt_init(); if (!mbinfo_init(mbinfo_addr)) { return;