#include struct gdt_item { unsigned short low_limit; unsigned short low_base; unsigned char middle_base; unsigned char access; unsigned char granular; unsigned char high_base; } __attribute__((packed)); //Prevent compiler optimisation by packing struct gdt_ptr { unsigned short limit; unsigned int base; } __attribute__((packed)); struct gdt_item gdt[3]; //3-entry gdt struct gdt_ptr gp; extern void gdt_flush(); void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char 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 = &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 gdt_flush();