1. 构建最小UEFI应用程序

任务目标

编写一个最小的UEFI应用程序,在QEMU虚拟机中运行并输出字符串 Hello UEFI。该程序不依赖操作系统,直接运行于UEFI固件环境。

环境与依赖

  • 操作系统:Linux(本文以Ubuntu/Debian为例)
  • 编译器:gcc(需支持-target交叉编译)或直接使用clang
  • EDK2开发套件:用于提供UEFI头文件与构建工具链
  • QEMU:用于模拟UEFI固件环境(需安装qemu-system-x86_64与OVMF固件包)

安装依赖(Ubuntu/Debian):

sudo apt update
sudo apt install -y gcc qemu-system-x86 ovmf
git clone https://github.com/tianocore/edk2.git
cd edk2
make -C BaseTools
source edksetup.sh

实现代码

创建文件 HelloUefi.c,内容如下:

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiApplicationEntryPoint.h>

EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  Print (L"Hello UEFI\n");
  return EFI_SUCCESS;
}

创建UEFI应用程序的编译描述文件 HelloUefi.inf:

[Defines]
  INF_VERSION                    = 0x00010006
  BASE_NAME                      = HelloUefi
  FILE_GUID                      = 8D0E8C7A-2F5D-4B6A-9E3C-1A2B3C4D5E6F
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = UefiMain

[Sources]
  HelloUefi.c

[Packages]
  MdePkg/MdePkg.dec

[LibraryClasses]
  UefiApplicationEntryPoint
  UefiLib

编译步骤

在EDK2环境中执行以下命令生成.efi文件:

build -p MdePkg/MdePkg.dsc -a X64 -t GCC5 -b DEBUG

编译完成后,可执行文件位于:Build/MdePkg/DEBUG_GCC5/X64/HelloUefi.efi。若需自定义输出路径,可在build命令后添加-D宏或修改target.txt配置。

运行与验证

使用QEMU加载OVMF固件并运行该应用程序:

qemu-system-x86_64 \
  -bios /usr/share/ovmf/OVMF.fd \
  -drive format=raw,file=fat:rw:./Build/MdePkg/DEBUG_GCC5/X64/ \
  -net none -nographic

在QEMU的UEFI Shell中,切换到包含HelloUefi.efi的目录(通常为FS0:),然后执行:

FS0:
HelloUefi.efi

通过条件:屏幕输出 Hello UEFI 且无错误信息,程序正常返回Shell提示符。

常见问题

  • 编译报错找不到头文件:确认已执行source edksetup.sh且当前目录为EDK2根目录。
  • QEMU无法识别UEFI Shell:确保OVMF固件路径正确,且-drive参数指向包含.efi文件的目录。
  • 输出乱码:检查终端编码,UEFI使用UTF-16字符串,QEMU的-nographic模式通常能正确显示。