首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >multiboot2报头要正确进入“启用启动服务的EFI amd64机器状态”- hlt指令不工作?

multiboot2报头要正确进入“启用启动服务的EFI amd64机器状态”- hlt指令不工作?
EN

Stack Overflow用户
提问于 2021-06-15 12:36:50
回答 1查看 286关注 0票数 1

我有一个基本的start.asm (nasm汇编程序)和一个multiboot2_header.asm的简单设置,一旦编译就可以链接到一起。multiboot2头位于最终ELF64-x86_64-file的开头。要运行它,我使用QEMU -> OVMF (UEFI) -> GRUB -> <my-binarỳ>。当我使用最小的multiboot2头时,一切都正常:我处于32位模式,我可以设置自己的堆栈和调用函数。为了验证这一点,我检查QEMU中的寄存器。但是现在我想引导到EFI amd64 machine state with boot services enabled,这是在3.5 multiboot2规范[1]部分中定义的,但是这会带来问题。

如何实现我的目标:规范告诉我们,multiboot2头必须包含两个标记EFI boot services tag: leaves UEFI boot services enabledEFI amd64 entry address tag of Multiboot2 header tag。我确信我做对了(下面的代码)。

问题(更新2021-06-17)经过进一步的调查,看起来我的方法大多是(?)对,是这样。问题是,我的hlt指令被忽略了。这样,执行的代码比预期的要多,而且一些执行会毒害eax。如果我将开始符号中的hlt更改为无限无条件jmp到该jmp的地址,则eax中的值是正确的!(更新结束)

multiboot2-header.asm:

代码语言:javascript
复制
; This file uses "Netwide Assembler Syntax" and can be compiled by running
; `nasm -f elf64 multiboot2_header.asm -o multiboot2_header.o`
;
; External symbol, that comes "start.asm"
EXTERN start

ALIGN   8  ; according to spec, the header must be 64-bit (8 byte) aligned
section .multiboot_header

    header_start:
        ;   dd => int 32, see https://www.cs.uaf.edu/2017/fall/cs301/reference/x86_64.html
        dd  0xe85250d6                ; magic number (multiboot 2 spec)
        dd  0                         ; architecture 0 (protected mode i386; spec doesn't specify many options)
        dd  header_end - header_start ; header length
        ;   checksum
        dd  0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))

        ; OPTIONAL MULTIBOOT2 TAGS (additional to required END TAG)
        ; In order to boot into "EFI amd64 machine state with boot services enabled" (3.5 in Spec, 2021-06)
        ; machine state, we must specify a few additional tags:
        ;
        ; ------------------------------------------------------------------------------------
        ; "EFI boot services tag": leaves UEFI boot services enabled: its our task to exit them
        ALIGN   8       ; alignment in bits, according to multiboot2 spec, tags are 8-byte (64bit) aligned
        dw      7       ; type  (16bit)
        dw      0       ; flags (16bit)
        dd      8       ; size  (32bit)
        ; ------------------------------------------------------------------------------------
        ; "EFI amd64 entry address tag of Multiboot2 header tag"
        ALIGN   8
        dw      9       ; type  (16bit)
        dw      0       ; flags (16bit)
        dd      12      ; size  (32bit)
        ; TODO I'm not entirely sure how this works together with the "start" symbol from the linker script:
        ;  perhaps the start symbol in the linker script is a fallback, if this is not found
        dd      start   ; entry_addr (32bit)
        ; ------------------------------------------------------------------------------------
        ; REQUIRED END TAG
        ALIGN   8
        dw      0       ; type  (16bit)
        dw      0       ; flags (16bit)
        dd      8       ; size  (32bit)
    header_end:

PS:锈蚀工具引导信息[2]正确识别multiboot2头和指定的标签在我的最终ELF。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-17 18:23:28

我最初的方法是正确的,而且实际上是正确的。我只是因为两种误解而无法正确地检查一下:

  • 我实际上处于64位长模式,但试图执行32位代码。
  • hlt指令不起作用,因为QEMU被中断,hlt被清除

在启动/切换后,您可以轻松地验证QEMU中的寄存器,如果开始符号如下所示:

代码语言:javascript
复制
GLOBAL start

SECTION .text

; produce x-bit x86 code (even if this will be an ELF-64 file)
[BITS 64]

    start:
        mov r12, 0xffffeeeeddddcccc   ; verify that we are in 64-bit mode (otherwise this fails)
        cli ; without clear interrupts, the hlt is ignored (I don't know what interrupt comes.. maybe the key input in qemu)
        hlt
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67986406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档