diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-07-18 10:49:03 +0000 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-07-18 10:49:03 +0000 |
| commit | a832505d9696ae66248b53602d41637bef4868aa (patch) | |
| tree | 8332caa1a4dd1c78060eb80dfb3b2bb370582105 | |
| parent | b794fc9e4427f63aba624700af2e1df250aa41ef (diff) | |
| download | teachos-a832505d9696ae66248b53602d41637bef4868aa.tar.xz teachos-a832505d9696ae66248b53602d41637bef4868aa.zip | |
kernel: turn into a PIE
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | CMakePresets.json | 2 | ||||
| -rw-r--r-- | arch/x86_64/src/boot/boot.s | 112 |
3 files changed, 87 insertions, 31 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ddb4ed..821640c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,10 @@ target_link_libraries("kernel" PRIVATE "os::kern" ) +target_link_options("kernel" PRIVATE + "-no-pie" +) + target_disassemble("kernel") target_extract_debug_symbols("kernel") target_strip("kernel") diff --git a/CMakePresets.json b/CMakePresets.json index b01208a..8943a4d 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -5,7 +5,7 @@ "name": "default", "binaryDir": "${sourceDir}/build", "generator": "Ninja Multi-Config", - "toolchainFile": "${workspaceFolder}/cmake/Platforms/x86_64.cmake", + "toolchainFile": "cmake/Platforms/x86_64.cmake", "cacheVariables": { "CMAKE_CONFIGURATION_TYPES": "Debug;MinSizeRel", "CMAKE_EXPORT_COMPILE_COMMANDS": "YES" diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s index 728380d..ada6426 100644 --- a/arch/x86_64/src/boot/boot.s +++ b/arch/x86_64/src/boot/boot.s @@ -71,16 +71,7 @@ stack_top: global_descriptor_table: .quad 0 global_descriptor_table_code = . - global_descriptor_table .quad (1<<43) | (1<<44) | (1<<47) | (1<<53) - -/** - * We also need a pointer that we can load into the GDTR. - * - * The pointer consists of a word describing the size of the table minus 1 and - * the pointer to the actual table. - */ -global_descriptor_table_pointer: -.word . - global_descriptor_table - 1 -.quad global_descriptor_table +global_descriptor_table_end: /** * We are going to print some messages in case we panic during boot, so we are @@ -130,7 +121,12 @@ _panic: push %ebp mov %esp, %ebp - push message_prefix_panic + call .Lpanic_get_ip +.Lpanic_get_ip: + pop %eax + lea (message_prefix_panic - .Lpanic_get_ip)(%eax), %eax + + push %eax push $0x4f call _print add $8, %esp @@ -155,10 +151,17 @@ _print: push %ebx push %esi + push %edi + + call .Lprint_get_ip +.Lprint_get_ip: + pop %edi + lea (vga_buffer_pointer - .Lprint_get_ip)(%edi), %edi + mov 8(%ebp), %eax mov 12(%ebp), %ebx mov $0, %ecx - mov (vga_buffer_pointer), %esi + mov (%edi), %esi .Lprint_loop: mov (%ebx, %ecx), %dl @@ -171,9 +174,11 @@ _print: .Lupdate_vga_buffer_address: shl $1, %ecx - add %ecx, (vga_buffer_pointer) + add %ecx, %esi + mov %esi, (%edi) .Lprint_end: + pop %edi pop %esi pop %ebx mov %ebp, %esp @@ -187,7 +192,12 @@ _print: */ .global _start _start: - mov $stack_top, %esp + call .Lstart_get_ip +.Lstart_get_ip: + pop %esi + lea (stack_top - .Lstart_get_ip)(%esi), %ebx + + mov %ebx, %esp mov %esp, %ebp call assert_loaded_by_multiboot2_loader @@ -197,8 +207,19 @@ _start: call enable_paging call enable_sse - lgdt (global_descriptor_table_pointer) - jmp $global_descriptor_table_code, $_transition_to_long_mode + sub $10, %esp + lea (global_descriptor_table - .Lstart_get_ip)(%esi), %eax + movw $(global_descriptor_table_end - global_descriptor_table -1), (%esp) + mov %eax, 2(%esp) + movl $0, 6(%esp) + + lgdt (%esp) + add $10, %esp + + lea (_transition_to_long_mode - .Lstart_get_ip)(%esi), %eax + pushl $global_descriptor_table_code + pushl %eax + lret call halt @@ -217,7 +238,11 @@ assert_cpu_supports_long_mode: jz .Llong_mode_assertion_failed ret .Llong_mode_assertion_failed: - push $mesage_long_mode_not_supported + call .Lassert_cpu_supports_long_mode_fail_get_ip +.Lassert_cpu_supports_long_mode_fail_get_ip: + pop %eax + lea (mesage_long_mode_not_supported - .Lassert_cpu_supports_long_mode_fail_get_ip)(%eax), %eax + push %eax call _panic /** @@ -245,7 +270,11 @@ assert_cpuid_instruction_is_supported: je .Lcpuid_assertion_fail ret .Lcpuid_assertion_fail: - push $message_cpuid_instruction_no_supported + call .Lassert_cpuid_instruction_is_supported_fail_get_ip +.Lassert_cpuid_instruction_is_supported_fail_get_ip: + pop %eax + lea (message_cpuid_instruction_no_supported - .Lassert_cpuid_instruction_is_supported_fail_get_ip)(%eax), %eax + push %eax call _panic /** @@ -259,10 +288,18 @@ assert_loaded_by_multiboot2_loader: cmp $0x36d76289, %eax /* Check if we received the expected magic */ jne .Lmultiboot2_assertion_fail /* Panic otherwise */ - mov %ebx, multiboot_information_pointer /* Store the MBI pointer */ + call .Lassert_loaded_by_multiboot2_loader_get_ip +.Lassert_loaded_by_multiboot2_loader_get_ip: + pop %eax + lea (multiboot_information_pointer - .Lassert_loaded_by_multiboot2_loader_get_ip)(%eax), %eax + mov %ebx, (%eax) /* Store the MBI pointer */ ret .Lmultiboot2_assertion_fail: - push $message_not_loaded_by_multiboot2 + call .Lassert_loaded_by_multiboot2_loader_fail_get_ip +.Lassert_loaded_by_multiboot2_loader_fail_get_ip: + pop %eax + lea (message_not_loaded_by_multiboot2 - .Lassert_loaded_by_multiboot2_loader_fail_get_ip)(%eax), %eax + push %eax call _panic /** @@ -272,7 +309,10 @@ assert_loaded_by_multiboot2_loader: * set up for use. */ enable_paging: - mov $page_map_level_4, %eax + call .Lenable_paging_get_ip +.Lenable_paging_get_ip: + pop %eax +lea (page_map_level_4 - .Lenable_paging_get_ip)(%eax), %eax mov %eax, %cr3 /* Enable Physical Address Extension */ @@ -316,37 +356,46 @@ enable_sse: * page map entries. */ prepare_page_maps: + call .Lprepare_page_maps_get_ip +.Lprepare_page_maps_get_ip: + pop %edi /* Map the P4 table recursively */ - mov $page_map_level_4, %eax + lea (page_map_level_4 - .Lprepare_page_maps_get_ip)(%edi), %eax + mov %eax, %ebx or $0b11, %eax /* Write present + writable flags into eax register */ - mov %eax, (page_map_level_4 + 511 * 8) + mov %eax, (511 * 8)(%ebx) /* Add an entry to the PML4, pointing to the PML3 */ - mov $page_map_level_3, %eax + lea (page_map_level_3 - .Lprepare_page_maps_get_ip)(%edi), %eax + lea (page_map_level_4 - .Lprepare_page_maps_get_ip)(%edi), %ebx or $0x3, %eax - mov %eax, (page_map_level_4 + ((0x0000000000100000 >> 39) & 0x1ff) * 8) + mov %eax, (((0x0000000000100000 >> 39) & 0x1ff) * 8)(%ebx) /* Add an entry to the PML3, pointing to the PML2 */ - mov $page_map_level_2, %eax + lea (page_map_level_2 - .Lprepare_page_maps_get_ip)(%edi), %eax + lea (page_map_level_3 - .Lprepare_page_maps_get_ip)(%edi), %ebx or $0x3, %eax - mov %eax, (page_map_level_3 + ((0x0000000000100000 >> 30) & 0x1ff) * 8) + mov %eax, (((0x0000000000100000 >> 30) & 0x1ff) * 8)(%ebx) xor %ecx, %ecx - mov $_end_linear, %esi + push %esi + lea (_end_linear - .Lprepare_page_maps_get_ip)(%edi), %esi shr $21, %esi add $2, %esi .Lmap_pages: + lea (page_map_level_2 - .Lprepare_page_maps_get_ip)(%edi), %ebx mov $(1 << 21), %eax mul %ecx or $((1 << 0) | (1 << 1) | (1 << 7)), %eax - mov %eax, page_map_level_2(,%ecx,8) + mov %eax, (%ebx,%ecx,8) inc %ecx cmp %esi, %ecx jne .Lmap_pages + pop %esi ret .section .boot_text, "ax", @progbits @@ -360,7 +409,10 @@ _transition_to_long_mode: mov %rax, %fs mov %rax, %gs - movl $0xb8000, (vga_buffer_pointer) + leaq vga_buffer_pointer(%rip), %rax + movl $0xb8000, (%rax) + + xor %rax, %rax call _init |
