aboutsummaryrefslogtreecommitdiff
path: root/src/as
diff options
context:
space:
mode:
Diffstat (limited to 'src/as')
-rw-r--r--src/as/boot.s119
-rw-r--r--src/as/paging.s20
2 files changed, 117 insertions, 22 deletions
diff --git a/src/as/boot.s b/src/as/boot.s
index f65cc72..adb24b7 100644
--- a/src/as/boot.s
+++ b/src/as/boot.s
@@ -1,42 +1,125 @@
-.set ALIGN, 1<<0
-.set MEMINFO, 1<<1
-.set FLAGS, ALIGN | MEMINFO
-.set MAGIC, 0x1BADB002
-.set CHECKSUM, -(MAGIC + FLAGS)
+# Declare constants for the multiboot header.
+.set ALIGN, 1<<0 # align loaded modules on page boundaries
+.set MEMINFO, 1<<1 # provide memory map
+.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
+.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
+.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
-.section .multiboot
+# Declare a multiboot header that marks the program as a kernel.
+.section .multiboot.data, "aw"
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
-.set CODE_SEGMENT, 0x08
-.set DATA_SEGMENT, 0x10
-
-.section .bss
-.align 16
+# Allocate the initial stack.
+.section .bootstrap_stack, "aw", @nobits
stack_bottom:
-.skip 16384
+.skip 16384 # 16 KiB
stack_top:
-.section .text
+# Preallocate pages used for paging. Don't hard-code addresses and assume they
+# are available, as the bootloader might have loaded its multiboot structures or
+# modules there. This lets the bootloader know it must avoid the addresses.
+.section .bss, "aw", @nobits
+ .align 4096
+boot_page_directory:
+ .skip 4096
+boot_page_table1:
+ .skip 4096
+boot_page_table2:
+ .skip 4096
+# Further page tables may be required if the kernel grows beyond 3 MiB.
+
+# The kernel entry point.
+.section .multiboot.text, "a"
.global _start
.type _start, @function
_start:
+ movl $(boot_page_table1 - 0xC0000000), %edi
+ movl $0, %esi
+
+1:
+ jl 2f
+ cmpl $0x00400000, %esi
+ jge 3f
+
+ movl %esi, %edx
+ orl $0x003, %edx
+ movl %edx, (%edi)
+
+2:
+ # Size of page is 4096 bytes.
+ addl $4096, %esi
+ # Size of entries in boot_page_table1 is 4 bytes.
+ addl $4, %edi
+ # Loop to the next entry if we haven't finished.
+ loop 1b
+
+3:
+ movl $(boot_page_table2 - 0xC0000000), %edi
+
+4:
+ jl 5f
+ cmpl $0x00800000, %esi
+ jge 6f
+
+ movl %esi, %edx
+ orl $0x003, %edx
+ movl %edx, (%edi)
+
+5:
+ # Size of page is 4096 bytes.
+ addl $4096, %esi
+ # Size of entries in boot_page_table1 is 4 bytes.
+ addl $4, %edi
+ # Loop to the next entry if we haven't finished.
+ loop 4b
+
+6:
+ movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0 * 4
+ movl $(boot_page_table2 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 1 * 4
+ movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
+ movl $(boot_page_table2 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 769 * 4
+
+ # Set cr3 to the address of the boot_page_directory.
+ movl $(boot_page_directory - 0xC0000000), %ecx
+ movl %ecx, %cr3
+
+ # Enable paging and the write-protect bit.
+ movl %cr0, %ecx
+ orl $0x80010000, %ecx
+ movl %ecx, %cr0
+
+ # Jump to higher half with an absolute jump.
+ lea 7f, %ecx
+ jmp *%ecx
+
+.section .text
+
+7:
+ # At this point, paging is fully set up and enabled.
+
+ # Unmap the identity mapping as it is now unnecessary.
+ movl $0, boot_page_directory + 0
+ movl $0, boot_page_directory + 4
+
+ # Reload crc3 to force a TLB flush so the changes to take effect.
+ movl %cr3, %ecx
+ movl %ecx, %cr3
+
+ movl $stack_top, %esp
call init_gdt_table
- ljmp $CODE_SEGMENT, $code
+ ljmp $0x08, $code
code:
- movw $DATA_SEGMENT, %ax
+ movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
- movl $stack_top, %esp
cli
call _init
call kernel_main
hlt
-
-.size _start, . - _start
diff --git a/src/as/paging.s b/src/as/paging.s
index e1cf42a..c3a9a0d 100644
--- a/src/as/paging.s
+++ b/src/as/paging.s
@@ -1,14 +1,16 @@
+.text
+
.global loadPageDirectory
loadPageDirectory:
push %ebp
- mov %esp, %ebp
- mov 8(%esp), %eax
- mov %eax, %cr3
+ movl %esp, %ebp
+ movl 8(%esp), %eax
+ subl $0xC0000000, %eax
+ movl %eax, %cr3
mov %ebp, %esp
pop %ebp
ret
-.text
.global enablePaging
enablePaging:
push %ebp
@@ -19,3 +21,13 @@ enablePaging:
mov %ebp, %esp
pop %ebp
ret
+
+.global flushPaging
+flushPaging:
+ push %ebp
+ mov %esp, %ebp
+ movl %cr3, %ecx
+ movl %ecx, %cr3
+ mov %ebp, %esp
+ pop %ebp
+ ret