alcedo/kernel/arch/i386/paging.nim

39 lines
1.3 KiB
Nim
Raw Normal View History

2018-05-02 23:03:01 +01:00
import serial
type
PageDirectoryEntry = uint32
PageTableEntry = uint32
PageDirectory = array[1024, PageDirectoryEntry]
PageTable = array[1024, PageTableEntry]
const
blankPageDirectory: PageDirectoryEntry = 0x00000002
var
pageDirectory: PageDirectory
pageTable: PageTable
proc createEntry(address: uint32, present: bool = false, readWrite: bool = false, userAccessible: bool = false, writeThrough: bool = false, disableCache: bool = false): uint32 =
result = address and 0xFFFFF000'u32 # Set attributes section to zero
if present: result = result or 0b1
if readWrite: result = result or 0b10
if userAccessible: result = result or 0b100
if writeThrough: result = result or 0b1000
if disableCache: result = result or 0b10000
proc loadPageDirectory(address: uint32){.asmNoStackFrame.} =
asm """
mov `address`, %cr3
mov %cr0, %eax
or $0x80000001, %eax
mov %eax, %cr0
"""
proc init*() =
serial.writeLine("Initialising paging tables and directories.")
for i in 0..1023:
pageDirectory[i] = blankPageDirectory
for i in 0..1023:
pageTable[i] = createEntry(address = uint32(i) * 0x1000, readWrite = true, present = true)
pageDirectory[0] = createEntry(address = cast[uint32](pageTable), readWrite = true, present = true)
loadPageDirectory(cast[uint32](pageDirectory.addr))