1. 搭建UEFI开发环境

任务目标

在本案例中,你将完成UEFI开发环境的搭建:安装EDK2源码与必要的工具链,配置编译环境,并最终编译一个输出Hello UEFI!的UEFI应用程序,以验证环境可用。

环境与依赖

  • 操作系统:Ubuntu 22.04 LTS(64位)或Windows 10/11 + WSL2(Ubuntu 22.04)
  • 必要工具链:gcc、make、uuid-dev、python3(EDK2构建脚本依赖)
  • EDK2版本:edk2-stable202311(已验证可稳定编译)

安装基础依赖:

sudo apt update
sudo apt install -y gcc make uuid-dev python3 python3-distutils git

获取EDK2源码

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

配置编译环境

EDK2使用edksetup.sh初始化环境变量,并需在Conf/target.txt中指定工具链。执行以下命令完成配置:

cd ~/uefi_workspace/edk2
make -C BaseTools
source edksetup.sh
# 编辑 Conf/target.txt,设置以下关键项:
# ACTIVE_PLATFORM       = MdeModulePkg/MdeModulePkg.dsc
# TARGET                = RELEASE
# TARGET_ARCH           = X64
# TOOL_CHAIN_TAG        = GCC5

若Conf/target.txt不存在,先运行一次source edksetup.sh生成默认配置,再修改。验证环境变量是否生效:

echo $WORKSPACE   # 应输出 ~/uefi_workspace/edk2
echo $EDK_TOOLS_PATH  # 应指向 BaseTools 路径

编写UEFI应用程序

在MdeModulePkg/Applications下创建HelloUefi目录,包含以下三个文件:

HelloUefi.c(核心实现):

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PrintLib.h>

EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  Print (L"Hello UEFI!\n");
  return EFI_SUCCESS;
}

HelloUefi.inf(模块描述文件):

[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = HelloUefi
  FILE_GUID                      = 8D0E8C3A-6F2A-4B7E-9C1D-3A5B7E9F2C41
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = UefiMain

[Sources]
  HelloUefi.c

[Packages]
  MdePkg/MdePkg.dec

[LibraryClasses]
  UefiLib
  UefiBootServicesTableLib
  PrintLib

Build.py(可选辅助脚本,用于自动编译):

#!/usr/bin/env python3
import subprocess
import os
os.chdir(os.path.expanduser("~/uefi_workspace/edk2"))
subprocess.run(["build"], check=True)

编译与验证

在EDK2根目录执行编译:

cd ~/uefi_workspace/edk2
source edksetup.sh
build

编译成功后,生成的.efi文件位于:

Build/MdeModulePkg/RELEASE_GCC5/X64/HelloUefi.efi

验证方法:在QEMU中运行该EFI程序(需先安装qemu-system-x86和ovmf):

sudo apt install -y qemu-system-x86 ovmf
cp Build/MdeModulePkg/RELEASE_GCC5/X64/HelloUefi.efi /tmp/
# 创建FAT格式磁盘镜像并放入efi文件
dd if=/dev/zero of=/tmp/uefi_disk.img bs=1M count=64
mkfs.vfat /tmp/uefi_disk.img
mmd -i /tmp/uefi_disk.img ::EFI
mcopy -i /tmp/uefi_disk.img /tmp/HelloUefi.efi ::EFI/
# 启动QEMU
qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -drive format=raw,file=fat:rw:/tmp/uefi_disk.img -nographic

在QEMU的UEFI Shell中执行:

fs0:
EFI\HelloUefi.efi

通过条件:屏幕输出Hello UEFI!且无错误信息,即表示环境搭建成功,编译工具链与运行链路均正常。

常见问题

  • 编译报错GCC5 not found:确认gcc已安装,且Conf/target.txt中TOOL_CHAIN_TAG与系统gcc版本匹配。
  • submodule更新失败:网络问题导致,可重试git submodule update --init --recursive,或设置代理。
  • QEMU无法识别fs0::确认磁盘镜像格式正确,且.efi文件确实在FAT分区的EFI目录下。