#include #include #include #include struct gdt_item { uint16_t low_limit; uint16_t low_base; uint8_t middle_base; uint8_t access; uint8_t granular; uint8_t high_base; } __attribute__((packed)); //Prevent compiler optimisation by packing struct gdt_ptr { uint16_t limit; unsigned int base; } __attribute__((packed)); struct gdt_item gdt[3]; //3-entry gdt struct gdt_ptr gp; extern void load_gdt(); void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { //Implementation taken from osdever.net gdt[num].low_base = (base & 0xFFFF); gdt[num].middle_base = (base >> 16) & 0xFF; gdt[num].high_base = (base >> 24) & 0xFF; gdt[num].low_limit = (limit & 0xFFFF); gdt[num].granular = ((limit >> 16) & 0x0F); gdt[num].granular = (gran & 0xF0); gdt[num].access = access; } void gdt_install() { gp.limit = (sizeof(struct gdt_item) * 3) - 1; gp.base = (unsigned int)&gdt; gdt_set_gate(0, 0, 0, 0, 0); //NULL item //Code Segment - base 0, 4KiB granularity, 4GiB limit gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); //Data Segment - ditto gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); //Apply changes load_gdt(); }