You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的Hello World EFI程序无法正确构建并运行?

EFI程序无法运行:PE二进制文件格式异常问题

问题概述

开发的EFI程序无法运行,EFI Shell返回Command Error Status: Unsupported错误。通过十六进制转储分析,发现生成的PE二进制文件节头起始位置离PE签名过近,导致无法被加载。开发基于经典EFI编程入门教程,构建环境为Debian 12.4 x86_64。

代码文件

Makefile

ARCH=x86_64

OBJS=hello.o
TARGET=hello.efi

EFIINC=/usr/include/efi
EFIINCS=-I$(EFIINC) -I$(EIFFINC)/$(ARCH) -I$(EFIINC)/protocol
LIB=/usr/lib64
EFILIB=/usr/lib
EFI_CRT_OJBS=$(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS=$(EFILIB)/elf_$(ARCH)_efi.lds

CFLAGS=$(EFIINCS) -fno-stack-protector -fpic -fshort-wchar -mno-red-zone -Wall -DEFI_FUNCION_WRAPPER

LDFLAGS =-nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L $(EFILIB) -L $(LIB) $(EFI_CRT_OBJS)

all: $(TARGET)

hello.so: $(OBJS)
    ld $(LDFLAGS) $(OBJS) -o $@ -lefi -lgnuefi

%.efi: %.so
    objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j rel -j rela -j reloc --target=efi-app-$(ARCH) $^ $@

hello.c

#include <efi.h>
#include <efilib.h>

EFI_STATUS EFIAPI efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
    InitializeLib(ImageHandle, SystemTable);
    Print(L"Hello, World\n");
    return EFI_SUCCESS;
}

测试流程及错误表现

  1. 构建完成后,将hello.efi复制到磁盘镜像,通过以下命令启动QEMU:
    qemu-system-x86_64 -enable-kvm -bios /usr/share/qemu/OVMF.fd -nodefaults -display gtk -vga std -hda target
    
  2. 在EFI Shell中执行程序时出现错误:
    FS0:\> dir
    Directory of: FS0:\
    12/31/2023    48,181  exit.efi
    12/31/2023    41,494  hello.efi
    FS0:\> hello.efi
    Command Error Status: Unsupported
    
    注:官方演示程序exit.efi可正常运行

二进制文件分析结果

objdump输出

$ objdump -f -h hello.efi 

hello.efi:     file format pei-x86-64
architecture: i386:x86-64, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x0000000000000000

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00005bf0  0000000000003000  0000000000003000  00000138  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00001d00  0000000000009000  0000000000009000  00005d38  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  2 .dynamic      00000110  000000000000b000  000000000000b000  00007b38  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  3 .dynsym       000000d8  000000000000d000  000000000000d000  00007d38  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA

十六进制转储头部

$ hexdump -C hello.efi | head -n 16
00000000  4d 5a 90 00 03 00 00 00  04 00 00 00 ff ff 00 00  |MZ..........ÿÿ..|
00000010  b8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  |¸.......@.......|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 80 00 00 00  |................|
00000040  0e 1f ba 0e 00 b4 09 cd  21 b8 01 4c cd 21 54 68  |..º..´.Í!¸.LÍ!Th|
00000050  69 73 20 70 72 6f 67 72  61 6d 20 63 61 6e 6e 6f  |is program canno|
00000060  74 20 62 65 20 72 75 6e  20 69 6e 20 44 4f 53 20  |t be run in DOS |
00000070  6d 6f 64 65 2e 0d 0d 0a  24 00 00 00 00 00 00 00  |mode....$.......|
00000080  50 45 00 00 64 86 04 00  00 00 00 00 38 7f 00 00  |PE..d.......8...|
00000090  12 01 00 00 00 00 05 02  2e 74 65 78 74 00 00 00  |.........text...|
000000a0  f0 5b 00 00 00 30 00 00  00 5c 00 00 38 01 00 00  |ð[...0...\..8...|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 20 00 50 60  |............ .P`|
000000c0  2e 64 61 74 61 00 00 00  00 1d 00 00 00 90 00 00  |.data...........|
000000d0  00 1e 00 00 38 5d 00 00  00 00 00 00 00 00 00 00  |....8]..........|
000000e0  00 00 00 00 40 00 60 c0  2e 64 79 6e 61 6d 69 63  |....@.`À.dynamic|
000000f0  10 01 00 00 00 b0 00 00  00 02 00 00 38 7b 00 00  |.....°......8{..|

核心问题:节头起始位置离PE签名过近,导致EFI无法正常加载该二进制文件

内容的提问来源于stack exchange,提问作者Joshua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:47:34