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))