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 源码。推荐使用 GitHub 上的
tianocore/edk2仓库,并同步子模块。子模块缺失是新手最常见的“编译报错但找不到原因”的根源。 - 配置构建工具链。Linux 下安装
build-essential、nasm、uuid-dev、python3;Windows 下安装 VS 与 Python,并设置EDK_TOOLS_PATH。 - 编译基座工具。执行
edksetup.sh或edksetup.bat,再编译BaseTools,生成build命令。 - 选择运行目标。先用 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 协议与平台服务开发的基础。