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

如何使用C++构建UEFI应用,编译后Qemu启动卡住求解决方案或POC代码

问题排查与解决方案

现有代码问题原因

  • 缺少extern "C"修饰入口函数:C++编译器会对函数名做名字修饰,而GNU EFI要求入口函数efi_main使用C ABI,不加修饰会导致固件找不到合法入口点,直接卡住启动流程。
  • 缺少输出刷新逻辑:UEFI的Print接口默认会做输出缓冲,未刷新就进入死循环会导致字符串无法正常打印到屏幕。
  • hlt指令未关中断:开中断状态下hlt会在收到中断时恢复执行,死循环逻辑会被打破。

修正后的可用C++ UEFI POC代码

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

// 必须加extern "C"指定使用C ABI,避免C++名字修饰导致入口点失效
extern "C" EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
    InitializeLib(ImageHandle, SystemTable);
    // 末尾加\n触发行缓冲刷新,保证内容正常输出
    Print(L"XENON OS VER 0.02\n");
    // 关中断后执行hlt,确保稳定停在死循环
    for(;;) __asm__ volatile ("cli; hlt");
    return EFI_SUCCESS;
}

完整编译链接流程(x86_64架构为例,需将gnu-efi-dir替换为本地gnu-efi库的实际路径)

  1. 编译目标文件
gcc -Ignu-efi-dir/inc -Ignu-efi-dir/inc/x86_64 -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -c main.cpp -o main.o
  1. 链接生成共享对象
ld -shared -Bsymbolic -Lgnu-efi-dir/lib -Tgnu-efi-dir/gnuefi/elf_x86_64_efi.lds gnu-efi-dir/gnuefi/crt0-efi-x86_64.o main.o -o main.so -lgnuefi -lefi
  1. 格式转换生成最终EFI可执行文件
objcopy -j .text -j .sdata -j .data -j .reloc --target=efi-app-x86_64 main.so main.efi

测试注意事项

  • 将生成的main.efi放到FAT32格式的镜像EFI/BOOT/BOOTX64.EFI路径下,再用Qemu启动即可正常看到输出
  • 确保使用的gnu-efi库版本和编译架构匹配,x86_64、ia32、aarch64的链接脚本和crt0文件各不相同

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:54:02