出于偶然的灵感、自我挑战的冲动,以及对从C++转向C语言后底层运用能力的巩固需求,我最近开始尝试学习UEFI程序开发。UEFI通常作为操作系统内核的引导环境,其编程与常见的应用开发截然不同——它涉及大量UEFI规范中的库函数与驱动交互,且由于处于硬件初始化阶段,几乎无法依赖成熟的第三方库,本质上是使用C语言进行裸机级别的开发。

UEFI本身是一套标准规范,而EDK II是其最著名的开源实现。它基于C语言编写,依赖NASM(汇编器)、IASL(ACPI编译工具)等工具,并使用Python作为构建系统的组织语言。本文便将记录我搭建EDK II开发环境的完整历程,希望能为各位提供一些避坑指南。

初生牛犊:在Windows上的探索与受挫

我偏好实践出真知,有时“撞南墙”反而能让思路更清晰。最初,我尝试在Windows 11上按照某篇中文教程部署EDK II。

准备工作如下:

  1. 已安装 Python 3.11、Visual Studio 2022及VC++ v143构建工具。
  2. NASM官网 下载便携版NASM。
  3. ACPICA项目发布页下载IASL编译器。
  4. 将两者解压至合适目录,并设置环境变量 NASM_PREFIXIASL_PREFIX注意:路径末尾需包含反斜杠)。
  5. 使用Git克隆EDK II主仓库:git clone https://github.com/tianocore/edk2
  6. 递归更新所有子模块:git submodule update --init --recursive
  7. 设置 EDK_TOOLS_BIN 环境变量指向 \<EDK II目录\>\BaseTools\Bin\Win32

至此,理论上所有依赖(VC++、Python、EDK II源码、NASM、IASL)已就位。我满怀信心地进入EDK II根目录,执行:

edksetup.bat

迎接我的却是连绵不绝的MSVC编译错误。耗费近两小时与各种路径、工具链版本和权限问题搏斗后,问题依然无解。切换至Clang编译器尝试,同样失败。最终,我决定暂时从Windows战场“撤退”。

柳暗花明:在Linux上成功构建

我将环境转移至Kali Linux(任何Debian系发行版步骤类似)。系统详情:
Linux kali 6.16.8+kali-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.16.8-1kali1 (2025-09-24) x86_64 GNU/Linux

这次,我决定使用系统原生的GCC工具链。

第一步:安装系统依赖

sudo apt update
sudo apt install -y git python3 python3-pip nasm iasl build-essential uuid-dev libssl-dev

第二步:获取EDK II源码

mkdir -p ~/edk2 && cd ~/edk2
git clone https://github.com/tianocore/edk2.git .
git submodule update --init --recursive

使用 git submodule status 可验证所有子模块状态正常。

第三步:编译EDK II基础工具

cd ~/edk2/BaseTools
make

这里有一个插曲:我首次错误地使用了clang,导致编译报错;切换回gcc后便顺利通过。原因尚待深究,但gcc的兼容性显然更好。

第四步:设置开发环境

cd ~/edk2
source edksetup.sh

第五步:配置目标平台
编辑 Conf/target.txt 文件,主要修改两项:

  • TOOL_CHAIN_TAG = GCC (指定使用GCC编译器)
  • TARGET_ARCH = X64 (指定64位架构)

最后:执行编译
在根目录下,直接运行:

build

随着终端滚过如江河奔流般的编译信息,最终构建成功。默认编译的 EmulatorPkg 项目中,便生成了我们期待的 HelloWorld.efi

验证:在虚拟机中运行第一个UEFI程序

我没有额外配置QEMU,而是选择了一个更直观的方式验证:

  1. HelloWorld.efi 文件放入一个Windows 10安装ISO的根目录。
  2. 在VMware中创建一个空的、固件类型为UEFI的虚拟机,并挂载上述ISO。
  3. 启动虚拟机,进入UEFI Shell环境。
  4. 在Shell中定位到包含文件的卷(例如 fs0:),并执行:

    HelloWorld.efi

屏幕上如期打印出了 “UEFI Hello World!” —— 那一刻,标志着通往底层系统开发的大门,已被叩开。

结语

这仅仅是一个开始,却是我深入理解计算机启动链条和底层硬件交互的一个重要里程碑。UEFI编程世界深邃而复杂,但此番环境搭建的成功,无疑是一个至关重要的航标。未来,我将继续探索UEFI应用的开发,或许,终能以此为基础,创造出一些切实可观的项目。