Added GDT setup code.

This commit is contained in:
neviyn 2017-11-06 21:44:17 +00:00
parent 4d896d0eb7
commit edbc39cc3b
2 changed files with 62 additions and 1 deletions

60
kernel/arch/i386/gdt.nim Normal file
View File

@ -0,0 +1,60 @@
type
GDTEntry{.packed.} = object
limit_low: uint16
base_low: uint16
base_middle: uint8
access: uint8
granularity: uint8
base_high: uint8
GDTPointer{.packed.} = ptr object
limit: uint16 # Size of GDT
base: uint32 # GDT memory location
GDTEntries = ptr array[0..2, GDTEntry]
var
gdt: GDTEntries
gp: GDTPointer
let gpAddr = cast[uint32](addr(gp))
{.push stackTrace:off.}
proc gdtFlush(){.asmNoStackFrame, inline.} =
asm """
lgdt [`gpAddr`]
mov %ax, 0x10
mov %ds, %ax
mov %es, %ax
mov %fs, %ax
mov %gs, %ax
mov %ss, %ax
"""
{.pop.}
proc gdtSetGate(num: int, base: uint16, limit: uint32, access: uint8, granularity: uint8) =
# 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
# Setup the descriptor limits
gdt[num].limit_low = (limit and 0xFFFF)
gdt[num].granularity = ((limit shr 16) and 0x0F)
# Finally, set up the granularity and access flags
gdt[num].granularity = gdt[num].granularity or (granularity and 0xF0)
gdt[num].access = access
proc gdtInstall*() =
gp.limit = uint16(sizeof(GDTEntry) * 3) - 1;
gp.base = cast[uint32](addr(gdt));
# NULL descriptor
gdtSetGate(0, 0, 0, 0, 0);
# The second entry is our Code Segment
gdtSetGate(1, 0'u16, 0xFFFFFFFF'u32, 0x9A'u8, 0xCF'u8);
# The third entry is our Data Segment
gdtSetGate(2, 0'u16, 0xFFFFFFFF'u32, 0x92'u8, 0xCF'u8);
gdtFlush();

View File

@ -1,6 +1,7 @@
import tty import tty, gdt
proc kernelMain() {.exportc: "kernel_main"}= proc kernelMain() {.exportc: "kernel_main"}=
gdt.gdtInstall()
terminalInitialize() terminalInitialize()
terminalWrite("Hello World!\L") terminalWrite("Hello World!\L")
terminalWrite("MAX_INT:") terminalWrite("MAX_INT:")