3、开发环境搭建:EDK2源码下载、编译环境配置(VS/GCC)、模拟器运行
好,咱们直接进入正题。这一章我带你把开发环境搭起来。别小看这一步,我见过太多人卡在环境配置上,代码写好了编译不过,那才叫一个憋屈。
说白了,UEFI开发不像写个简单的C程序,它依赖的工具链和库文件都比较特殊。咱们的目标是:能下载、能编译、能跑起来。嗯,就这三件事。
3.1 EDK2源码下载
EDK2是TianoCore社区维护的开源项目,也是UEFI开发的事实标准。我个人习惯用Git直接拉取,这样方便后续切换分支和打补丁。
打开你的终端,找个干净的目录,执行:
git clone https://github.com/tianocore/edk2.git
cd edk2
git submodule update --init --recursive
这里有个坑,我当初第一次拉的时候忘了执行 submodule update,结果编译时一堆头文件找不到。EDK2依赖了openssl、basecrypto等子模块,必须一并拉下来。
拉完以后,目录结构大概是这样的:
edk2/
├── BaseTools/ # 编译工具和脚本
├── MdePkg/ # 核心定义和协议头文件
├── MdeModulePkg/ # 通用模块
├── UefiCpuPkg/ # CPU相关
├── OvmfPkg/ # 虚拟机和模拟器相关
├── NetworkPkg/ # 网络协议栈
└── ...
你想想看,整个UEFI固件就是由这些Package拼装起来的。咱们后面写驱动,也是在某个Package里加代码。
3.2 编译环境配置
EDK2支持两大工具链:Windows上的VS和Linux上的GCC。我两边都用过,说实话各有优劣。下面分开讲。
3.2.1 Windows + VS2019/2022
Windows下开发,我建议用VS2019或VS2022。安装时记得勾选「使用C++的桌面开发」和「Windows 10 SDK」。
装好以后,打开「x64 Native Tools Command Prompt」,然后设置环境变量:
set EDK_TOOLS_PATH=C:\path\to\edk2\BaseTools
set WORKSPACE=C:\path\to\edk2
set PACKAGES_PATH=C:\path\to\edk2
我个人习惯把这些写到一个批处理文件里,比如 setup_env.bat,每次编译前跑一下就行。省得每次敲一堆命令。
然后执行编译:
edksetup.bat
build -p OvmfPkg\OvmfPkgX64.dsc -a X64 -t VS2019 -b DEBUG
-j N 参数(N为CPU核心数)来加速。我一般用 -j 8。
3.2.2 Linux + GCC5
Linux下就清爽多了。先装依赖:
sudo apt-get install build-essential uuid-dev nasm python3
然后进入EDK2目录,执行:
make -C BaseTools
source edksetup.sh
build -p OvmfPkg\OvmfPkgX64.dsc -a X64 -t GCC5 -b DEBUG
这里要注意,source edksetup.sh 不是 bash edksetup.sh。前者会设置当前shell的环境变量,后者只会在子shell里生效。我当初就犯过这个错,编译时老是报找不到工具链。
3.3 模拟器运行
编译出来的固件是个 .fd 文件,比如 OVMF.fd。这东西不能直接在Windows上双击运行,得用模拟器。
我推荐用QEMU,轻量又好用。安装方式:
- Windows:下载QEMU安装包,把
qemu-system-x86_64.exe所在目录加到PATH里。 - Linux:
sudo apt-get install qemu-system-x86
运行命令:
qemu-system-x86_64 -bios Build\OvmfX64\DEBUG_VS2019\FV\OVMF.fd -m 2048 -net none
你会看到一个UEFI Shell界面。嗯,这就是咱们的「Hello World」了。
.fd 文件里,然后在QEMU里跑起来。
下面这张图帮你理清整个环境搭建的脉络:
3.4 验证环境是否正常
环境搭好以后,怎么确认没问题?我一般做两件事:
- 编译一次OvmfPkg:如果能完整编译通过,说明工具链和依赖没问题。
- 在QEMU里进UEFI Shell:能看到Shell提示符,说明固件能正常启动。
如果编译报错,八成是环境变量没设对,或者子模块没拉全。别慌,看看错误日志,EDK2的报错还算友好。
好了,环境搭好了,下一章咱们就可以写第一个UEFI应用程序了。到时候你就能在Shell里看到自己打印的「Hello UEFI」了。