aboutsummaryrefslogtreecommitdiff
path: root/arch/i686/lgdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i686/lgdt.c')
-rw-r--r--arch/i686/lgdt.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/i686/lgdt.c b/arch/i686/lgdt.c
new file mode 100644
index 0000000..2d35e8d
--- /dev/null
+++ b/arch/i686/lgdt.c
@@ -0,0 +1,31 @@
+#include <gdt.h>
+
+static struct SegmentDescriptor_t segments[8] __attribute__((aligned(32)));
+
+void
+gdt_install()
+{
+ SegmentDescriptor(&segments[0], 0, 0, 0); // null segment
+ SegmentDescriptor(&segments[2], 0, 0xffffffff, 0x9a); // ktext
+ SegmentDescriptor(&segments[3], 0, 0xffffffff, 0x92); // kdata
+
+ struct Pointer ptr = {.limit = sizeof(segments) - 1, .base = (unsigned)&segments};
+
+ asm volatile("lgdt (%0)" : : "a"(&ptr));
+
+ // load the kernel data segment
+ asm volatile(R"(mov %0, %%ds
+ mov %0, %%es
+ mov %0, %%fs
+ mov %0, %%gs
+ mov %0, %%ss
+)"
+ :
+ : "ax"(kdataDescriptor));
+
+ // load the kernel code segment
+ asm volatile(R"(ljmp %0, $1f
+ 1:)"
+ :
+ : "i"(ktextDescriptor));
+}