import serial type GDTEntry{.packed.} = object limit_low: uint16 base_low: uint16 base_middle: uint8 access: uint8 flags_and_limit_mid: uint8 base_high: uint8 GDTPointer{.packed.} = object limit: uint16 # Size of GDT base: uint32 # GDT memory location AccessByte = uint8 Flags = uint8 GDT{.packed.} = object descriptor: GDTPointer entries: array[0..2, GDTEntry] const gdtAddress: uint32 = 0x800 gdt = cast[ptr GDT](gdtAddress) proc gdtFlush(){.inline,asmNoStackFrame.} = asm """ lgdt (0x800) ret """ proc gdtSetGate(num: int, base: uint16, limit: uint32, access: AccessByte, flags: Flags) = # Setup the descriptor base address gdt.entries[num].base_low = uint16(base and 0xFFFF) gdt.entries[num].base_middle = uint8((base shr 16) and 0xFF) gdt.entries[num].base_high = uint8((base shr 24) and 0xFF) # Setup the descriptor limits gdt.entries[num].limit_low = uint16(limit and 0xFFFF) gdt.entries[num].flags_and_limit_mid = uint8(((limit shr 16) and 0x0F) or flags) gdt.entries[num].access = access proc createAccessByte(priv: range[0..3], directionConform: bool, readWrite: bool): AccessByte = result = 0b10011000'u8 # Present and executable bit result = result or (uint8(priv) shl 5) if directionConform: result = result or 0b00000100'u8 if readWrite: result = result or 0b00000010'u8 proc createFlags(granularity: bool, size: bool): Flags = if granularity: result = result or 0b10000000'u8 if size: result = result or 0b01000000'u8 proc gdtInstall*() = gdt.descriptor.limit = uint16(sizeof(gdt.entries)) - 1 gdt.descriptor.base = cast[uint32](gdt.entries.addr) # NULL descriptor gdtSetGate(0, 0, 0, 0, 0); # The second entry is our Code Segment gdtSetGate(1, 0'u16, 0xFFFFFFFF'u32, 0x9A, createFlags(true, true)); # The third entry is our Data Segment gdtSetGate(2, 0'u16, 0xFFFFFFFF'u32, 0x92, createFlags(true, true)); #gdtSetGate(3, 0'u16, 0xFFFFFFFF'u32, 0xFA, createFlags(true, true)); #gdtSetGate(4, 0'u16, 0xFFFFFFFF'u32, 0xF2, createFlags(true, true)); serial.write("GDT Address:") serial.writeLine(gdt.descriptor.base) serial.writeLine("Flushing GDT.") gdtFlush()