Paging now works. Is initially bootstrapped by GRUB then later OS accessible.

Some memory maybe wasted on bootstrap page table?
This commit is contained in:
neviyn 2018-05-11 22:41:52 +01:00
parent 722fd080e0
commit cea54a8b77
6 changed files with 77 additions and 25 deletions

View File

@ -10,16 +10,53 @@
.long FLAGS .long FLAGS
.long CHECKSUM .long CHECKSUM
.section .bss .section .bootstrap_stack, "aw", @nobits
.align 16 .align 16
stack_bottom: stack_bottom:
.skip 16384 # 16 KiB .skip 16384 # 16 KiB
stack_top: stack_top:
.section .bss, "aw", @nobits
.align 4096
boot_pagedir:
.skip 4096
boot_pagetab1:
.skip 4096
.section .text .section .text
.global _start .global _start
.type _start, @function .type _start, @function
_start: _start:
mov $(boot_pagetab1 - 0xC0000000), %edi
mov $0, %esi
mov $1023, %ecx
1:
cmp $(_kernel_start - 0xC0000000), %esi
jl 2f
cmp $(_kernel_end - 0xC0000000), %esi
jge 3f
mov %esi, %edx
or $0x003, %edx
mov %edx, (%edi)
2:
add $4096, %esi
add $4, %edi
loop 1b
3:
movl $(boot_pagetab1 - 0xC0000000 + 0x003), boot_pagedir - 0xC0000000 + 0
movl $(boot_pagetab1 - 0xC0000000 + 0x003), boot_pagedir - 0xC0000000 + 768 * 4
movl $(boot_pagedir - 0xC0000000), %ecx
mov %ecx, %cr3
mov %cr0, %ecx
or $0x80010000, %ecx
mov %ecx, %cr0
lea 4f, %ecx
jmp *%ecx
4:
movl $0, boot_pagedir + 0
mov %cr3, %ecx
mov %ecx, %cr3
mov $stack_top, %esp mov $stack_top, %esp
call kernel_main call kernel_main
cli cli

View File

@ -84,11 +84,11 @@ macro generateISR(code: static[int], isError: static[bool]): typed =
newIdentNode("writeLine") newIdentNode("writeLine")
), ),
newLit(code) newLit(code)
), )#,
nnkAsmStmt.newTree( #nnkAsmStmt.newTree(
newEmptyNode(), # newEmptyNode(),
newLit((if isError: "" else: "push 0\x0A") & "push " & $code & "\x0A") # newLit((if isError: "" else: "push 0\x0A") & "push " & $code & "\x0A")
) #)
) )
) )
) )

View File

@ -4,28 +4,29 @@ OUTPUT_FORMAT(elf32-i386)
SECTIONS SECTIONS
{ {
. = 0x00100000; . = 0xC0100000;
_kernel_start = .;
.text BLOCK(4K) : ALIGN(4K) .text ALIGN(4K) : AT(ADDR(.text) - 0xC0000000)
{ {
*(.multiboot) *(.multiboot)
*(.text) *(.text)
} }
.rodata BLOCK(4K) : ALIGN(4K) .rodata ALIGN(4K) : AT(ADDR(.rodata) - 0xC0000000)
{ {
*(.rodata) *(.rodata)
} }
.data BLOCK(4K) : ALIGN(4K) .data ALIGN(4K) : AT(ADDR(.data) - 0xC0000000)
{ {
*(.data) *(.data)
} }
.bss BLOCK(4K) : ALIGN(4K) .bss ALIGN(4K) : AT(ADDR(.bss) - 0xC0000000)
{ {
*(COMMON) *(COMMON)
*(.bss) *(.bss)
*(.bootstrap_stack)
} }
_kernel_end = .;
} }

View File

@ -10,7 +10,7 @@ const
blankPageDirectory: PageDirectoryEntry = 0x00000002 blankPageDirectory: PageDirectoryEntry = 0x00000002
var var
pageDirectory{.exportc, codegenDecl: "$# $# __attribute__((aligned(0x1000)))".}: PageDirectory pageDirectory: ptr PageDirectory
pageTable0{.exportc, codegenDecl: "$# $# __attribute__((aligned(0x1000)))".}: 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 =
@ -31,19 +31,32 @@ proc loadPageDirectory(address: uint32){.inline.} =
serial.writeLine("Loading paging data") serial.writeLine("Loading paging data")
asm """ asm """
mov %%cr3, %%eax mov %%cr3, %%eax
mov %%eax, %%cr0
or $0x80000001, %%eax
mov %%cr0, %%eax
::"a"(`address`) ::"a"(`address`)
""" """
# Converts a physical to a virtual address for the kernel
proc toVirtual(address: uint32): uint32 =
result = address + 0xC0000000'u32
# Converts a physical to a virtual address for the kernel
proc toPhysical(address: uint32): uint32 =
result = address - 0xC0000000'u32
# Each page starts from a multiple of 0x400000 769
proc init*() = proc init*() =
serial.writeLine("Initialising paging tables and directories.") serial.writeLine("Initialising paging tables and directories.")
for i in 0..1023: var pagingAddress: uint32 = 0
pageDirectory[i] = blankPageDirectory # Find the bootstrapped page directory
asm """
mov %%cr3, %%eax
:"=a"(`pagingAddress`)
"""
pageDirectory = cast[ptr PageDirectory](toVirtual(pagingAddress))
for i in 0..767:
pageDirectory[][i] = blankPageDirectory
for i in 0..1023: for i in 0..1023:
pageTable0[i] = createEntry(address = uint32(i) * 0x1000, readWrite = true, present = true) pageTable0[i] = createEntry(address = uint32(i) * 0x1000, readWrite = true, present = true)
pageDirectory[0] = createDirectory(address = cast[uint32](pageTable0), readWrite = true, present = true) pageDirectory[][768] = createDirectory(address = toPhysical(cast[uint32](pageTable0.addr)), readWrite = true, present = true)
loadPageDirectory(cast[uint32](pageDirectory.addr)) for i in 769..1023:
serial.write("Paging setup complete at ") pageDirectory[][i] = blankPageDirectory
serial.writeLine(cast[uint32](pageDirectory.addr)) loadPageDirectory(pagingAddress)

View File

@ -8,7 +8,7 @@ type
VGAMemory = ptr array[0..(vgaWidth * vgaHeight - 1), VGADoubleByte] VGAMemory = ptr array[0..(vgaWidth * vgaHeight - 1), VGADoubleByte]
const const
terminalBufferBaseAddress = 0xB8000 terminalBufferBaseAddress = 0xC00B8000
vgaMem = cast[VGAMemory](terminalBufferBaseAddress) vgaMem = cast[VGAMemory](terminalBufferBaseAddress)
var var

View File

@ -25,16 +25,17 @@ proc getMemoryMap(mbd: multiboot_info) =
#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"}= proc kernelMain() {.exportc: "kernel_main"}=
paging.init()
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()
serial.writeLine("IDT installed") serial.writeLine("IDT installed")
tty.init() tty.init()
serial.writeLine("TTY initialised")
tty.writeLine("Version:" & version) tty.writeLine("Version:" & version)
tty.writeLine("Hello World!") tty.writeLine("Hello World!")
tty.write("MAX_INT:") tty.write("MAX_INT:")