aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/boot
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src/boot')
-rw-r--r--arch/x86_64/src/boot/boot.s80
1 files changed, 39 insertions, 41 deletions
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s
index 7b4e193..8d27ea1 100644
--- a/arch/x86_64/src/boot/boot.s
+++ b/arch/x86_64/src/boot/boot.s
@@ -7,38 +7,38 @@
* Uninitialized data for the bootstrapping process.
*/
.section .boot_bss, "aw", @nobits
+
+/**
+ * Reserve some space for the Multiboot 2 information pointer.
+ */
+.global multiboot_information_pointer
+multiboot_information_pointer: .skip 4
+
+/**
+ * Align page maps to 4 KiB or the assembler code, will cause crashes when attempting to enable paging.
+ */
.align 4096
/**
- * Reserve space for the page maps we are going to used during startup.
+ * Reserve space for the page maps we are going to use during startup.
*
* Note: We are going to use large pages to make the initial mapping code
* simpler.
*
* We need:
* - A single PML 4 (since we will only use 4-level paging)
- * - 2 PML 3s (since we need to map high (-2GiB) and low (1+MiB) memory)
- * - 2 PML 2s (since we need to map high (-2GiB) and low (1+MiB) memory)
+ * - 1 PML 3
+ * - 1 PML 2
*/
.global page_map_level_4
page_map_level_4: .skip 512 * 8
-.global page_map_level_3_low
-page_map_level_3_low: .skip 512 * 8
-.global page_map_level_3_high
-page_map_level_3_high: .skip 512 * 8
-
-.global page_map_level_2_low
-page_map_level_2_low: .skip 512 * 8
-.global page_map_level_2_high
-page_map_level_2_high: .skip 512 * 8
+.global page_map_level_3
+page_map_level_3: .skip 512 * 8
-/**
- * Reserve some space for the Multiboot 2 information pointer.
- */
-.global multiboot_information_pointer
-multiboot_information_pointer: .skip 4
+.global page_map_level_2
+page_map_level_2: .skip 512 * 8
/**
* Stack space for the bootstrapping process.
@@ -86,6 +86,7 @@ global_descriptor_table_pointer:
* We are going to print some messages in case we panic during boot, so we are
* going to store them here as well
*/
+.global message_prefix_panic
message_prefix_panic:
.string "TeachOS Panic: "
message_not_loaded_by_multiboot2:
@@ -113,6 +114,12 @@ vga_buffer_pointer: .long 0xb8000
.align 16
.code32
+.global halt
+halt:
+1:
+ hlt
+ jmp 1b
+
/**
* Print a given panic message and then halt the machine.
*
@@ -133,7 +140,7 @@ _panic:
call _print
add $8, %esp
- hlt
+ call halt
/**
* Print a message via the VGA buffer.
@@ -193,7 +200,7 @@ _start:
lgdt (global_descriptor_table_pointer)
jmp $global_descriptor_table_code,$_transition_to_long_mode
- hlt
+ call halt
/**
* Assert that the CPU supports going into long mode.
@@ -306,31 +313,23 @@ enable_sse:
*
* We map all physical memory we were loaded in plus one additional page. The
* mapping is done in terms of huge pages (2 MiB per page) to save on required
- * page map entries. Note that we also map memory both in the low and high
- * virtual address ranges, giving us two ways of accessing it. We need to do
- * this, because the bootstrapping code lives in low memory, while the rest of
- * the kernel will reside on the high end.
+ * page map entries.
*/
prepare_page_maps:
- /* Add an entry to the PML4, pointing to the low PML3 */
- mov $page_map_level_3_low, %eax
- or $0x3, %eax
- mov %eax, (page_map_level_4 + ((0x0000000000100000 >> 39) & 0x1ff) * 8)
-
- /* Add an entry to the PML4, pointing to the high PML3 */
- mov $page_map_level_3_high, %eax
- or $0x3, %eax
- mov %eax, (page_map_level_4 + ((0xffffffff80100000 >> 39) & 0x1ff) * 8)
+ /* Map the P4 table recursively */
+ mov $page_map_level_4, %eax
+ or $0b11, %eax /* Write present + writable flags into eax register */
+ mov %eax, (page_map_level_4 + 511 * 8)
- /* Add an entry to the low PML3, pointing to the low PML2 */
- mov $page_map_level_2_low, %eax
+ /* Add an entry to the PML4, pointing to the PML3 */
+ mov $page_map_level_3, %eax
or $0x3, %eax
- mov %eax, (page_map_level_3_low + ((0x0000000000100000 >> 30) & 0x1ff) * 8)
+ mov %eax, (page_map_level_4 + ((0x0000000000100000 >> 39) & 0x1ff) * 8)
- /* Add an entry to the high PML3, pointing to the high PML2 */
- mov $page_map_level_2_high, %eax
+ /* Add an entry to the PML3, pointing to the PML2 */
+ mov $page_map_level_2, %eax
or $0x3, %eax
- mov %eax, (page_map_level_3_high + ((0xffffffff80100000 >> 30) & 0x1ff) * 8)
+ mov %eax, (page_map_level_3 + ((0x0000000000100000 >> 30) & 0x1ff) * 8)
xor %ecx, %ecx
@@ -342,8 +341,7 @@ prepare_page_maps:
mov $(1 << 21), %eax
mul %ecx
or $((1 << 0) | (1 << 1) | (1 << 7)), %eax
- mov %eax, page_map_level_2_low(,%ecx,8)
- mov %eax, page_map_level_2_high(,%ecx,8)
+ mov %eax, page_map_level_2(,%ecx,8)
inc %ecx
cmp %esi, %ecx
@@ -367,4 +365,4 @@ _transition_to_long_mode:
call _init
call kernel_main
- hlt
+ call halt