GDT now installs correctly.
This commit is contained in:
parent
5cefd5d2b8
commit
8d61080d8d
@ -11,43 +11,41 @@ type
|
||||
GDTPointer{.packed.} = object
|
||||
limit: uint16 # Size of GDT
|
||||
base: uint32 # GDT memory location
|
||||
GDTEntries = array[0..2, GDTEntry]
|
||||
AccessByte = uint8
|
||||
Flags = uint8
|
||||
GDT{.packed.} = object
|
||||
descriptor: GDTPointer
|
||||
entries: array[0..2, GDTEntry]
|
||||
|
||||
var
|
||||
gdt: GDTEntries
|
||||
gp: GDTPointer
|
||||
gpAddr: uint32
|
||||
const
|
||||
gdtAddress: uint32 = 0x00000800
|
||||
gdt = cast[ptr GDT](gdtAddress)
|
||||
|
||||
{.push stackTrace:off.}
|
||||
proc gdtFlush(){.inline.} =
|
||||
gpAddr = cast[uint32](gp.addr)
|
||||
serial.write("GDPointer Address: ")
|
||||
serial.write(gpAddr)
|
||||
serial.newLine()
|
||||
proc gdtFlush(){.inline,asmNoStackFrame.} =
|
||||
asm """
|
||||
cli
|
||||
lgdt [`gpAddr`]
|
||||
mov %ax, 0x10
|
||||
mov %ds, %ax
|
||||
mov %es, %ax
|
||||
mov %fs, %ax
|
||||
mov %gs, %ax
|
||||
mov %ss, %ax
|
||||
lgdtl [`0x00000800`]
|
||||
movw $0x10, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
ljmp $0x08, $next
|
||||
next:
|
||||
"""
|
||||
{.pop.}
|
||||
|
||||
proc gdtSetGate(num: int, base: uint16, limit: uint32, access: AccessByte, flags: Flags) =
|
||||
# Setup the descriptor base address
|
||||
gdt[num].base_low = (base and 0xFFFF)
|
||||
gdt[num].base_middle = (base shr 16) and 0xFF
|
||||
gdt[num].base_high = (base shr 24) and 0xFF
|
||||
gdt.entries[num].base_low = (base and 0xFFFF)
|
||||
gdt.entries[num].base_middle = (base shr 16) and 0xFF
|
||||
gdt.entries[num].base_high = (base shr 24) and 0xFF
|
||||
|
||||
# Setup the descriptor limits
|
||||
gdt[num].limit_low = (limit and 0xFFFF)
|
||||
gdt[num].flags_and_limit_mid = ((limit shr 16) and 0x0F) or flags
|
||||
gdt[num].access = access
|
||||
gdt.entries[num].limit_low = (limit and 0xFFFF)
|
||||
gdt.entries[num].flags_and_limit_mid = ((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
|
||||
@ -64,11 +62,8 @@ proc createFlags(granularity: bool, size: bool): Flags =
|
||||
result = result or 0b01000000'u8
|
||||
|
||||
proc gdtInstall*() =
|
||||
gp.limit = uint16(sizeof(GDTEntry) * gdt.len) - 1;
|
||||
gp.base = cast[uint32](gdt.addr)
|
||||
serial.write("GDT Address: ")
|
||||
serial.write(gp.base)
|
||||
serial.newLine()
|
||||
gdt.descriptor.limit = uint16(sizeof(GDTEntry) * gdt.entries.len) - 1;
|
||||
gdt.descriptor.base = cast[uint32](gdt.entries.addr)
|
||||
# NULL descriptor
|
||||
gdtSetGate(0, 0, 0, 0, 0);
|
||||
|
||||
@ -78,4 +73,4 @@ proc gdtInstall*() =
|
||||
# The third entry is our Data Segment
|
||||
gdtSetGate(2, 0'u16, 0xFFFFFFFF'u32, createAccessByte(0, false, true), createFlags(true, true));
|
||||
serial.write("Flushing GDT.\L")
|
||||
gdtFlush();
|
||||
gdtFlush()
|
||||
|
Loading…
Reference in New Issue
Block a user