#include "gdt.h" #include using seg = GDT::SegmentDescriptor; static_assert(sizeof(GDT::Pointer) == 6); constexpr uint32_t null_sz = 0; /* TODO kcode should only contain the .text segment * TODO kdata should contain the other segments * */ constexpr uint32_t kseg_start = 0; constexpr uint32_t kseg_sz = 0xffffffff; __attribute__((section(".constinit"))) static GDT::SegmentDescriptor segments[256]{ seg::make(0, {}), seg::make(kseg_start, {.r_w = true, .exe = true, .segment = true, .present = true}), seg::make(kseg_start, {.r_w = true, .segment = true, .present = true}), }; GDT::GDT() { Pointer gdtr{.limit = sizeof(segments) - 1, .base = reinterpret_cast(segments)}; asm volatile("lgdt %0" : : "p"(gdtr)); // flush the segment registers constexpr auto cs = GDT::descriptor(kcode); constexpr auto ds = GDT::descriptor(kdata); asm volatile( "jmpl %0,$.reload_cs\n\t" // far jump: cs,location ".reload_cs:\n\t" " mov %1, %%ds\n\t" // ds " mov %1, %%es\n\t" " mov %1, %%fs\n\t" " mov %1, %%gs\n\t" " mov %1, %%ss\n\t" ::"i"(cs), "rm"(ds)); printk("GDT installed at ", uhex{gdtr.base}, '\n'); }