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:
parent
722fd080e0
commit
cea54a8b77
@ -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
|
||||||
|
@ -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")
|
||||||
)
|
#)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -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 = .;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
@ -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
|
||||||
|
@ -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:")
|
||||||
|
Loading…
Reference in New Issue
Block a user