Fix multiboot entry in UEFI boot

This commit is contained in:
Zhang Junyang
2023-10-12 21:16:43 +08:00
committed by Tate, Hongliang Tian
parent cdc2b960dc
commit 503252e8e8
4 changed files with 32 additions and 26 deletions

View File

@ -11,6 +11,9 @@ ENTRYTYPE_MULTIBOOT = 1
ENTRYTYPE_MULTIBOOT2 = 2 ENTRYTYPE_MULTIBOOT2 = 2
ENTRYTYPE_LINUX_32 = 3 ENTRYTYPE_LINUX_32 = 3
MULTIBOOT_ENTRY_MAGIC = 0x2BADB002
MULTIBOOT2_ENTRY_MAGIC = 0x36D76289
// The Linux 32-bit Boot Protocol entry point. // The Linux 32-bit Boot Protocol entry point.
// Must be located at 0x100000, ABI immutable! // Must be located at 0x100000, ABI immutable!
.code32 .code32
@ -40,7 +43,7 @@ __linux64_boot_tag:
call rax call rax
jmp halt // unreachable here jmp halt // unreachable here
// The multiboot entry point. // The multiboot & multiboot2 entry point.
.code32 .code32
.global __multiboot_boot .global __multiboot_boot
__multiboot_boot: __multiboot_boot:
@ -54,28 +57,19 @@ __multiboot_boot:
push eax // multiboot magic ptr push eax // multiboot magic ptr
push 0 // Upper 32-bits. push 0 // Upper 32-bits.
push ebx // multiboot info ptr push ebx // multiboot info ptr
// Tell the entry type from eax
cmp eax, MULTIBOOT_ENTRY_MAGIC
je magic_is_mb
cmp eax, MULTIBOOT2_ENTRY_MAGIC
je magic_is_mb2
jmp halt // Should not be reachable!
magic_is_mb:
push 0 // Upper 32-bits. push 0 // Upper 32-bits.
push ENTRYTYPE_MULTIBOOT push ENTRYTYPE_MULTIBOOT
jmp initial_boot_setup jmp initial_boot_setup
magic_is_mb2:
// The multiboot2 entry point.
.code32
.global __multiboot2_boot
__multiboot2_boot:
cli
cld
// Set the kernel call stack.
mov esp, offset boot_stack_top
push 0 // Upper 32-bits.
push eax // multiboot magic ptr
push 0 // Upper 32-bits.
push ebx // multiboot info ptr
push 0 // Upper 32-bits. push 0 // Upper 32-bits.
push ENTRYTYPE_MULTIBOOT2 push ENTRYTYPE_MULTIBOOT2
jmp initial_boot_setup jmp initial_boot_setup
initial_boot_setup: initial_boot_setup:
@ -305,6 +299,8 @@ long_mode:
// Call the corresponding Rust entrypoint according to the boot entrypoint // Call the corresponding Rust entrypoint according to the boot entrypoint
pop rax pop rax
cmp rax, ENTRYTYPE_MULTIBOOT
je entry_type_multiboot
cmp rax, ENTRYTYPE_MULTIBOOT2 cmp rax, ENTRYTYPE_MULTIBOOT2
je entry_type_multiboot2 je entry_type_multiboot2
cmp rax, ENTRYTYPE_LINUX_32 cmp rax, ENTRYTYPE_LINUX_32
@ -312,17 +308,31 @@ long_mode:
// Unreachable! // Unreachable!
jmp halt jmp halt
.extern __linux64_boot
.extern __multiboot_entry
.extern __multiboot2_entry
entry_type_linux_32: entry_type_linux_32:
pop rdi // boot_params ptr pop rdi // boot_params ptr
// Clear the frame pointer to stop backtracing here. // Clear the frame pointer to stop backtracing here.
xor rbp, rbp xor rbp, rbp
.extern __linux64_boot
lea rax, [rip + __linux64_boot] // jump into Rust code lea rax, [rip + __linux64_boot] // jump into Rust code
call rax call rax
jmp halt jmp halt
entry_type_multiboot:
pop rsi // the address of multiboot info
pop rdi // multiboot magic
// Clear the frame pointer to stop backtracing here.
xor rbp, rbp
lea rax, [rip + __multiboot_entry] // jump into Rust code
call rax
jmp halt
entry_type_multiboot2: entry_type_multiboot2:
pop rsi // the address of multiboot info pop rsi // the address of multiboot info
pop rdi // multiboot magic pop rdi // multiboot magic
@ -330,7 +340,6 @@ entry_type_multiboot2:
// Clear the frame pointer to stop backtracing here. // Clear the frame pointer to stop backtracing here.
xor rbp, rbp xor rbp, rbp
.extern __multiboot2_entry
lea rax, [rip + __multiboot2_entry] // jump into Rust code lea rax, [rip + __multiboot2_entry] // jump into Rust code
call rax call rax
jmp halt jmp halt

View File

@ -1,4 +1,4 @@
ENTRY(__linux64_boot) ENTRY(__multiboot_boot)
OUTPUT_ARCH(i386:x86-64) OUTPUT_ARCH(i386:x86-64)
OUTPUT_FORMAT(elf64-x86-64) OUTPUT_FORMAT(elf64-x86-64)

View File

@ -12,6 +12,3 @@ multiboot_header:
.long MB_MAGIC .long MB_MAGIC
.long MB_FLAGS .long MB_FLAGS
.long MB_CHECKSUM .long MB_CHECKSUM
multiboot_entry:
.global __multiboot_boot
jmp __multiboot_boot

View File

@ -22,8 +22,8 @@ entry_address_tag_start:
.short 3 .short 3
.short 1 // Optional .short 1 // Optional
.long entry_address_tag_end - entry_address_tag_start .long entry_address_tag_end - entry_address_tag_start
.extern __multiboot2_boot .extern __multiboot_boot
.long __multiboot2_boot // entry_addr .long __multiboot_boot // entry_addr
entry_address_tag_end: entry_address_tag_end:
// Tag: information request // Tag: information request