#include "src/kernel/gdt.h" #include "src/kernel/tss.h" typedef struct { uint16_t limit_low; uint16_t base_low; uint8_t base_mid; uint8_t access; uint8_t flags_limit_high; uint8_t base_high; } __attribute__((packed)) gdt_entry_t; typedef struct { gdt_entry_t base; uint32_t base_upper; uint32_t reserved; } __attribute__((packed)) gdt_system_entry_t; typedef struct { gdt_entry_t gdt[6]; gdt_system_entry_t tss_entry; } __attribute__((packed)) gdt_table_t; typedef struct { uint16_t limit; uint64_t offset; } __attribute__((packed)) gdt_descriptor_t; static gdt_table_t gdt; static gdt_descriptor_t desc; static void set_entry(gdt_entry_t *e, uint8_t access, uint8_t flags) { e->limit_low = 0xFFFF; e->base_low = 0; e->base_mid = 0; e->access = access; e->flags_limit_high = flags | 0x0F; e->base_high = 0; } static void set_tss_entry(void *base) { uint64_t ibase = (uint64_t)base; gdt.tss_entry.base.limit_low = sizeof(tss_t) - 1; gdt.tss_entry.base.base_low = ibase & 0xFFFF; gdt.tss_entry.base.base_mid = (ibase >> 16) & 0xFF; gdt.tss_entry.base.access = 0x89; // present, type=TSS available gdt.tss_entry.base.flags_limit_high = 0x00; gdt.tss_entry.base.base_high = (ibase >> 24) & 0xFF; gdt.tss_entry.base_upper = ibase >> 32; gdt.tss_entry.reserved = 0; } void gdt_init() { gdt.gdt[0] = (gdt_entry_t){0}; set_entry(&gdt.gdt[1], 0x9A, 0xCF); // present, ring 0, code, executable, readable, 32-bit, 4KB granularity set_entry(&gdt.gdt[2], 0x9A, 0xA0); // present, ring 0, code, executable, readable, 64-bit set_entry(&gdt.gdt[3], 0x92, 0x00); // present, ring 0, data, writable set_entry(&gdt.gdt[4], 0xF2, 0x00); // present, ring 3, data, writable set_entry(&gdt.gdt[5], 0xFA, 0xA0); // present, ring 3, code, executable, readable, 64-bit set_tss_entry(&tss); desc.limit = sizeof(gdt) - 1; desc.offset = (uint64_t)&gdt; __asm__ volatile("lgdt %0" : : "m"(desc)); __asm__ volatile("ltr %0" : : "r"((uint16_t)TSS_SEL)); }