GDT and IDT now exist in locations that aren't hard coded. Paging currently breaks interrupts.
This commit is contained in:
parent
ada7e292f8
commit
722fd080e0
@ -13,18 +13,20 @@ type
|
|||||||
base: uint32 # GDT memory location
|
base: uint32 # GDT memory location
|
||||||
AccessByte = uint8
|
AccessByte = uint8
|
||||||
Flags = uint8
|
Flags = uint8
|
||||||
|
GDTEntries{.packed.} = array[0..2, GDTEntry]
|
||||||
GDT{.packed.} = object
|
GDT{.packed.} = object
|
||||||
descriptor: GDTPointer
|
descriptor: GDTPointer
|
||||||
entries: array[0..2, GDTEntry]
|
entries: GDTEntries
|
||||||
|
|
||||||
const
|
var
|
||||||
gdtAddress: uint32 = 0x800
|
address: uint32
|
||||||
gdt = cast[ptr GDT](gdtAddress)
|
gdt: GDT
|
||||||
|
|
||||||
proc gdtFlush(){.inline,asmNoStackFrame.} =
|
proc gdtFlush(){.inline,asmNoStackFrame.} =
|
||||||
asm """
|
asm """
|
||||||
lgdt (0x800)
|
lgdt (%%eax)
|
||||||
ret
|
ret
|
||||||
|
::"a"(`address`)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc gdtSetGate(num: int, base: uint16, limit: uint32, access: AccessByte, flags: Flags) =
|
proc gdtSetGate(num: int, base: uint16, limit: uint32, access: AccessByte, flags: Flags) =
|
||||||
@ -68,7 +70,8 @@ proc gdtInstall*() =
|
|||||||
#gdtSetGate(3, 0'u16, 0xFFFFFFFF'u32, 0xFA, createFlags(true, true));
|
#gdtSetGate(3, 0'u16, 0xFFFFFFFF'u32, 0xFA, createFlags(true, true));
|
||||||
|
|
||||||
#gdtSetGate(4, 0'u16, 0xFFFFFFFF'u32, 0xF2, createFlags(true, true));
|
#gdtSetGate(4, 0'u16, 0xFFFFFFFF'u32, 0xF2, createFlags(true, true));
|
||||||
serial.write("GDT Address:")
|
|
||||||
serial.writeLine(gdt.descriptor.base)
|
|
||||||
serial.writeLine("Flushing GDT.")
|
serial.writeLine("Flushing GDT.")
|
||||||
|
address = cast[uint32](gdt.addr)
|
||||||
|
serial.write("GDT Address:")
|
||||||
|
serial.writeLine(address)
|
||||||
gdtFlush()
|
gdtFlush()
|
||||||
|
@ -18,14 +18,15 @@ type
|
|||||||
int_no, err_code: uint32 # Interrupt number and error code (if applicable)
|
int_no, err_code: uint32 # Interrupt number and error code (if applicable)
|
||||||
eip, cs, eflags, useresp, ss: uint32 # Pushed by the processor automatically.
|
eip, cs, eflags, useresp, ss: uint32 # Pushed by the processor automatically.
|
||||||
|
|
||||||
const
|
var
|
||||||
idtAddress: uint32 = 0x00000000
|
address: uint32
|
||||||
idt = cast[ptr IDT](idtAddress)
|
idt: IDT
|
||||||
|
|
||||||
proc idtFlush(){.inline,asmNoStackFrame.} =
|
proc idtFlush(){.inline,asmNoStackFrame.} =
|
||||||
asm """
|
asm """
|
||||||
lidtl (0x0)
|
lidt (%%eax)
|
||||||
ret
|
ret
|
||||||
|
::"a"(`address`)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#[
|
#[
|
||||||
@ -175,4 +176,7 @@ proc idtInstall*() =
|
|||||||
idtSetGate(30, cast[uint32](isr30), selector, flags)
|
idtSetGate(30, cast[uint32](isr30), selector, flags)
|
||||||
idtSetGate(31, cast[uint32](isr31), selector, flags)
|
idtSetGate(31, cast[uint32](isr31), selector, flags)
|
||||||
serial.writeLine("Flushing IDT.")
|
serial.writeLine("Flushing IDT.")
|
||||||
|
address = cast[uint32](idt.addr)
|
||||||
|
serial.write("IDT Address:")
|
||||||
|
serial.writeLine(address)
|
||||||
idtFlush()
|
idtFlush()
|
@ -4,7 +4,7 @@ OUTPUT_FORMAT(elf32-i386)
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 1M;
|
. = 0x00100000;
|
||||||
|
|
||||||
.text BLOCK(4K) : ALIGN(4K)
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
|
@ -10,8 +10,8 @@ const
|
|||||||
blankPageDirectory: PageDirectoryEntry = 0x00000002
|
blankPageDirectory: PageDirectoryEntry = 0x00000002
|
||||||
|
|
||||||
var
|
var
|
||||||
pageDirectory: PageDirectory
|
pageDirectory{.exportc, codegenDecl: "$# $# __attribute__((aligned(0x1000)))".}: PageDirectory
|
||||||
pageTable: PageTable
|
pageTable0{.exportc, codegenDecl: "$# $# __attribute__((aligned(0x1000)))".}: PageTable
|
||||||
|
|
||||||
proc createEntry(address: uint32, present: bool = false, readWrite: bool = false, userAccessible: bool = false, writeThrough: bool = false, disableCache: bool = false): uint32 =
|
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
|
result = address and 0xFFFFF000'u32 # Set attributes section to zero
|
||||||
@ -21,12 +21,20 @@ proc createEntry(address: uint32, present: bool = false, readWrite: bool = false
|
|||||||
if writeThrough: result = result or 0b1000
|
if writeThrough: result = result or 0b1000
|
||||||
if disableCache: result = result or 0b10000
|
if disableCache: result = result or 0b10000
|
||||||
|
|
||||||
proc loadPageDirectory(address: uint32){.asmNoStackFrame.} =
|
proc createDirectory(address: uint32, present: bool = false, readWrite: bool = false, userAccessible: bool = false, writeThrough: bool = false, disableCache: bool = false, pageSize: bool = false): uint32 =
|
||||||
|
var checkAddress = address
|
||||||
|
if pageSize: checkAddress = checkAddress and 0xFFFF0000'u32
|
||||||
|
result = createEntry(address, present, readWrite, userAccessible, writeThrough, disableCache)
|
||||||
|
if pageSize: result = result or 0b10000000
|
||||||
|
|
||||||
|
proc loadPageDirectory(address: uint32){.inline.} =
|
||||||
|
serial.writeLine("Loading paging data")
|
||||||
asm """
|
asm """
|
||||||
mov `address`, %cr3
|
mov %%cr3, %%eax
|
||||||
mov %cr0, %eax
|
mov %%eax, %%cr0
|
||||||
or $0x80000001, %eax
|
or $0x80000001, %%eax
|
||||||
mov %eax, %cr0
|
mov %%cr0, %%eax
|
||||||
|
::"a"(`address`)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc init*() =
|
proc init*() =
|
||||||
@ -34,6 +42,8 @@ proc init*() =
|
|||||||
for i in 0..1023:
|
for i in 0..1023:
|
||||||
pageDirectory[i] = blankPageDirectory
|
pageDirectory[i] = blankPageDirectory
|
||||||
for i in 0..1023:
|
for i in 0..1023:
|
||||||
pageTable[i] = createEntry(address = uint32(i) * 0x1000, readWrite = true, present = true)
|
pageTable0[i] = createEntry(address = uint32(i) * 0x1000, readWrite = true, present = true)
|
||||||
pageDirectory[0] = createEntry(address = cast[uint32](pageTable), readWrite = true, present = true)
|
pageDirectory[0] = createDirectory(address = cast[uint32](pageTable0), readWrite = true, present = true)
|
||||||
loadPageDirectory(cast[uint32](pageDirectory.addr))
|
loadPageDirectory(cast[uint32](pageDirectory.addr))
|
||||||
|
serial.write("Paging setup complete at ")
|
||||||
|
serial.writeLine(cast[uint32](pageDirectory.addr))
|
@ -2,7 +2,7 @@
|
|||||||
{.passL: "-ffreestanding -target i386 -nostdlib -T arch/i386/linker.ld".}
|
{.passL: "-ffreestanding -target i386 -nostdlib -T arch/i386/linker.ld".}
|
||||||
{.passC: "-ffreestanding -nostdlib --target=i386-pc-none-elf -march=i386".}
|
{.passC: "-ffreestanding -nostdlib --target=i386-pc-none-elf -march=i386".}
|
||||||
|
|
||||||
import tty, gdt, interrupts, serial, multiboot
|
import tty, gdt, interrupts, serial, multiboot, paging
|
||||||
|
|
||||||
const version {.strdefine.} = "UNKNOWN"
|
const version {.strdefine.} = "UNKNOWN"
|
||||||
|
|
||||||
@ -23,11 +23,13 @@ proc memset*(dest: ByteAddress, value: char, count: int){.exportc.} =
|
|||||||
proc getMemoryMap(mbd: multiboot_info) =
|
proc getMemoryMap(mbd: multiboot_info) =
|
||||||
discard # Use this if we need to do anything with the GRUB memory map
|
discard # Use this if we need to do anything with the GRUB memory map
|
||||||
|
|
||||||
proc kernelMain(mbd: multiboot_info, magic: uint) {.exportc: "kernel_main"}=
|
#proc kernelMain(mbd: multiboot_info, magic: uint) {.exportc: "kernel_main"}=
|
||||||
|
proc kernelMain() {.exportc: "kernel_main"}=
|
||||||
serial.init()
|
serial.init()
|
||||||
serial.writeLine("Version:" & (version))
|
serial.writeLine("Version:" & (version))
|
||||||
serial.writeLine("Booting OS")
|
serial.writeLine("Booting OS")
|
||||||
getMemoryMap(mbd)
|
#getMemoryMap(mbd)
|
||||||
|
#paging.init()
|
||||||
gdt.gdtInstall()
|
gdt.gdtInstall()
|
||||||
serial.writeLine("GDT installed")
|
serial.writeLine("GDT installed")
|
||||||
interrupts.idtInstall()
|
interrupts.idtInstall()
|
||||||
@ -37,7 +39,7 @@ proc kernelMain(mbd: multiboot_info, magic: uint) {.exportc: "kernel_main"}=
|
|||||||
tty.writeLine("Hello World!")
|
tty.writeLine("Hello World!")
|
||||||
tty.write("MAX_INT:")
|
tty.write("MAX_INT:")
|
||||||
tty.writeLine(high(int))
|
tty.writeLine(high(int))
|
||||||
tty.write("LMIN_INT:")
|
tty.write("MIN_INT:")
|
||||||
tty.writeLine((low(int)+1))
|
tty.writeLine((low(int)+1))
|
||||||
tty.write("MAX_UINT:")
|
tty.write("MAX_UINT:")
|
||||||
tty.writeLine(high(uint32))
|
tty.writeLine(high(uint32))
|
||||||
|
Loading…
Reference in New Issue
Block a user