diff options
Diffstat (limited to 'arch/i686/lgdt.c')
-rw-r--r-- | arch/i686/lgdt.c | 31 |
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)); +} |