diff options
Diffstat (limited to 'i686/lgdt.c')
-rw-r--r-- | i686/lgdt.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/i686/lgdt.c b/i686/lgdt.c new file mode 100644 index 0000000..10781db --- /dev/null +++ b/i686/lgdt.c @@ -0,0 +1,35 @@ +#include "gdt.h" + +struct __attribute__((packed)) Pointer { + uint16_t limit; + uint32_t base; +}; + +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 + + const 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)); +} |