diff --git a/kernel/arch/gdt.c b/kernel/arch/gdt.c new file mode 100644 index 0000000..aaf0a43 --- /dev/null +++ b/kernel/arch/gdt.c @@ -0,0 +1,25 @@ +#include +#include +#include + +uint64_t gdt[5]; +struct gdtp_st gdt_p; +#define GDT gdt +#define GDTP gdt_p + + +void gdt_init() +{ + + GDT[0] = 0; + GDT[SEG_KCODE/8] = (uint64_t)(GDT_PRESENT | GDT_CODEDATA | GDT_WRITE | GDT_EXECUTE | GDT_64BIT); + GDT[SEG_KDATA/8] = (GDT_PRESENT | GDT_CODEDATA | GDT_WRITE); + GDT[SEG_UCODE/8] = (GDT_PRESENT | GDT_CODEDATA | GDT_WRITE | GDT_EXECUTE | GDT_64BIT | GDT_RING3); + GDT[SEG_UDATA/8] = (GDT_PRESENT | GDT_CODEDATA | GDT_WRITE | GDT_RING3); + + GDTP.len = 5*8-1; + GDTP.addr = (uint64_t)&GDT[0]; + + load_gdt(&GDTP); + +} diff --git a/kernel/arch/registers.S b/kernel/arch/registers.S index 09e1eec..ca3fa1e 100644 --- a/kernel/arch/registers.S +++ b/kernel/arch/registers.S @@ -1,4 +1,5 @@ .intel_syntax noprefix +#include .global load_idt load_idt: @@ -25,3 +26,18 @@ write_cr3: read_cr4: mov rax, cr4 ret + +.global load_gdt +load_gdt: + lgdt [rdi] + mov ax, SEG_KDATA + mov ss, ax + mov ds, ax + mov es, ax + movabs rax, offset .load_gdt + pushq SEG_KCODE + push rax + retfq # perform long jump to SEG_KCODE:.load_gdt +.load_gdt: + ret + diff --git a/kernel/boot/kmain.c b/kernel/boot/kmain.c index 6195b25..433b438 100644 --- a/kernel/boot/kmain.c +++ b/kernel/boot/kmain.c @@ -2,6 +2,7 @@ #include #include #include +#include int kmain(uint64_t multiboot_magic, void *multiboot_data) { @@ -14,23 +15,8 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data) multiboot_init(multiboot_magic, P2V(multiboot_data)); vmm_init(); pmm_init(); + gdt_init(); - // We still need the GDT to be mapped in - extern void *BootGDT; - vmm_set_page(0, V2P(&BootGDT), V2P(&BootGDT), PAGE_PRESENT); - - void *a = kmalloc(0x400); - void *b = kmalloc(0x200); - void *c = kmalloc(0x100); - kfree(b); - void *d = kmalloc(0x100); - - (void)a; - (void)b; - (void)c; - (void)d; - - heap_print(); debug_info("BOOT COMPLETE\n"); for(;;)asm("hlt"); diff --git a/kernel/include/gdt.h b/kernel/include/gdt.h index 8da116a..8db6099 100644 --- a/kernel/include/gdt.h +++ b/kernel/include/gdt.h @@ -1,12 +1,37 @@ #pragma once +#define SEG_KCODE 0x08 +#define SEG_KDATA 0x10 +#define SEG_UDATA 0x18 +#define SEG_UCODE 0x20 + +#ifdef __ASSEMBLER__ #define GDT_WRITE (1<<41) #define GDT_EXECUTE (1<<43) #define GDT_CODEDATA (1<<44) #define GDT_PRESENT (1<<47) #define GDT_64BIT (1<<53) +#else +#define GDT_WRITE (1LL<<41) +#define GDT_EXECUTE (1LL<<43) +#define GDT_CODEDATA (1LL<<44) +#define GDT_PRESENT (1LL<<47) +#define GDT_64BIT (1LL<<53) +#define GDT_RING3 (3LL<<45) +#define GDT_TSS (9LL<<40) -#ifndef __ASSEMBLER__ #include + extern uint64_t BootGDT; + +struct gdtp_st +{ + uint16_t len; + uint64_t addr; + uint16_t pad1; + uint32_t pad2; +}__attribute__((packed)); + +void load_gdt(struct gdtp_st *); +void gdt_init(); #endif