3. UEFI固件开发环境搭建:EDK2源码获取、编译环境配置(Windows/Linux)、模拟器运行
好,咱们进入第三章。说实话,很多初学者觉得UEFI开发难,其实有一半的功夫都花在环境搭建上。环境配不好,后面全是坑。我个人习惯先把EDK2源码拉下来,再配编译器,最后跑个模拟器验证——这套流程走通了,后面写代码才踏实。
3.1 EDK2源码获取
EDK2是TianoCore社区维护的开源项目,也是UEFI固件开发的事实标准。我建议直接从GitHub拉取稳定分支,别用master,那个太新,有时候会有兼容问题。
推荐分支:edk2-stable202311 或更新的稳定标签。我个人习惯用stable标签,因为经过社区测试,坑少。
3.1.1 通过Git克隆
git clone https://github.com/tianocore/edk2.git
cd edk2
git checkout edk2-stable202311
git submodule update --init --recursive
注意最后一步——子模块更新。EDK2依赖很多第三方库,比如CryptoPkg、MdeModulePkg里的某些组件。如果不更新子模块,编译时会报一堆头文件找不到的错误。我曾经有一次忘了跑这步,排查了半小时才发现是子模块没拉全。
3.1.2 目录结构速览
拉下来之后,你看到的目录大概是这样:
| 目录/文件 | 作用 |
|---|---|
| MdePkg/ | 核心定义:数据类型、协议、PPI、GUID等 |
| MdeModulePkg/ | 通用模块:BDS、Driver Binding、HII等 |
| UefiCpuPkg/ | CPU相关驱动和库 |
| PcAtChipsetPkg/ | 传统芯片组支持(8259、8254等) |
| OvmfPkg/ | QEMU虚拟机固件,模拟器运行就靠它 |
| edksetup.bat / edksetup.sh | 环境初始化脚本(Windows/Linux) |
| Conf/target.txt | 编译目标配置文件 |
嗯,这里要提醒一下:不要直接修改EDK2源码目录下的文件。你的代码应该放在自己的Package里,通过DSC文件引用。这是工程规范,也是避免合并冲突的好习惯。
3.2 编译环境配置
EDK2支持Windows和Linux两大平台。我两边都用过,说实话Linux下更顺手,但Windows也有它的优势——调试工具链更成熟。
3.2.1 Windows环境配置
Windows下需要装三样东西:Visual Studio、Python、NASM。
- Visual Studio 2019/2022:安装时勾选“使用C++的桌面开发”,编译器用VS自带的cl.exe。
- Python 3.x:EDK2的构建脚本依赖Python,建议装3.8以上版本。
- NASM:汇编器,用于编译汇编代码。下载后把nasm.exe所在目录加到PATH里。
小技巧:我习惯在Windows上装一个“Developer Command Prompt for VS”,然后在这个终端里执行EDK2的编译命令。这样环境变量自动配好,省事。
配置步骤:
# 打开VS开发者命令提示符
cd C:\edk2
edksetup.bat Rebuild
# 编辑 Conf\target.txt,设置:
# ACTIVE_PLATFORM = OvmfPkg/OvmfPkgX64.dsc
# TARGET = DEBUG
# TARGET_ARCH = X64
# TOOL_CHAIN_TAG = VS2022
build
我第一次配Windows环境时,卡在TOOL_CHAIN_TAG上。VS2019对应VS2019,VS2022对应VS2022,别写错了。还有,如果报“nasm not found”,八成是PATH没加对。
3.2.2 Linux环境配置
Linux下相对简单,装好gcc、make、python3、nasm就行。以Ubuntu为例:
sudo apt update
sudo apt install build-essential uuid-dev nasm python3 python3-pip
cd ~/edk2
make -C BaseTools
source edksetup.sh
# 编辑 Conf/target.txt,设置:
# ACTIVE_PLATFORM = OvmfPkg/OvmfPkgX64.dsc
# TARGET = DEBUG
# TARGET_ARCH = X64
# TOOL_CHAIN_TAG = GCC5
build
注意Linux下用source edksetup.sh而不是直接执行。这个脚本会设置EDK2相关的环境变量,比如WORKSPACE、PACKAGES_PATH。如果不source,build命令会找不到路径。
避坑指南:我曾经在Ubuntu 22.04上遇到gcc版本过高导致编译报错。EDK2对GCC5支持最好,如果你的系统默认gcc是12或13,建议装一个gcc-10并设置CC=gcc-10。或者用CLANG38工具链也行。
3.3 模拟器运行
环境配好、编译通过后,怎么验证?你手头不一定有真机,所以模拟器是首选。EDK2官方推荐两种方式:QEMU + OVMF 和 NT32模拟器。
3.3.1 QEMU + OVMF
OVMF(Open Virtual Machine Firmware)是EDK2为QEMU虚拟机准备的UEFI固件。编译OvmfPkg后,会生成OVMF.fd文件,这就是一个完整的UEFI BIOS。
运行命令:
# 安装QEMU
sudo apt install qemu-system-x86
# 启动UEFI固件
qemu-system-x86_64 -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd \
-m 2048 \
-net none \
-nographic
你会看到UEFI Shell启动界面。输入map -r可以查看设备映射,输入fs0:可以访问文件系统。说白了,这就是一个完整的UEFI环境,你可以在这里测试自己的驱动或应用。
我的经验:调试阶段我习惯加-debugcon参数,把UEFI日志输出到文件。这样能看到DXE驱动加载顺序、Protocol安装情况,排查问题非常有用。
3.3.2 NT32模拟器(Windows专用)
NT32是EDK2提供的一个特殊平台——它把UEFI环境模拟成一个Windows应用程序。好处是调试方便,可以直接用Visual Studio断点调试。
配置方法:
# 在Conf/target.txt中设置:
# ACTIVE_PLATFORM = Nt32Pkg/Nt32Pkg.dsc
build
# 编译成功后,运行:
Build/Nt32/DEBUG_VS2022/X64/Nt32.efi
会弹出一个控制台窗口,里面就是UEFI Shell。你可以加载自己的.efi文件,测试功能。不过NT32不支持硬件相关的Protocol(比如PCI、SMM),所以只适合纯逻辑测试。
3.4 本章知识体系
下面这张图概括了环境搭建的完整流程和关键节点:
3.5 常见问题与排查
环境搭建过程中,我遇到过不少问题。挑几个典型的说说:
- 编译报错“工具链未找到”:检查Conf/target.txt里的TOOL_CHAIN_TAG是否匹配实际安装的编译器版本。
- 子模块更新失败:网络问题,建议用代理或手动下载子模块包放到edk2目录下。
- QEMU启动后黑屏:检查OVMF.fd路径是否正确,或者加
-vga std参数试试。 - NT32启动报错“无法加载DLL”:缺少Visual C++运行库,安装VC++ redist即可。
调试小技巧:在UEFI Shell里输入ver可以查看固件版本,输入dh可以列出所有已安装的Protocol Handle。这两个命令我几乎天天用,排查驱动加载问题非常高效。
好了,环境搭建就讲到这里。你按照上面的步骤走一遍,应该能顺利看到UEFI Shell的界面。后面章节我们会基于这个环境,开始写真正的UEFI驱动和应用程序。