From 18d5eb1f02825ce80cefc8a9c09e6931a0c2ac9e Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Sat, 7 Dec 2024 23:50:52 +0800 Subject: [PATCH] Use physical addresses in boot segments --- osdk/src/base_crate/x86_64.ld.template | 15 +++-- ostd/src/arch/x86/boot/ap_boot.S | 25 ++++----- ostd/src/arch/x86/boot/bsp_boot.S | 65 +++++++++++----------- ostd/src/arch/x86/boot/multiboot2/header.S | 3 +- 4 files changed, 52 insertions(+), 56 deletions(-) diff --git a/osdk/src/base_crate/x86_64.ld.template b/osdk/src/base_crate/x86_64.ld.template index 300a4dc35..1efcd96fd 100644 --- a/osdk/src/base_crate/x86_64.ld.template +++ b/osdk/src/base_crate/x86_64.ld.template @@ -30,11 +30,11 @@ PHDRS # segment to prevent this from happening. header PT_LOAD FLAGS(4); # R__ - # Boot segments. + # Boot segments. Addresses are physical. bsp_boot PT_LOAD FLAGS(7); # RWE ap_boot PT_LOAD FLAGS(7); # RWE - # Normal segments. + # Normal segments. Addresses are virtual. text PT_LOAD FLAGS(5); # R_E rodata PT_LOAD FLAGS(4); # R__ data PT_LOAD FLAGS(6); # RW_ @@ -57,22 +57,21 @@ SECTIONS } : header # --------------------------------------------------------------------------- # -# These are 2 boot sections that need specific physical addresses. But they # -# should use virtual symbols. # +# These are 2 boot sections that need specific physical addresses. # # --------------------------------------------------------------------------- # - . = BSP_BOOT_LMA + KERNEL_VMA; + . = BSP_BOOT_LMA; .bsp_boot : AT(BSP_BOOT_LMA) { KEEP(*(.bsp_boot .bsp_boot.*)) . = ALIGN(4096); } : bsp_boot - . = AP_EXEC_MA + KERNEL_VMA; + . = AP_EXEC_MA; .ap_boot : AT(BSP_BOOT_LMA + SIZEOF(.bsp_boot)) { - __ap_boot_start = . - AP_EXEC_MA + BSP_BOOT_LMA + SIZEOF(.bsp_boot); + __ap_boot_start = BSP_BOOT_LMA + SIZEOF(.bsp_boot) + KERNEL_VMA; KEEP(*(.ap_boot .ap_boot.*)) - __ap_boot_end = . - AP_EXEC_MA + BSP_BOOT_LMA + SIZEOF(.bsp_boot); + __ap_boot_end = __ap_boot_start + (. - AP_EXEC_MA); . = ALIGN(4096); } : ap_boot diff --git a/ostd/src/arch/x86/boot/ap_boot.S b/ostd/src/arch/x86/boot/ap_boot.S index f41d0f85f..ba8273446 100644 --- a/ostd/src/arch/x86/boot/ap_boot.S +++ b/ostd/src/arch/x86/boot/ap_boot.S @@ -6,8 +6,6 @@ .extern boot_page_table_start .extern ap_early_entry -KERNEL_VMA = 0xffffffff80000000 - .section ".ap_boot", "awx" .align 4096 .code16 @@ -23,13 +21,13 @@ ap_real_mode_boot: xor ax, ax // clear ax mov ds, ax // clear ds - lgdt [ap_gdtr - KERNEL_VMA] // load gdt + lgdt [ap_gdtr] // load gdt mov eax, cr0 or eax, 1 mov cr0, eax // enable protected mode - ljmp 0x8, offset ap_protect_entry - KERNEL_VMA + ljmp 0x8, offset ap_protect_entry // 32-bit AP GDT. .align 16 @@ -44,7 +42,7 @@ ap_gdt_end: .align 16 ap_gdtr: .word ap_gdt_end - ap_gdt - 1 - .quad ap_gdt - KERNEL_VMA + .quad ap_gdt .align 4 .code32 @@ -95,7 +93,7 @@ ap_protect: // Now we try getting into long mode. // Use the 64-bit GDT. - lgdt [boot_gdtr - KERNEL_VMA] + lgdt [boot_gdtr] // Enable PAE and PGE. mov eax, cr4 @@ -105,7 +103,7 @@ ap_protect: // Set the page table. The application processors use // the same page table as the bootstrap processor's // boot phase page table. - lea eax, [boot_page_table_start - KERNEL_VMA] + lea eax, [boot_page_table_start] mov cr3, eax // Enable long mode. @@ -119,10 +117,9 @@ ap_protect: or eax, 1 << 31 mov cr0, eax - ljmp 0x8, offset ap_long_mode_in_low_address - KERNEL_VMA + ljmp 0x8, offset ap_long_mode_in_low_address .code64 - ap_long_mode_in_low_address: mov ax, 0 mov ds, ax @@ -132,18 +129,19 @@ ap_long_mode_in_low_address: mov gs, ax // Update RIP to use the virtual address. - mov rbx, KERNEL_VMA - lea rax, [ap_long_mode - KERNEL_VMA] - or rax, rbx + mov rax, offset ap_long_mode jmp rax // This is a pointer to be filled by the BSP when boot stacks // of all APs are allocated and initialized. +.data .global __ap_boot_stack_array_pointer .align 8 __ap_boot_stack_array_pointer: .skip 8 +.text +.code64 ap_long_mode: // The local APIC ID is in the RDI. mov rax, rdi @@ -158,4 +156,5 @@ ap_long_mode: mov rax, offset ap_early_entry call rax - hlt +.extern halt # bsp_boot.S + jmp halt diff --git a/ostd/src/arch/x86/boot/bsp_boot.S b/ostd/src/arch/x86/boot/bsp_boot.S index 8dab07920..b38cbb650 100644 --- a/ostd/src/arch/x86/boot/bsp_boot.S +++ b/ostd/src/arch/x86/boot/bsp_boot.S @@ -31,7 +31,7 @@ __linux32_boot: cld // Set the kernel call stack. - mov esp, offset boot_stack_top - KERNEL_VMA + mov esp, offset boot_stack_top push 0 // upper 32-bits push esi // boot_params ptr @@ -47,7 +47,7 @@ __linux32_boot: .global __linux64_boot_tag __linux64_boot_tag: // Set the kernel call stack. - lea rsp, [boot_stack_top - KERNEL_VMA] + lea rsp, [boot_stack_top] push rsi // boot_params ptr from the loader push ENTRYTYPE_LINUX_64 @@ -62,7 +62,7 @@ __multiboot_boot: cld // Set the kernel call stack. - mov esp, offset boot_stack_top - KERNEL_VMA + mov esp, offset boot_stack_top push 0 // Upper 32-bits. push eax // multiboot magic ptr @@ -87,11 +87,11 @@ initial_boot_setup: // Prepare for far return. We use a far return as a fence after setting GDT. mov eax, 24 push eax - lea edx, [protected_mode - KERNEL_VMA] + lea edx, [protected_mode] push edx // Switch to our own temporary GDT. - lgdt [boot_gdtr - KERNEL_VMA] + lgdt [boot_gdtr] retf protected_mode: @@ -105,8 +105,8 @@ protected_mode: page_table_setup: // Zero out the page table. mov al, 0x00 - lea edi, [boot_page_table_start - KERNEL_VMA] - lea ecx, [boot_page_table_end - KERNEL_VMA] + lea edi, [boot_page_table_start] + lea ecx, [boot_page_table_end] sub ecx, edi cld rep stosb @@ -121,8 +121,8 @@ PTE_GLOBAL = (1 << 8) // 0x00000000_40000000 ~ 0x00000000_7fffffff // 0x00000000_80000000 ~ 0x00000000_bfffffff // 0x00000000_c0000000 ~ 0x00000000_ffffffff - lea edi, [boot_pml4 - KERNEL_VMA] - lea eax, [boot_pdpt - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE)] + lea edi, [boot_pml4] + lea eax, [boot_pdpt + (PTE_PRESENT | PTE_WRITE)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 @@ -131,56 +131,56 @@ PTE_GLOBAL = (1 << 8) // 0xffff8000_80000000 ~ 0xffff8000_bfffffff // 0xffff8000_c0000000 ~ 0xffff8000_ffffffff // 0xffff8008_00000000 ~ 0xffff8008_3fffffff - lea edi, [boot_pml4 - KERNEL_VMA + 0x100 * 8] - lea eax, [boot_pdpt - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE)] + lea edi, [boot_pml4 + 0x100 * 8] + lea eax, [boot_pdpt + (PTE_PRESENT | PTE_WRITE)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 // PML4: 0xffffffff_80000000 ~ 0xffffffff_bfffffff // 0xffffffff_c0000000 ~ 0xffffffff_ffffffff - lea edi, [boot_pml4 - KERNEL_VMA + 0x1ff * 8] - lea eax, [boot_pdpt - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE)] + lea edi, [boot_pml4 + 0x1ff * 8] + lea eax, [boot_pdpt + (PTE_PRESENT | PTE_WRITE)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 // PDPT: 0x00000000_00000000 ~ 0x00000000_3fffffff - lea edi, [boot_pdpt - KERNEL_VMA] - lea eax, [boot_pd_0g_1g - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] + lea edi, [boot_pdpt] + lea eax, [boot_pd_0g_1g + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 // PDPT: 0x00000000_40000000 ~ 0x00000000_7fffffff - lea edi, [boot_pdpt - KERNEL_VMA + 0x1 * 8] - lea eax, [boot_pd_1g_2g - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] + lea edi, [boot_pdpt + 0x1 * 8] + lea eax, [boot_pd_1g_2g + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 // PDPT: 0x00000000_80000000 ~ 0x00000000_bfffffff - lea edi, [boot_pdpt - KERNEL_VMA + 0x2 * 8] - lea eax, [boot_pd_2g_3g - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] + lea edi, [boot_pdpt + 0x2 * 8] + lea eax, [boot_pd_2g_3g + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 // PDPT: 0x00000000_c0000000 ~ 0x00000000_ffffffff - lea edi, [boot_pdpt - KERNEL_VMA + 0x3 * 8] - lea eax, [boot_pd_3g_4g - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] + lea edi, [boot_pdpt + 0x3 * 8] + lea eax, [boot_pd_3g_4g + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 // PDPT: 0xffffffff_80000000 ~ 0xffffffff_bfffffff - lea edi, [boot_pdpt - KERNEL_VMA + 0x1fe * 8] - lea eax, [boot_pd_0g_1g - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] + lea edi, [boot_pdpt + 0x1fe * 8] + lea eax, [boot_pd_0g_1g + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 // PDPT: 0xffffffff_c0000000 ~ 0xffffffff_ffffffff - lea edi, [boot_pdpt - KERNEL_VMA + 0x1ff * 8] - lea eax, [boot_pd_1g_2g - KERNEL_VMA + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] + lea edi, [boot_pdpt + 0x1ff * 8] + lea eax, [boot_pd_1g_2g + (PTE_PRESENT | PTE_WRITE | PTE_GLOBAL)] mov dword ptr [edi], eax mov dword ptr [edi + 4], 0 // Page Directory: map to low 1 GiB * 4 space - lea edi, [boot_pd - KERNEL_VMA] + lea edi, [boot_pd] mov eax, PTE_PRESENT | PTE_WRITE | PTE_GLOBAL | PTE_HUGE mov ecx, 512 * 4 // (of entries in PD) * (number of PD) write_pd_entry: @@ -199,7 +199,7 @@ enable_long_mode: mov cr4, eax // Set the page table address. - lea eax, [boot_pml4 - KERNEL_VMA] + lea eax, [boot_pml4] mov cr3, eax // Enable long mode. @@ -211,7 +211,7 @@ enable_long_mode: // Prepare for far return. mov eax, 8 push eax - lea edx, [long_mode_in_low_address - KERNEL_VMA] + lea edx, [long_mode_in_low_address] push edx // Enable paging. @@ -227,7 +227,7 @@ enable_long_mode: .global boot_gdtr boot_gdtr: .word gdt_end - gdt - 1 - .quad gdt - KERNEL_VMA + .quad gdt .align 16 gdt: @@ -274,13 +274,12 @@ long_mode_in_low_address: // Update RSP/RIP to use the virtual address. mov rbx, KERNEL_VMA or rsp, rbx - lea rax, [long_mode - KERNEL_VMA] - or rax, rbx + mov rax, offset long_mode jmp rax -// From here, we're in the .text section: we no longer use physical address. -.code64 +// From here, we're in the .text section: we no longer use physical address. .text +.code64 long_mode: // Clear .bss section. mov al, 0x00 diff --git a/ostd/src/arch/x86/boot/multiboot2/header.S b/ostd/src/arch/x86/boot/multiboot2/header.S index 13831b425..76d967ef4 100644 --- a/ostd/src/arch/x86/boot/multiboot2/header.S +++ b/ostd/src/arch/x86/boot/multiboot2/header.S @@ -10,7 +10,6 @@ MB2_MAGIC = 0xE85250D6 MB2_ARCHITECTURE = 0 // 32-bit (protected) mode of i386 MB2_HEADERLEN = header_end - header_start MB2_CHECKSUM = -(MB2_MAGIC + MB2_ARCHITECTURE + MB2_HEADERLEN) -KERNEL_VMA = 0xffffffff80000000 header_start: .align 8 @@ -26,7 +25,7 @@ entry_address_tag_start: .short 1 // Optional .long entry_address_tag_end - entry_address_tag_start .extern __multiboot_boot - .long __multiboot_boot - KERNEL_VMA // entry_addr + .long __multiboot_boot // entry_addr entry_address_tag_end: // Tag: information request