diff --git a/kernel/arch/i386/paging.nim b/kernel/arch/i386/paging.nim new file mode 100644 index 0000000..d2e5e7b --- /dev/null +++ b/kernel/arch/i386/paging.nim @@ -0,0 +1,39 @@ +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)) \ No newline at end of file