summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/gdt.c10
-rw-r--r--kernel/gdt.h49
2 files changed, 58 insertions, 1 deletions
diff --git a/kernel/gdt.c b/kernel/gdt.c
index 7d23289..92d3d4c 100644
--- a/kernel/gdt.c
+++ b/kernel/gdt.c
@@ -1,11 +1,14 @@
#include "gdt.h"
+tss_entry tss = tss_entry_init(0xfffff800, 0x10, 0x0b, 0x13);
+
gdt_entry gdt[] = {
gdt_entry_init(0, 0, 0),
gdt_entry_init(0, 0xfffff, 0xc09a), // Code segment.
gdt_entry_init(0, 0xfffff, 0xc092), // Data segment.
gdt_entry_init(0, 0xfffff, 0xc0fa), // User mode code segment.
gdt_entry_init(0, 0xfffff, 0xc0f2), // User mode data segment.
+ gdt_entry_init(0, sizeof(tss_entry), 0x00e9), // TSS.
};
gdt_ptr gdtr = {
@@ -14,6 +17,10 @@ gdt_ptr gdtr = {
};
void gdt_init() {
+ gdt[5].base_low = (uint32_t)&tss & 0xffff;
+ gdt[5].base_mid = (uint32_t)&tss >> 16 & 0xff;
+ gdt[5].base_high = (uint32_t)&tss >> 24 & 0xff;
+
asm volatile(
"lgdt (%0)\n"
"mov %w1, %%ds\n"
@@ -23,6 +30,7 @@ void gdt_init() {
"mov %w1, %%ss\n"
"ljmp $0x08, $.flush\n"
".flush:\n"
- : : "r" (&gdtr), "r" (0x10)
+ "ltr %w2\n"
+ : : "r" (&gdtr), "r" (0x10), "r" (0x28)
);
}
diff --git a/kernel/gdt.h b/kernel/gdt.h
index e2c5b46..36c37dd 100644
--- a/kernel/gdt.h
+++ b/kernel/gdt.h
@@ -4,6 +4,45 @@
#include "types.h"
typedef struct {
+ uint32_t link;
+
+ uint32_t esp0;
+ uint32_t ss0;
+
+ uint32_t esp1;
+ uint32_t ss1;
+
+ uint32_t esp2;
+ uint32_t ss2;
+
+ uint32_t cr3;
+
+ uint32_t eip;
+ uint32_t eflags;
+
+ uint32_t eax;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t ebx;
+ uint32_t esp;
+ uint32_t ebp;
+ uint32_t esi;
+ uint32_t edi;
+
+ uint32_t es;
+ uint32_t cs;
+ uint32_t ss;
+ uint32_t ds;
+ uint32_t fs;
+ uint32_t gs;
+
+ uint32_t ldt;
+
+ uint16_t trap;
+ uint16_t iomap;
+} __attribute__((packed)) tss_entry;
+
+typedef struct {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_mid;
@@ -23,6 +62,16 @@ typedef struct {
.limit_low = (l & 0xffff), \
.flags = (f | (l >> 8 & 0x0f00))}
+#define tss_entry_init(e, s, c, d) { \
+ .esp0 = e, \
+ .ss0 = s, \
+ .cs = c, \
+ .ss = d, \
+ .ds = d, \
+ .es = d, \
+ .fs = d, \
+ .gs = d}
+
void gdt_init();
#endif