diff options
-rw-r--r-- | kernel/drivers/gdt.c | 34 | ||||
-rw-r--r-- | kernel/inc/gdt.h | 16 | ||||
-rw-r--r-- | libs/libc/inc/def.h | 2 |
3 files changed, 35 insertions, 17 deletions
diff --git a/kernel/drivers/gdt.c b/kernel/drivers/gdt.c index 8209eaf..693f25f 100644 --- a/kernel/drivers/gdt.c +++ b/kernel/drivers/gdt.c @@ -21,6 +21,12 @@ static struct tss_entry tss = { 0 }; PROTECTED static struct gdt_ptr gp = { 0 }; +CONST u8 gdt_offset(u8 gate) +{ + assert(gate && gate < COUNT(gdt)); + return ((u32)&gdt[gate] - (u32)gdt) & 0xff; +} + CLEAR static void gdt_set_gate(u32 num, u32 base, u32 limit, u8 access, u8 gran) { // Set descriptor base address @@ -48,13 +54,14 @@ CLEAR static void tss_write(u32 num, u16 ss0, u32 esp0) tss.ss0 = ss0; tss.esp0 = esp0; - tss.cs = 0x0b; - tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13; + tss.cs = GDT_SUPER_CODE_OFFSET | 3; + tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SUPER_DATA_OFFSET | 3; + tss.iomap_base = U16_MAX; } CLEAR static void tss_flush(void) { - __asm__ volatile("ltr %0" ::"r"((u16)((u32)&gdt[5] - (u32)gdt))); + __asm__ volatile("ltr %0" ::"r"((u16)(GDT_TSS_OFFSET | 3))); } CLEAR static void gdt_flush(void) @@ -73,36 +80,35 @@ CLEAR void gdt_install(u32 esp) { // Set GDT pointer and limit gp.limit = sizeof(gdt) - 1; - gp.base = &gdt; + gp.base = gdt; // NULL descriptor gdt_set_gate(0, 0, 0, 0, 0); // Code segment - gdt_set_gate(1, 0, 0xffffffff, + gdt_set_gate(GDT_ROOT_CODE_GATE, 0, U32_MAX, GDT_PRESENT | GDT_DESCRIPTOR | GDT_EXECUTABLE | GDT_READWRITE, GDT_GRANULARITY | GDT_SIZE); // Data segment - gdt_set_gate(2, 0, 0xffffffff, GDT_PRESENT | GDT_DESCRIPTOR | GDT_READWRITE, + gdt_set_gate(GDT_ROOT_DATA_GATE, 0, U32_MAX, GDT_PRESENT | GDT_DESCRIPTOR | GDT_READWRITE, GDT_GRANULARITY | GDT_SIZE); // User mode code segment - gdt_set_gate(3, 0, 0xffffffff, + gdt_set_gate(GDT_USER_CODE_GATE, 0, U32_MAX, GDT_PRESENT | GDT_RING3 | GDT_DESCRIPTOR | GDT_EXECUTABLE | GDT_READWRITE, GDT_GRANULARITY | GDT_SIZE); // User mode data segment - gdt_set_gate(4, 0, 0xffffffff, GDT_PRESENT | GDT_RING3 | GDT_DESCRIPTOR | GDT_READWRITE, + gdt_set_gate(GDT_USER_DATA_GATE, 0, U32_MAX, + GDT_PRESENT | GDT_RING3 | GDT_DESCRIPTOR | GDT_READWRITE, GDT_GRANULARITY | GDT_SIZE); // Write TSS - tss_write(5, GDT_SUPER_DATA_OFFSET, esp); + tss_write(GDT_TSS_GATE, GDT_SUPER_DATA_OFFSET, esp); // Remove old GDT and install the new changes! gdt_flush(); - tss_flush(); - __asm__ volatile("mov %%ax, %%ds\n" "mov %%ax, %%es\n" "mov %%ax, %%fs\n" @@ -110,6 +116,8 @@ CLEAR void gdt_install(u32 esp) "mov %%ax, %%ss\n" ::"a"(GDT_SUPER_DATA_OFFSET) : "memory"); - __asm__ volatile("ljmpl $" STRINGIFY(GDT_SUPER_CODE_OFFSET) ", $code\n" - "code:\n"); + __asm__ volatile("ljmpl $0x08 , $code\n" + "code:\n"); + + tss_flush(); } diff --git a/kernel/inc/gdt.h b/kernel/inc/gdt.h index 9a9fd01..20261f3 100644 --- a/kernel/inc/gdt.h +++ b/kernel/inc/gdt.h @@ -5,10 +5,17 @@ #include <def.h> -#define GDT_SUPER_CODE_OFFSET 0x08 // Super (kernel) code segment offset in GDT -#define GDT_SUPER_DATA_OFFSET 0x10 // Super (kernel) data segment offset in GDT -#define GDT_USER_CODE_OFFSET 0x1b // User code segment offset in GDT (with ring3 mask) -#define GDT_USER_DATA_OFFSET 0x23 // User data segment offset in GDT (with ring3 mask) +#define GDT_ROOT_CODE_GATE 1 +#define GDT_ROOT_DATA_GATE 2 +#define GDT_USER_CODE_GATE 3 +#define GDT_USER_DATA_GATE 4 +#define GDT_TSS_GATE 5 + +#define GDT_SUPER_CODE_OFFSET (gdt_offset(GDT_ROOT_CODE_GATE)) +#define GDT_SUPER_DATA_OFFSET (gdt_offset(GDT_ROOT_DATA_GATE)) +#define GDT_USER_CODE_OFFSET (gdt_offset(GDT_USER_CODE_GATE) | 3) +#define GDT_USER_DATA_OFFSET (gdt_offset(GDT_USER_DATA_GATE) | 3) +#define GDT_TSS_OFFSET (gdt_offset(GDT_TSS_GATE)) struct gdt_entry { u16 limit_low; @@ -54,6 +61,7 @@ struct tss_entry { u16 iomap_base; } PACKED; +u8 gdt_offset(u8 gate); void gdt_install(u32 esp); void tss_set_stack(u32 ss, u32 esp); diff --git a/libs/libc/inc/def.h b/libs/libc/inc/def.h index cf49c63..6253371 100644 --- a/libs/libc/inc/def.h +++ b/libs/libc/inc/def.h @@ -33,6 +33,8 @@ typedef unsigned long long u64; #define __STRINGIFY(a) #a #define STRINGIFY(a) __STRINGIFY(a) +#define COUNT(a) (sizeof(a) / sizeof 0 [a]) + #define ATTR __attribute__ #define NORETURN ATTR((noreturn)) #define NOINLINE ATTR((noinline)) |