diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-07-24 10:17:53 +0000 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-07-24 10:17:53 +0000 |
| commit | 2ebf8d525e6a030efc8ca23bcbdf92c2d0cb8985 (patch) | |
| tree | d311baa0e25e56bd1d7789fa3260ac5076fd6187 /arch/x86_64/src/boot/boot32.S | |
| parent | bb685cca3a537f0df4205050a9c52b411dee95c6 (diff) | |
| download | teachos-2ebf8d525e6a030efc8ca23bcbdf92c2d0cb8985.tar.xz teachos-2ebf8d525e6a030efc8ca23bcbdf92c2d0cb8985.zip | |
x86_64: implement high/low split
Diffstat (limited to 'arch/x86_64/src/boot/boot32.S')
| -rw-r--r-- | arch/x86_64/src/boot/boot32.S | 102 |
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 /** |
