#include #include #include #define GDT_ENTRIES 5 uint64_t gdt[GDT_ENTRIES]; struct { uint16_t limit; uint32_t base; } __attribute__((packed)) gp; extern void gdt_flush(uint32_t); void gdt_install(bool prnt_gdt) { if (prnt_gdt) { printf("<===== GDT =====>\n"); } create_descriptor(0, 0, 0, 0, prnt_gdt); /* Null */ create_descriptor(1, 0, 0x000FFFFF, GDT_CODE_PL0, prnt_gdt); /* Kernel code */ create_descriptor(2, 0, 0x000FFFFF, GDT_DATA_PL0, prnt_gdt); /* Kernel data */ create_descriptor(3, 0, 0x000FFFFF, GDT_CODE_PL3, prnt_gdt); /* User code */ create_descriptor(4, 0, 0x000FFFFF, GDT_DATA_PL3, prnt_gdt); /* User data */ if (prnt_gdt) { printf("<===== GDT =====>\n"); } gp.limit = sizeof(gdt) - 1; gp.base = (uint32_t)&gdt; gdt_flush((uint32_t)&gp); } void create_descriptor(int index, uint32_t base, uint32_t limit, uint16_t flag, bool prnt_gdt) { uint64_t descriptor; descriptor = limit & 0x000F0000; /* limit bits 19:16 */ descriptor |= (flag << 8) & 0x00F0FF00; /* flags and access */ descriptor |= (base >> 16) & 0x000000FF; /* base bits 23:16 */ descriptor |= base & 0xFF000000; /* base bits 31:24 */ descriptor <<= 32; descriptor |= ((uint64_t)base << 16); /* base bits 15:0 */ descriptor |= (limit & 0x0000FFFF); /* limit bits 15:0 */ gdt[index] = descriptor; if (prnt_gdt) { printf("GDT[%d] = 0x%llX\n", index, descriptor); } }