ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

自己编译EDK2 ARM版固件并用qemu安装Windows On ARM系统

2026/8/13 22:44:28 拓冰建站 浏览量
自己编译EDK2 ARM版固件并用qemu安装Windows On ARM系统 在 Windows 上交叉编译 AARCH64 UEFI 固件ArmVirtQemu本文档记录了在 Windows 10/11 上使用 EDK2 源码和 GCC 交叉编译工具链构建支持 Secure Boot 与 TPM 2.0 的 AARCH64 UEFI 固件.fd的完整流程并使用 QEMU 验证固件启动。1. 环境要求组件版本说明EDK2 源码edk2 2508Full工作目录E:\code\edk22508FullARM GCC 交叉工具链arm-gnu-toolchain-15.3.rel1-mingw-w64-x86_64-aarch64-none-elf安装于C:\Tools\Host GCC (MinGW-W64)13.2.0 (Strawberry Perl 自带)用于编译 BaseTools C 工具GNU Make4.4.1 (Strawberry Perl 自带gmake.exe)BaseTools 编译用Python3.10.9EDK2 build 系统依赖NASM2.x (Strawberry Perl 自带)汇编编译用iasl (ACPI 编译器)20250807从 ACPICA GitHub Releases 下载QEMUsystem-aarch64用于固件启动验证1.1 工具链路径一览C:\Tools\arm-gnu-toolchain-15.3.rel1-mingw-w64-x86_64-aarch64-none-elf\bin\ ├── aarch64-none-elf-gcc.exe # 交叉编译器 ├── aarch64-none-elf-gcc-ar.exe # 静态库归档 ├── aarch64-none-elf-objcopy.exe # 目标文件转换 └── aarch64-none-elf-ld.exe # 链接器 C:\Strawberry\c\bin\ ├── gcc.exe # Host GCC (编译 BaseTools) ├── gmake.exe # GNU Make └── nasm.exe # NASM 汇编器 C:\Program Files\Python310\python.exe # Python 3.10 C:\Program Files\qemu\ └── qemu-system-aarch64.exe # QEMU (验证用)1.2 获取 iasl从 ACPICA GitHub Releases 下载 Windows 预编译版本# 下载 iaslInvoke-WebRequest-Urihttps://github.com/user-attachments/files/21674608/iasl-win-20250807.zip-OutFileiasl.zip# 解压Expand-Archive-Pathiasl.zip-DestinationPathiasl_temp# 复制到 BaseTools\Bin\Win32Copy-Itemiasl_temp\iasl.exeE:\code\edk22508Full\BaseTools\Bin\Win32\iasl.exe2. 编译 EDK2 BaseToolsBaseTools 是 EDK2 的构建工具集C 工具 Python 脚本需要先编译。2.1 初始化配置文件运行edksetup.bat生成Conf\target.txt、Conf\tools_def.txt和Conf\build_rule.txtcd /d E:\code\edk22508Full call edksetup.bat如果edksetup.bat因环境问题报错可手动从BaseTools\Conf\目录复制.template文件到Conf\目录并去掉.template后缀。2.2 编译 BaseTools C 工具使用 Strawberry Perl 的 GNU Make 和 GCC 编译cd /d E:\code\edk22508Full\BaseTools\Source\C set HOST_ARCHX64 set CCgcc set CXXg set PYTHON_COMMANDpy -3 set PATHC:\Strawberry\c\bin;%PATH% C:\Strawberry\c\bin\gmake.exe -j4编译成功后在BaseTools\Source\C\bin\下生成 12 个.exe文件BrotliCompress.exe DevicePath.exe EfiRom.exe GenCrc32.exe GenFfs.exe GenFv.exe GenFw.exe GenSec.exe LzmaCompress.exe TianoCompress.exe VfrCompile.exe VolInfo.exe2.3 复制工具到 Bin\Win32mkdir E:\code\edk22508Full\BaseTools\Bin\Win32 2nul copy E:\code\edk22508Full\BaseTools\Source\C\bin\*.exe ^ E:\code\edk22508Full\BaseTools\Bin\Win32\2.4 创建 GNU make 副本EDK2 的 GCC 工具链通过GCC_HOST_BIN环境变量查找make。Strawberry Perl 提供的是gmake.exe需要复制一份为make.execopy C:\Strawberry\c\bin\gmake.exe C:\Strawberry\c\bin\make.exe3. 配置工具链3.1 关键环境变量环境变量值说明GCC5_AARCH64_PREFIXC:\Tools\arm-gnu-toolchain-...\bin\aarch64-none-elf-ARM 交叉工具链前缀GCC_HOST_BINC:\Strawberry\c\bin\Host GNU make 路径NASM_PREFIXC:\Strawberry\c\bin\NASM 前缀PYTHON_COMMANDpy -3Python 命令EDK_TOOLS_BIN...\BaseTools\Bin\Win32BaseTools 二进制路径3.2 tools_def.txt 中的 GCC5 工具链EDK2 的Conf\tools_def.txt已内置 GCC5 工具链定义关键行# 工具链前缀通过环境变量设置 DEFINE GCC_HOST_PREFIX ENV(GCC_HOST_BIN) # AARCH64 交叉编译器路径 *_GCC5_AARCH64_CC_PATH ENV(GCC5_AARCH64_PREFIX)gcc *_GCC5_AARCH64_SLINK_PATH ENV(GCC5_AARCH64_PREFIX)gcc-ar *_GCC5_AARCH64_DLINK_PATH ENV(GCC5_AARCH64_PREFIX)gcc *_GCC5_AARCH64_ASM_PATH ENV(GCC5_AARCH64_PREFIX)gcc *_GCC5_AARCH64_PP_PATH ENV(GCC5_AARCH64_PREFIX)gcc *_GCC5_AARCH64_RC_PATH ENV(GCC5_AARCH64_PREFIX)objcopy # Host make 路径 *_GCC5_*_MAKE_PATH DEF(GCC_HOST_PREFIX)make4. 构建固件4.1 构建脚本创建build_armvirt.batecho off setlocal set WORKSPACEE:\code\edk22508Full set EDK_TOOLS_PATHE:\code\edk22508Full\BaseTools set BASE_TOOLS_PATHE:\code\edk22508Full\BaseTools set EDK_TOOLS_BINE:\code\edk22508Full\BaseTools\Bin\Win32 set CONF_PATHE:\code\edk22508Full\Conf set PYTHON_COMMANDpy -3 set PYTHONPATHE:\code\edk22508Full\BaseTools\Source\Python set GCC5_AARCH64_PREFIXC:\Tools\arm-gnu-toolchain-15.3.rel1-mingw-w64-x86_64-aarch64-none-elf\bin\aarch64-none-elf- set GCC_HOST_BINC:\Strawberry\c\bin\ set NASM_PREFIXC:\Strawberry\c\bin\ set PATHE:\code\edk22508Full\BaseTools\Bin\Win32;E:\code\edk22508Full\BaseTools\BinWrappers\WindowsLike;C:\Strawberry\c\bin;C:\Program Files\Python310;C:\Program Files\qemu;%PATH% cd /d E:\code\edk22508Full build -a AARCH64 -t GCC5 -b RELEASE -p ArmVirtPkg/ArmVirtQemu.dsc ^ -D SECURE_BOOT_ENABLETRUE ^ -D TPM2_ENABLETRUE ^ -D TPM2_CONFIG_ENABLETRUE ^ %*4.2 参数说明参数值说明-aAARCH64目标架构-tGCC5工具链标签-bRELEASE构建类型DEBUG / RELEASE / NOOPT-pArmVirtPkg/ArmVirtQemu.dsc平台描述文件-D SECURE_BOOT_ENABLETRUE—启用 Secure Boot镜像签名验证-D TPM2_ENABLETRUE—启用 TPM 2.0 支持-D TPM2_CONFIG_ENABLETRUE—启用 TPM 2.0 配置界面4.3 执行构建cd /d E:\code\edk22508Full build_armvirt.bat构建过程约 3~15 分钟取决于 CPU 核心数输出如下关键信息表示成功Fd File Name:QEMU_EFI (...\Build\ArmVirtQemu-AARCH64\RELEASE_GCC5\FV\QEMU_EFI.fd) Fd File Name:QEMU_VARS (...\Build\ArmVirtQemu-AARCH64\RELEASE_GCC5\FV\QEMU_VARS.fd) FV Space Information FVMAIN [99%Full] 7131712 total, 7131656 used, 56 free FVMAIN_COMPACT [38%Full] 3141632 total, 1199736 used, 1941896 free - Done -4.4 构建产物文件大小说明QEMU_EFI.fd3 MB主固件文件包含 SEC/PEI/DXE/BDS 全部模块QEMU_VARS.fd768 KBNVRAM 变量存储Secure Boot 密钥等路径Build\ArmVirtQemu-AARCH64\RELEASE_GCC5\FV\5. Secure Boot 与 TPM 2.0 模块说明5.1 Secure Boot 相关模块启用SECURE_BOOT_ENABLETRUE后以下模块被编入固件模块阶段功能DxeImageVerificationLibDXEUEFI 镜像签名验证SecureBootConfigDxeDXESecure Boot 配置界面EnrollDefaultKeysDXE默认密钥注册VariableRuntimeDxeDXE认证变量服务AuthVar相关 PCDgEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04 gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04 gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x045.2 TPM 2.0 相关模块启用TPM2_ENABLETRUE后以下模块被编入固件模块阶段功能Tcg2ConfigPeiPEITPM 2.0 早期配置Tcg2PeiPEIPEI 阶段 TPM 度量Tcg2DxeDXEDXE 阶段 TCG2 协议Tcg2ConfigDxeDXETPM 2.0 配置界面DxeTpm2MeasureBootLibDXE启动度量需同时启用 Secure BootTpm2CommandLib—TPM 2.0 命令库Tpm2DeviceLibDTpm—dTPM MMIO 设备访问库注意TPM 2.0 模块已编入.fd但实际运行需要 QEMU 提供 TPM 设备模拟tpm-tis-device前端 swtpm后端。Windows 版 QEMU 不支持 TPM 后端需在 Linux 环境验证。6. QEMU 验证固件启动6.1 准备 pflash 镜像QEMUvirt机器的 pflash 设备要求 64 MB 镜像需要将 3 MB 的QEMU_EFI.fd填充到 64 MB# 填充 QEMU_EFI.fd 到 64MB$content[System.IO.File]::ReadAllBytes(...\FV\QEMU_EFI.fd)$paddedNew-Objectbyte[]67108864[Array]::Copy($content,$padded,$content.Length)[System.IO.File]::WriteAllBytes(...\FV\QEMU_EFI_64M.fd,$padded)# 填充 QEMU_VARS.fd 到 64MB可写副本$content[System.IO.File]::ReadAllBytes(...\FV\QEMU_VARS.fd)$paddedNew-Objectbyte[]67108864[Array]::Copy($content,$padded,$content.Length)[System.IO.File]::WriteAllBytes(...\FV\QEMU_VARS_64M.fd,$padded)6.2 启动 QEMUqemu-system-aarch64.exe ^ -machine virt ^ -cpu cortex-a57 ^ -m 512 ^ -nographic ^ -drive ifpflash,formatraw,fileQEMU_EFI_64M.fd,readonlyon ^ -drive ifpflash,formatraw,fileQEMU_VARS_64M.fd ^ -net none6.3 预期输出固件正常启动时串口输出如下UEFI firmware (version built at 12:13:16 on Jul 27 2026) BdsDxe: No bootable option or device was found. BdsDxe: Press any key to enter the Boot Manager Menu.按任意键后进入 Boot Manager 菜单Please select boot device: EFI Firmware Setup ^ and v to move selection ENTER to select boot device ESC to exit这表明固件从 SEC → PEI → DXE → BDS 全流程正常执行。7. 常见问题Q1:make tbuild失败提示 “Unable to open makefile”原因系统 PATH 中的 Embarcaderomake.exe优先于 GNU make。解决复制 Strawberry Perl 的gmake.exe为make.exe并确保GCC_HOST_BIN指向C:\Strawberry\c\bin\。Q2:iasl未找到原因RamDiskDxe 等模块需要 iasl 编译 ACPI 表。解决从 ACPICA GitHub Releases 下载iasl-win-*.zip解压后将iasl.exe放入BaseTools\Bin\Win32\。Q3:HOST_ARCH is not defined原因BaseTools 的header.makefile无法自动检测 host 架构。解决编译时显式传入set HOST_ARCHX64。Q4: Pccts/antlr 编译失败ccnot found原因Pccts 的 makefile 默认使用cc而非gcc。解决编译时设置set CCgcc和set CXXg。Q5: QEMU 报错 “requires 67108864 bytes, pflash0 provides 3145728 bytes”原因QEMUvirt机器的 pflash 设备要求 64 MB 镜像。解决用零字节将.fd文件填充到 64 MB见第 6.1 节。Q6: QEMU 不支持 TPM-tpmdev: invalid option原因QEMU 在 Windows 平台上不支持 TPM 后端meson.build中限制host_os ! windows。解决固件端 TPM 2.0 模块已编入.fd。如需验证 TPM 功能需在 Linux 环境使用 QEMU swtpm。8. 目录结构参考E:\code\edk22508Full\ ├── ArmVirtPkg\ # ArmVirt 平台包 │ ├── ArmVirtQemu.dsc # 平台描述文件构建入口 │ ├── ArmVirtQemu.fdf # Flash 描述文件FD 布局 │ └── ArmVirtQemuFvMain.fdf.inc # FVMAIN 内容定义 ├── BaseTools\ │ ├── Bin\Win32\ # 编译后的 C 工具 iasl.exe │ ├── Source\C\ # C 工具源码 │ └── Source\Python\ # build 系统 Python 脚本 ├── Conf\ │ ├── target.txt # 构建目标配置 │ ├── tools_def.txt # 工具链定义 │ └── build_rule.txt # 构建规则 ├── Build\ │ └── ArmVirtQemu-AARCH64\ │ └── RELEASE_GCC5\ │ ├── AARCH64\ # 编译中间产物 │ └── FV\ │ ├── QEMU_EFI.fd # ★ 主固件 (3MB) │ └── QEMU_VARS.fd # ★ 变量存储 (768KB) └── build_armvirt.bat # 一键构建脚本增加一张带有电池功能的截图看起来Windows On ARM的还可以