3. UEFI 开发环境搭建:EDK2 源码获取、VS2019/VS2022 与 GCC 工具链配置、编译第一个 UEFI 应用
搭建稳定、可复现的开发环境是 UEFI 固件开发的基石。本章将引导你完成从源码获取、工具链配置到编译并运行第一个 UEFI 应用程序的完整流程。我们将以 EDK2(EFI Development Kit II)作为核心开发框架,分别讲解在 Windows 与 Linux 环境下的标准配置方法。
3.1 EDK2 源码获取与版本管理
EDK2 是 TianoCore 社区维护的开源 UEFI 固件开发框架,几乎所有的 UEFI BIOS 开发都基于此。推荐使用 Git 进行版本管理,以便跟踪上游更新和自定义修改。
3.1.1 克隆 EDK2 主仓库
打开终端或命令提示符,执行以下命令获取 EDK2 的稳定分支(推荐 edk2-stable202405 或更新版本):
git clone https://github.com/tianocore/edk2.git
cd edk2
git checkout edk2-stable202405
3.1.2 初始化子模块
EDK2 依赖多个子模块(如 MdePkg、CryptoPkg 等),必须同步初始化:
git submodule update --init --recursive
3.2 Windows 环境:VS2019/VS2022 工具链配置
Windows 平台下,微软 Visual Studio 是编译 EDK2 的主流选择。VS2019 与 VS2022 均受支持,配置步骤基本一致。
3.2.1 安装 Visual Studio
安装时请确保勾选以下工作负载:
- 使用 C++ 的桌面开发(包含 MSVC 编译器、Windows SDK)
- Windows 10 SDK 或 Windows 11 SDK(建议最新版本)
3.2.2 配置 EDK2 编译环境
EDK2 使用 edksetup.bat 脚本初始化环境变量。每次打开新终端编译前,需执行:
cd C:\path\to\edk2
edksetup.bat
该脚本会自动检测已安装的 VS 版本并设置 PATH、INCLUDE、LIB 等环境变量。若系统同时安装多个 VS 版本,可通过参数指定:
edksetup.bat --nt32 # 使用 VS2019
edksetup.bat --nt32 VS2022 # 使用 VS2022
3.2.3 验证工具链
执行以下命令确认编译器可用:
build -p MdePkg\MdePkg.dsc -a X64 -t VS2022 -b DEBUG
若输出无错误,则表明工具链配置成功。
3.3 Linux 环境:GCC 工具链配置
Linux 平台通常使用 GCC 交叉编译器。以 Ubuntu 22.04 LTS 为例:
3.3.1 安装必要软件包
sudo apt update
sudo apt install build-essential uuid-dev nasm python3 python3-pip
3.3.2 安装 GCC 交叉编译器
EDK2 需要 gcc-aarch64-linux-gnu(ARM64)或 gcc-x86-64-linux-gnu(X64)。以 X64 目标为例:
sudo apt install gcc-x86-64-linux-gnu
3.3.3 配置 EDK2 环境
Linux 下使用 edksetup.sh:
cd ~/edk2
source edksetup.sh
该脚本会设置 WORKSPACE、PACKAGES_PATH 等环境变量。建议将 source edksetup.sh 添加到 ~/.bashrc 中以便自动加载。
3.3.4 验证 GCC 工具链
build -p MdePkg\MdePkg.dsc -a X64 -t GCC5 -b DEBUG
GCC5(兼容 GCC 5.x 及以上版本)。若使用 Clang,请使用 CLANGDWARF 或 CLANGPDB 标签。
3.4 工具链对比与选择建议
| 特性 | VS2019/VS2022 | GCC (Linux) | GCC (Windows, MinGW) |
|---|---|---|---|
| 调试体验 | 优秀(集成 WinDbg) | 良好(GDB) | 一般 |
| 编译速度 | 较快 | 中等 | 较慢 |
| 二进制兼容性 | PE32+ 格式 | PE32+ 格式 | PE32+ 格式 |
| 社区支持 | 广泛 | 广泛 | 较少 |
| 推荐场景 | Windows 原生开发 | Linux 服务器/CI | 跨平台测试 |
3.5 编译第一个 UEFI 应用:HelloWorld
EDK2 自带一个经典的 HelloWorld 示例,位于 MdeModulePkg/Application/HelloWorld。我们将以此为例,完成从编译到运行的完整流程。
3.5.1 确认应用源码结构
进入 MdeModulePkg/Application/HelloWorld 目录,查看关键文件:
HelloWorld.c— 主程序源码HelloWorld.inf— 模块描述文件(INF),定义模块属性、依赖库、源文件等
HelloWorld.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 World!\n");
return EFI_SUCCESS;
}
3.5.2 修改平台描述文件(DSC)
为了让 EDK2 的构建系统识别并编译该应用,需要将其添加到平台描述文件(.dsc)中。以 MdeModulePkg/MdeModulePkg.dsc 为例,在 [Components] 段添加:
[Components]
MdeModulePkg/Application/HelloWorld/HelloWorld.inf
3.5.3 执行编译
在 EDK2 根目录执行以下命令(以 VS2022 为例):
build -p MdeModulePkg\MdeModulePkg.dsc -a X64 -t VS2022 -b DEBUG
编译成功后,输出文件位于 Build/MdeModule/DEBUG_VS2022/X64/HelloWorld.efi。
3.5.4 在模拟器中运行
EDK2 提供了 NT32 模拟器,可在 Windows 下直接运行 UEFI 应用:
build -p MdeModulePkg\MdeModulePkg.dsc -a X64 -t VS2022 -b DEBUG
cd Build\MdeModule\DEBUG_VS2022\X64
SecMain.efi
在模拟器 Shell 中,切换到 fs0: 并执行 HelloWorld.efi,即可看到输出:
FS0:\> HelloWorld.efi
Hello, UEFI World!
3.6 编译流程与关键概念图解
下图展示了从源码到 UEFI 可执行文件的完整编译流程:
3.7 常见问题与排查
- 编译报错:找不到头文件 — 检查
PACKAGES_PATH环境变量是否指向 EDK2 根目录,或子模块是否未同步。 - 链接错误:未解析的外部符号 — 确认
HelloWorld.inf的[LibraryClasses]段已包含UefiLib、UefiApplicationEntryPoint等必要库。 - 模拟器无法启动 — 确保以管理员权限运行
SecMain.efi,或检查 Windows 防火墙是否阻止了模拟器进程。 - GCC 编译报错:缺少
nasm— 安装 NASM 汇编器:sudo apt install nasm。
3.8 小结
至此,你已经完成了 UEFI 开发环境的完整搭建,并成功编译并运行了第一个 UEFI 应用程序。掌握 EDK2 的构建系统、工具链配置和基本调试方法,是后续深入学习 UEFI 驱动开发、固件定制和平台初始化的基础。建议将本章的编译流程反复练习,直至能够独立完成从零开始的环境搭建。