3. 开发环境搭建

UEFI 应用开发与普通用户态程序最大的区别在于:代码运行在固件阶段,没有操作系统提供运行时环境,编译、链接、打包、部署、调试各环节都需要专用工具链配合。EDK II 是当前 UEFI 固件开发的事实标准开源框架,掌握它的源码获取、构建工具链、模拟器与真实平台烧录调试配置,是完成第一个 UEFI 应用的前提。本章围绕“从零到跑通一个 HelloUEFI 应用”这条主线,把环境搭建拆解为源码、工具链、模拟器、真机烧录四个环节。

一、核心原理:EDK II 的构建模型

EDK II 不是简单的 Makefile 工程,而是一套“描述文件驱动”的构建系统。开发者编写 .inf(模块描述)、.dsc(平台描述)、.fdf(固件布局)三类文件,构建工具 build 读取这些描述,调用底层编译器生成 .efi 应用或完整固件镜像。理解这条链路,才能明白为什么“改一个文件要动三处描述”。

构建过程大致分为:解析 DSC/FDF → 编译各模块 → 链接生成 PE/COFF 格式的 .efi → 按 FDF 规则打包成 .fd 固件卷。UEFI 应用最终以 PE/COFF 可执行文件形式存在,由固件加载器加载执行,这与 Windows 的 PE 格式同源,但运行环境完全不同。

EDK II 构建链路与运行环境 源码与描述文件 .c / .h .inf / .dsc / .fdf 构建工具链 build / GenFw GCC / VS / CLANG 构建产物 HelloUEFI.efi OVMF.fd / 平台固件 运行环境 QEMU 模拟器 真实主板 模拟器路径(推荐入门) 1. 构建 OVMF.fd 2. 制作 FAT 格式 ESP 盘 3. QEMU 加载固件与磁盘 4. UEFI Shell 中执行 .efi 真实平台路径(进阶) 1. 确认主板支持 UEFI Shell 2. U 盘制作 ESP 分区 3. 关闭 Secure Boot 或签名 4. 串口 / 屏幕查看输出

二、方法流程:四步搭建可运行环境

  1. 获取 EDK II 源码。推荐使用 GitHub 上的 tianocore/edk2 仓库,并同步子模块。子模块缺失是新手最常见的“编译报错但找不到原因”的根源。
  2. 配置构建工具链。Linux 下安装 build-essential、nasm、uuid-dev、python3;Windows 下安装 VS 与 Python,并设置 EDK_TOOLS_PATH。
  3. 编译基座工具。执行 edksetup.sh 或 edksetup.bat,再编译 BaseTools,生成 build 命令。
  4. 选择运行目标。先用 QEMU + OVMF 跑通模拟器,再迁移到真实平台烧录调试。
# Linux 下典型初始化流程
git clone https://github.com/tianocore/edk2.git
cd edk2
git submodule update --init --recursive
make -C BaseTools
source edksetup.sh
# 修改 Conf/target.txt
# ACTIVE_PLATFORM = OvmfPkg/OvmfPkgX64.dsc
# TOOL_CHAIN_TAG = GCC5
# TARGET_ARCH    = X64
build

三、案例:第一个 UEFI 应用 HelloUEFI

在 edk2 下新建 HelloUEFI 包,包含 HelloUEFI.inf 与 HelloUEFI.c。入口函数使用 UefiMain,通过 SystemTable->ConOut->OutputString 输出字符串。INF 中声明模块类型为 UEFI_APPLICATION,并在 DSC 的 [Components] 段登记。

EFI_STATUS EFIAPI UefiMain(
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable)
{
  SystemTable->ConOut->OutputString(
      SystemTable->ConOut, L"Hello UEFI!\r\n");
  return EFI_SUCCESS;
}

编译后产物位于 Build/OvmfX64/DEBUG_GCC5/X64/HelloUEFI.efi。把它复制到 FAT 格式 U 盘的 \EFI\BOOT\ 目录,在 UEFI Shell 中执行 HelloUEFI.efi,即可看到输出。这一步跑通,说明源码、工具链、运行环境三者已经打通。

四、模拟器与真实平台配置对比

对比项 QEMU + OVMF 模拟器 真实平台烧录调试
固件来源自行构建 OVMF.fd主板厂商固件或自编译固件
部署方式QEMU 参数加载磁盘镜像U 盘 ESP 分区或 SPI Flash 烧录
调试手段QEMU 串口、GDB stub串口日志、JTAG、屏幕输出
Secure Boot默认关闭,无需签名常需关闭或对应用签名
风险低,可反复重启高,刷坏固件可能无法开机
适用阶段功能验证、快速迭代硬件相关验证、最终交付

五、误区与复盘

常见误区一:只克隆主仓库,忘记子模块。表现为编译时找不到 MdePkg 等包。解决:执行 git submodule update --init --recursive。

常见误区二:工具链标签写错。Linux 常用 GCC5,Windows 常用 VS2019,写错会提示找不到编译器。

常见误区三:U 盘不是 FAT 格式。UEFI 固件只识别 FAT12/16/32,NTFS 或 exFAT 无法加载 .efi。

常见误区四:真机未关 Secure Boot。未签名的自编译应用会被拒绝执行,需在 BIOS 中关闭或进行签名。

复盘建议:先用模拟器把 HelloUEFI 跑通,再迁移到真机。每次修改后记录“改了哪个描述文件、编译命令、运行结果”,形成自己的环境搭建笔记。环境问题往往不是代码问题,而是描述文件、路径、工具链标签三者之一出错。

完成本章后,你应当拥有一个可重复使用的 EDK II 开发环境:源码完整、工具链可用、模拟器可启动、真机可部署。这是后续所有 UEFI 协议与平台服务开发的基础。