aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/boot/boot32.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src/boot/boot32.S')
-rw-r--r--arch/x86_64/src/boot/boot32.S102
1 files changed, 66 insertions, 36 deletions
diff --git a/arch/x86_64/src/boot/boot32.S b/arch/x86_64/src/boot/boot32.S
index 7e6c2ae..3039f38 100644
--- a/arch/x86_64/src/boot/boot32.S
+++ b/arch/x86_64/src/boot/boot32.S
@@ -13,9 +13,13 @@ multiboot_information_pointer: .skip 8
.align 4096
-page_map_level_4: .skip 512 * 8
-page_map_level_3: .skip 512 * 8
-page_map_level_2: .skip 512 * 8
+page_maps_start:
+page_map_level_4: .skip 512 * 8
+page_map_level_3_high: .skip 512 * 8
+page_map_level_3_low: .skip 512 * 8
+page_map_level_2: .skip 512 * 8
+page_maps_end = .
+page_maps_size = page_maps_end - page_maps_start
/**
* @brief Storage for the bootstrap stack.
@@ -40,9 +44,9 @@ global_descriptor_table:
global_descriptor_table_null = . - global_descriptor_table
.quad 0
global_descriptor_table_code = . - global_descriptor_table
-.quad GDT_ACCESSED | GDT_READ_WRITE | GDT_EXECUTABLE | GDT_DESCRIPTOR_TYPE | GDT_PRESENT | GDT_LONG_MODE
+.quad GDT_READ_WRITE | GDT_EXECUTABLE | GDT_DESCRIPTOR_TYPE | GDT_PRESENT | GDT_LONG_MODE | (1 << 55)
global_descriptor_table_data = . - global_descriptor_table
-.quad GDT_ACCESSED | GDT_READ_WRITE | GDT_DESCRIPTOR_TYPE | GDT_PRESENT
+.quad GDT_READ_WRITE | GDT_DESCRIPTOR_TYPE | GDT_PRESENT | (1 << 54) | (1 << 55)
global_descriptor_table_end:
message_prefix_panic: .string "Panic: "
@@ -125,7 +129,10 @@ _start:
call _assert_cpuid_instruction_is_supported
call _assert_cpu_supports_long_mode
+ push $HUGE_PAGES_TO_MAP
call _prepare_page_maps
+ add $4, %esp
+
call _enable_paging
call _enable_sse
call _reload_gdt
@@ -302,51 +309,74 @@ _assert_cpu_supports_long_mode:
/**
* @brief Prepare a recursive page map hierarchy
*
- * 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.
- *
+ * @param ebp+8 The number of huge pages to map
* @return void
*/
_prepare_page_maps:
pie_function_start
- push %ebx
- /* Map the P4 table recursively */
- lea (page_map_level_4 - 0b)(%esi), %eax
- mov %eax, %ebx
- or $0b11, %ebx
- mov %ebx, (511 * 8)(%eax)
-
- /* Add an entry to the PML4, pointing to the PML3 */
- lea (page_map_level_3 - 0b)(%esi), %ebx
- or $0b11, %ebx
- mov %ebx, (((0x0000000000100000 >> 39) & 0x1ff) * 8)(%eax)
-
- /* Add an entry to the PML3, pointing to the PML2 */
- lea (page_map_level_3 - 0b)(%esi), %eax
- lea (page_map_level_2 - 0b)(%esi), %ebx
- or $0b11, %ebx
- mov %ebx, (((0x0000000000100000 >> 30) & 0x1ff) * 8)(%eax)
-
- /* Add entries for huge pages to the PML2 */
push %edi
- lea (page_map_level_2 - 0b)(%esi), %ebx
- mov $HUGE_PAGES_TO_MAP, %edi
- xor %ecx, %ecx
+
+ call _clear_page_map_memory
+
+ lea (page_map_level_4 - 0b)(%esi), %edi
+ mov %edi, %eax
+ or $0b11, %eax
+ mov %eax, (510 * 8)(%edi)
+
+ lea (page_map_level_3_low - 0b)(%esi), %eax
+ or $0b11, %eax
+ mov %eax, (%edi)
+
+ lea (page_map_level_3_high - 0b)(%esi), %eax
+ or $0b11, %eax
+ mov %eax, (511 * 8)(%edi)
+
+ lea (page_map_level_3_low - 0b)(%esi), %edi
+ lea (page_map_level_2 - 0b)(%esi), %eax
+ or $0b11, %eax
+ mov %eax, (%edi)
+
+ lea (page_map_level_3_high - 0b)(%esi), %edi
+ lea (page_map_level_2 - 0b)(%esi), %eax
+ or $0b11, %eax
+ mov %eax, (510 * 8)(%edi)
+
+ lea (page_map_level_2 - 0b)(%esi), %edi
+ mov 8(%ebp), %ecx
1:
+ dec %ecx
mov $(1 << 21), %eax
mul %ecx
or $0b10000011, %eax
- mov %eax, (%ebx, %ecx, 8)
+ mov %eax, (%edi, %ecx, 8)
- inc %ecx
- cmp %edi, %ecx
- jne 1b
+ test %ecx, %ecx
+ jnz 1b
pop %edi
- pop %ebx
+
+ pie_function_end
+
+/**
+ * @brief Clear all page map memory by filling it with 0s.
+ *
+ * @return void
+ */
+_clear_page_map_memory:
+ pie_function_start
+
+ push %edi
+
+ xor %eax, %eax
+ mov $page_maps_size, %ecx
+ shr $2, %ecx
+ lea (page_maps_start - 0b)(%esi), %edi
+ rep stosl
+
+ pop %edi
+
pie_function_end
/**