diff options
Diffstat (limited to 'src/kernel/gdt.c')
-rw-r--r-- | src/kernel/gdt.c | 121 |
1 files changed, 0 insertions, 121 deletions
diff --git a/src/kernel/gdt.c b/src/kernel/gdt.c deleted file mode 100644 index b0d6320..0000000 --- a/src/kernel/gdt.c +++ /dev/null @@ -1,121 +0,0 @@ -#include <kernel/gdt.h> -#include <kernel/util.h> -#include <stdint.h> - -extern void stack_top; // platform/boot.s - -struct gdt_entry { - uint64_t limit_low : 16; - uint64_t base_low : 24; - uint64_t accessed : 1; // set by the processor - // CODE | DATA - uint64_t rw : 1; // readable? | writeable? - uint64_t conforming : 1; // conforming? | expands down? - uint64_t code : 1; // 1 | 0 - - uint64_t codeordata : 1; // 1 for everything other than TSS and LDT - uint64_t ring : 2; - uint64_t present : 1; // always 1 - uint64_t limit_high : 4; - uint64_t available : 1; // ??? - uint64_t long_mode : 1; - uint64_t x32 : 1; - uint64_t gran : 1; // 1 - 4kb, 0 - 1b - uint64_t base_high : 8; -} __attribute__((packed)); - -struct tss_entry { - uint32_t prev_tss; // unused - uint32_t esp0; // kernel mode stack pointer - uint32_t ss0; // kernel mode stack segment - // total size = 0x68 (?) - 3 * sizeof(uint32_t) = 5c - uint8_t _unused[0x5c]; -} __attribute__((packed)); - -struct lgdt_arg { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); - -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 - -static void gdt_prepare(); -static void gdt_load(); - - -static void gdt_prepare() { - GDT[SEG_null].present = 0; - - GDT[SEG_r0data].limit_low = 0xFFFF; - GDT[SEG_r0data].limit_high = 0xF; - GDT[SEG_r0data].gran = 1; // 4KB * 0xFFFFF = (almost) 4GB - GDT[SEG_r0data].base_low = 0; - GDT[SEG_r0data].base_high = 0; - GDT[SEG_r0data].accessed = 0; - GDT[SEG_r0data].rw = 1; - GDT[SEG_r0data].conforming = 0; - GDT[SEG_r0data].code = 0; - GDT[SEG_r0data].codeordata = 1; - GDT[SEG_r0data].ring = 0; - GDT[SEG_r0data].present = 1; - GDT[SEG_r0data].long_mode = 0; // ??? - GDT[SEG_r0data].available = 1; // ??? - GDT[SEG_r0data].x32 = 1; - - // copy to r0 code - GDT[SEG_r0code] = GDT[SEG_r0data]; - GDT[SEG_r0code].code = 1; - - GDT[SEG_r3data] = GDT[SEG_r0data]; - GDT[SEG_r3data].ring = 3; - GDT[SEG_r3code] = GDT[SEG_r0code]; - GDT[SEG_r3code].ring = 3; - - // tss - memset(&TSS, 0, sizeof(TSS)); - TSS.ss0 = SEG_r0data << 3; // kernel data segment - TSS.esp0 = (uint32_t) &stack_top; - - GDT[SEG_TSS].limit_low = sizeof(TSS); - GDT[SEG_TSS].base_low = (uint32_t) &TSS; - GDT[SEG_TSS].accessed = 1; // 1 for TSS - GDT[SEG_TSS].rw = 0; // 1 busy / 0 not busy - GDT[SEG_TSS].conforming = 0; // 0 for TSS - GDT[SEG_TSS].code = 1; // 32bit - GDT[SEG_TSS].codeordata = 0; // is a system entry - GDT[SEG_TSS].ring = 3; - GDT[SEG_TSS].present = 1; - GDT[SEG_TSS].limit_high = (sizeof(TSS) >> 16) & 0xf; - GDT[SEG_TSS].available = 0; // 0 for TSS - GDT[SEG_TSS].long_mode = 0; - GDT[SEG_TSS].x32 = 0; // idk - GDT[SEG_TSS].gran = 0; - GDT[SEG_TSS].base_high = (((uint32_t) &TSS) >> 24) & 0xff; -} - -void change_cs(int seg); // temporary - -static void gdt_load() { - lgdt_arg.limit = sizeof(GDT) - 1; - lgdt_arg.base = (uint32_t) &GDT; - asm("lgdt (%0)" - : : "r" (&lgdt_arg) : "memory"); - asm("ltr %%ax" - : : "a" (SEG_TSS << 3 | 3) : "memory"); - - // update all segment registers - change_cs(SEG_r0code << 3); - asm("mov %0, %%ds;" - "mov %0, %%ss;" - "mov %0, %%es;" - "mov %0, %%fs;" - "mov %0, %%gs;" - : : "r" (SEG_r0data << 3) : "memory"); -} - -void gdt_init() { - gdt_prepare(); - gdt_load(); -} |