summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/gdt.c21
-rw-r--r--platform/boot.s10
2 files changed, 22 insertions, 9 deletions
diff --git a/kernel/gdt.c b/kernel/gdt.c
index b76e441..b0d6320 100644
--- a/kernel/gdt.c
+++ b/kernel/gdt.c
@@ -43,7 +43,6 @@ static struct lgdt_arg lgdt_arg; // probably doesn't need to be global
static void gdt_prepare();
static void gdt_load();
-static void gdt_check();
static void gdt_prepare() {
@@ -96,23 +95,27 @@ static void gdt_prepare() {
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");
-}
+ asm("lgdt (%0)"
+ : : "r" (&lgdt_arg) : "memory");
+ asm("ltr %%ax"
+ : : "a" (SEG_TSS << 3 | 3) : "memory");
-static void gdt_check() {
- // note: this only checks the r0data segment,
- // it's far from a comprehensive test
+ // 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();
- gdt_check();
}
diff --git a/platform/boot.s b/platform/boot.s
index c2a06c3..d5bfda5 100644
--- a/platform/boot.s
+++ b/platform/boot.s
@@ -34,4 +34,14 @@ halt_cpu:
1: hlt
jmp 1b
+// temporary, will be moved to another file soon
+.global change_cs
+.type change_cs, @function
+change_cs:
+ /* retf pops off the return address and code segment off the stack.
+ * it turns out that in the i386 cdecl calling convention they're in
+ * the correct place already.
+ */
+ retf
+
.size _start, . - _start