Fixed GDT creation and address retrieval.
This commit is contained in:
parent
8b129ea6d8
commit
f279852501
@ -1,25 +1,33 @@
|
|||||||
|
import serial
|
||||||
|
|
||||||
type
|
type
|
||||||
GDTEntry{.packed.} = object
|
GDTEntry{.packed.} = object
|
||||||
limit_low: uint16
|
limit_low: uint16
|
||||||
base_low: uint16
|
base_low: uint16
|
||||||
base_middle: uint8
|
base_middle: uint8
|
||||||
access: uint8
|
access: uint8
|
||||||
granularity: uint8
|
flags_and_limit_mid: uint8
|
||||||
base_high: uint8
|
base_high: uint8
|
||||||
GDTPointer{.packed.} = ptr object
|
GDTPointer{.packed.} = object
|
||||||
limit: uint16 # Size of GDT
|
limit: uint16 # Size of GDT
|
||||||
base: uint32 # GDT memory location
|
base: uint32 # GDT memory location
|
||||||
GDTEntries = ptr array[0..2, GDTEntry]
|
GDTEntries = array[0..2, GDTEntry]
|
||||||
|
AccessByte = uint8
|
||||||
|
Flags = uint8
|
||||||
|
|
||||||
var
|
var
|
||||||
gdt: GDTEntries
|
gdt: GDTEntries
|
||||||
gp: GDTPointer
|
gp: GDTPointer
|
||||||
|
gpAddr: uint32
|
||||||
let gpAddr = cast[uint32](addr(gp))
|
|
||||||
|
|
||||||
{.push stackTrace:off.}
|
{.push stackTrace:off.}
|
||||||
proc gdtFlush(){.asmNoStackFrame, inline.} =
|
proc gdtFlush(){.inline.} =
|
||||||
|
gpAddr = cast[uint32](gp.addr)
|
||||||
|
serial.write("GDPointer Address: ")
|
||||||
|
serial.write(gpAddr)
|
||||||
|
serial.newLine()
|
||||||
asm """
|
asm """
|
||||||
|
cli
|
||||||
lgdt [`gpAddr`]
|
lgdt [`gpAddr`]
|
||||||
mov %ax, 0x10
|
mov %ax, 0x10
|
||||||
mov %ds, %ax
|
mov %ds, %ax
|
||||||
@ -30,7 +38,7 @@ proc gdtFlush(){.asmNoStackFrame, inline.} =
|
|||||||
"""
|
"""
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc gdtSetGate(num: int, base: uint16, limit: uint32, access: uint8, granularity: uint8) =
|
proc gdtSetGate(num: int, base: uint16, limit: uint32, access: AccessByte, flags: Flags) =
|
||||||
# Setup the descriptor base address
|
# Setup the descriptor base address
|
||||||
gdt[num].base_low = (base and 0xFFFF)
|
gdt[num].base_low = (base and 0xFFFF)
|
||||||
gdt[num].base_middle = (base shr 16) and 0xFF
|
gdt[num].base_middle = (base shr 16) and 0xFF
|
||||||
@ -38,23 +46,36 @@ proc gdtSetGate(num: int, base: uint16, limit: uint32, access: uint8, granularit
|
|||||||
|
|
||||||
# Setup the descriptor limits
|
# Setup the descriptor limits
|
||||||
gdt[num].limit_low = (limit and 0xFFFF)
|
gdt[num].limit_low = (limit and 0xFFFF)
|
||||||
gdt[num].granularity = ((limit shr 16) and 0x0F)
|
gdt[num].flags_and_limit_mid = ((limit shr 16) and 0x0F) or flags
|
||||||
|
|
||||||
# Finally, set up the granularity and access flags
|
|
||||||
gdt[num].granularity = gdt[num].granularity or (granularity and 0xF0)
|
|
||||||
gdt[num].access = access
|
gdt[num].access = access
|
||||||
|
|
||||||
proc gdtInstall*() =
|
proc createAccessByte(priv: range[0..3], directionConform: bool, readWrite: bool): AccessByte =
|
||||||
gp.limit = uint16(sizeof(GDTEntry) * 3) - 1;
|
result = 0b10011000'u8 # Present and executable bit
|
||||||
gp.base = cast[uint32](addr(gdt));
|
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*() =
|
||||||
|
gp.limit = uint16(sizeof(GDTEntry) * gdt.len) - 1;
|
||||||
|
gp.base = cast[uint32](gdt.addr)
|
||||||
|
serial.write("GDT Address: ")
|
||||||
|
serial.write(gp.base)
|
||||||
|
serial.newLine()
|
||||||
# NULL descriptor
|
# NULL descriptor
|
||||||
gdtSetGate(0, 0, 0, 0, 0);
|
gdtSetGate(0, 0, 0, 0, 0);
|
||||||
|
|
||||||
# The second entry is our Code Segment
|
# The second entry is our Code Segment
|
||||||
gdtSetGate(1, 0'u16, 0xFFFFFFFF'u32, 0x9A'u8, 0xCF'u8);
|
gdtSetGate(1, 0'u16, 0xFFFFFFFF'u32, createAccessByte(0, false, true), createFlags(true, true));
|
||||||
|
|
||||||
# The third entry is our Data Segment
|
# The third entry is our Data Segment
|
||||||
gdtSetGate(2, 0'u16, 0xFFFFFFFF'u32, 0x92'u8, 0xCF'u8);
|
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