尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

从BIOS到UEFI与EDK2:开源固件生态全解读

从BIOS到UEFI与EDK2:开源固件生态全解读 1. 从 BIOS 到 UEFI固件世界的分水岭先交代一下背景。我入行那会儿PC 固件的主流还是 BIOS也就是 Basic Input Output System。那时候调一台服务器的启动问题最常见的手段就是拔插内存、扣电池、清 CMOS然后盯着 POST 自检的嘀声和屏幕上的错误码判断故障点。后来 UEFI 大规模铺开整个排查逻辑、开发思路、生态玩法全变了。说实话刚从 BIOS 切到 UEFI 那阵子很多老工程师是有点不适应的——因为 UEFI 不是简单换了个界面而是把固件从底层汇编逻辑升级成了一套完整的、可编程的、模块化的运行环境。这篇文章我想认真聊一聊 UEFI 的来龙去脉、EDK2 的现状以及整个开源固件生态的格局。适合三类人看一是刚入门做固件开发、想知道 EDK2 该从哪里下手的朋友二是做系统集成、运维或者工控的老手经常碰到 UEFI 相关的启动问题想弄个明白三是对 BIOS 魔改、固件定制、开源方案感兴趣想了解这个圈子究竟有哪些可玩的工具和路线。先抛几个核心结论后面逐一展开UEFI 不只是图形化 BIOS它是一套操作系统和固件之间的标准接口规范定义了启动服务、运行时服务、协议驱动等一整套机制。EDK2 是 Intel 主导的开源 UEFI 实现目前几乎所有主流主板、服务器、嵌入式平台的固件底层都直接或间接用它。开源固件生态不是只有 EDK2还有 coreboot、U-Boot、TianoCore 分支、Slim Bootloader 等各有各的主场。UEFI 看起来万能但在兼容性、安全启动、CSM 支持、NVMe 引导、固件回滚这些实操环节上坑一点都不比 BIOS 少。从一个实际场景切入为什么现在还有人问Supermicro 主板不支持 UEFI 固件如何处理这种问题其实不是 Supermicro 不支持 UEFI而是有些老款板子默认关闭了 UEFI 引导选项或者出厂 BIOS 版本过旧导致 NVMe 盘、UEFI 启动盘识别不到。这类问题背后反映的是很多用户对 BIOS 和 UEFI 的边界认识不够清晰。所以这一篇我把能从 BIOS 讲到 EDK2再把开源固件生态盘一遍尽量减少信息差。2. UEFI 到底是什么规范、运行时、启动服务2.1 不是界面升级是接口标准很多人以为 UEFI 就是鼠标可以点的 BIOS 设置界面这个理解太浅了。UEFI 全称 Unified Extensible Firmware Interface统一可扩展固件接口本质上是一套由 UEFI Forum 维护的公开规范。它规定了固件和操作系统之间的接口怎么定、启动过程分成几个阶段、固件如何向 OS 提供服务和数据。类比一下BIOS 时代固件和 OS 之间基本靠中断向量表和内存约定来通讯整个体系是封闭的、按 Intel x86 的硬件思路写死的。而 UEFI 更像是一套操作系统之前的小型操作系统——固件上电后先初始化 CPU、内存、芯片组和外设然后加载 UEFI 驱动和应用程序最终把控制权交给 bootloader 或 OS。这个过程有明确的分阶段状态也有一套标准协议可供调用。因此UEFI 的价值不止是被动地引导系统它可以让固件开发者写出跑在固件层面的小程序比如 EFI Shell、诊断工具、固件更新器、启动管理器甚至硬件测试程序。这也是为什么 UEFI 规范出来后Intel 能推出 EDK2 这样一套完整源码级实现因为整个体系本来就是按可编程平台设计的。2.2 启动流程七阶段理解 UEFI 启动流程是解决一切 UEFI 引导问题的前提。标准流程大致可以分为几个阶段我习惯简化为SECSecurity上电后第一段代码负责验证后续固件卷的可靠性是信任链的起点。PEIPre-EFI Initialization极简环境初始化 CPU、内存控制器找到内存后就为 DXE 阶段准备资源。DXEDriver Execution Environment核心驱动环境加载大量 UEFI 驱动枚举 PCI、USB、SATA、NVMe 等设备也是我们平时看到主板 Logo 前最耗时的部分。BDSBoot Device Selection启动设备选择按 BootOrder 变量查找引导项尝试加载 OS 引导器。TSLTransient System Load短暂系统加载阶段通常是 bootloader 或 EFI Shell。RTRuntime进入操作系统后固件部分服务以运行时服务的形式继续存在比如 SetVariable、GetTime、ResetSystem 等。ALAfter Life系统关机或休眠后的一些收尾操作。这套流程看起来复杂但实际开发中 EDK2 已经把这些阶段的框架搭好了我们要做的大多是往对应阶段里塞模块、改配置、加驱动。2.3 CSM、Secure Boot、BootOrder 这些概念再解释几个被问烂的术语CSMCompatibility Support Module兼容性支持模块是 UEFI 固件里用来兼容传统 BIOS 引导方式Legacy Boot的翻译层。很多主板关闭 CSM 后无法引导传统 MBR 格式的 Windows 7就是这个原因。现代 UEFI 固件正在逐渐移除 CSM纯 UEFI 环境是趋势。Secure Boot安全启动利用证书链验证引导加载程序签名防止启动阶段被植入恶意代码。Windows 11 强制开启但很多 Linux 发行版和自制工具链会因此翻车。BootOrder / Boot####NVRAM 中的变量记录启动顺序和每次引导项的具体路径例如FS0:\EFI\BOOT\BOOTX64.EFI。很多引导问题说白了就是 BootOrder 被打乱或者引导项指向了不存在的设备路径。实际排查中我常用的命令是efibootmgrLinux 下或者 EFI Shell 里的bcfg命令可以快速查看和修改 BootOrder、BootNext 等变量。之前帮朋友修一台 ZBook 17 G2 卡 BIOS 的问题最后就是用 EFI Shell 清掉了坏的启动项才救回来这个后面细说。3. EDK2UEFI 的参考实现也是事实标准3.1 EDK2 和 TianoCore 的关系EDK2 的全称是 EFI Development Kit II是 Intel 开源的 UEFI 固件开发套件。它由 TianoCore 项目托管项目地址就是 GitHub 上的 tianocore/edk2许可证主要是 BSD-2-Clause和部分子模块采用其他宽松协议。为什么说 EDK2 是事实标准因为目前主流主板厂商华硕、技嘉、微星等的 BIOS/UEFI 固件底层基本都是基于 EDK2 或者其衍生分支定制出来的只不过厂商层层的 UI、logo、驱动、微码都是闭源的最终用户看不到源码。服务器领域AMI、Insyde、Phoenix 这些固件方案商的产品内核也大量吸收了 EDK2 的框架和代码。所以如果你在招聘网站看到BIOS 开发工程师大概率要求就是熟悉 EDK2、UEFI 规范、C 语言、x86 架构、PCIe/USB 驱动开发这些。这个岗位的门槛不算低但整个知识体系相比传统 BIOS 时代清晰太多了因为源码是开放的。3.2 EDK2 的核心目录结构新手刚拿到 EDK2 源码会懵。我建议先看几个关键目录MdePkg定义了 UEFI 规范对应的头文件、基础数据类型、协议接口是所有模块都要依赖的基础包。MdeModulePkg核心实现模块包括 Boot Manager、Variable 服务、PCI Host Bridge、串口终端、NVM Express 驱动等。UefiCpuPkgCPU 相关的初始化、MP 服务、SMM 通讯、Microcode 更新等。ShellPkgEFI Shell 的实现和命令集合调试固件必备。OvmfPkg面向 QEMU/KVM 虚拟机的 OVMF 固件是学习 EDK2、调试 UEFI 应用程序最友好的切入点。NetworkPkg / HttpBootPkg网络协议栈、PXE、HTTP Boot 相关。SecurityPkgSecure Boot、TPG 测量、密码管理等安全相关模块。IntelFsp2Pkg / IntelFsp2WrapperPkgFSPFirmware Support Package封装coreboot 和 EDK2 混合方案里的关键。对于学习顺序我推荐先跑 OvmfPkg 在 QEMU 上启动一个 UEFI 虚拟机然后用 EDK2 写一个最简单的 UEFI Application比如打印 Hello UEFI再慢慢深入了解 DXE 驱动。3.3 EDK2 环境的搭建不要被工具链吓倒这里分享一下当前2025 年前后比较稳的 EDK2 环境搭建步骤基于 Windows 11 WSL 或 Linux 都适用。步骤如下安装依赖工具以 Ubuntu/Debian 为例sudo apt update sudo apt install -y build-essential git uuid-dev nasm python3 python3-pip拉取 EDK2 源码和子模块git clone https://github.com/tianocore/edk2.git cd edk2 git submodule update --init --recursive设置环境变量并激活编译环境source edksetup.sh编译 BaseTools这是编译固件和驱动必需的二进制工具集make -C BaseTools配置目标平台。最方便的方式是直接编译 OvmfPkg也就是 QEMU 用的 UEFI 固件build -a X64 -p OvmfPkg/OvmfPkgX64.dsc -t GCC5 -b DEBUG编译产物一般在Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd把它直接丢给 QEMU 就能用qemu-system-x86_64 -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -m 2048 -hda test.img我在实际使用中最常用的是编译一个带 Shell 的 OVMF 固件然后启动到 UEFI Shell去调试变量、协议、设备路径比自己脑补一百遍都有效。3.4 EDK2 开发写一个最小 UEFI Application很多想转固件开发的朋友问EDK2 学的第一步是什么。我的建议是不要去看大而全的驱动源码先写一个 Shell 下能跑的 App。方法如下在 edk2 目录下新建一个MyHelloPkg结构类似MyHelloPkg/ ├── MyHelloPkg.dec ├── MyHelloPkg.dsc └── Hello/ ├── Hello.c ├── Hello.infHello.c 里写#include Uefi.h #include Library/UefiLib.h #include Library/UefiApplicationEntryPoint.h EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { Print (LHello UEFI World!\r\n); return EFI_SUCCESS; }Hello.inf 如下[Defines] INF_VERSION 1.29 BASE_NAME Hello FILE_GUID 8D1C9B6C-8F4A-4E6B-9D2A-1E3D5F7A9B2C MODULE_TYPE UEFI_APPLICATION VERSION_STRING 1.0 ENTRY_POINT UefiMain [Sources] Hello.c [Packages] MdePkg/MdePkg.dec [LibraryClasses] UefiLib UefiApplicationEntryPoint然后在 MyHelloPkg.dsc 里加上[Components] Hello/Hello.inf再用 build 命令编译生成的.efi文件拷贝到 UEFI Shell 环境执行就能看到输出。别看只是 Hello World跑通它意味着你理顺了 INF/DSC/DEC 三件套的关系、掌握了 EDK2 的构建流程这是所有固件开发的地基。4. 固件生态版图coreboot、U-Boot、Slim Bootloader 与其他分支EDK2 是 UEFI 家族里的绝对主力但整个开源固件生态并不只有它。我自己做过几个项目把相关的方案也摸了一遍下面按应用场景分开讲。4.1 coreboot快速启动的极简派coreboot以前叫 LinuxBIOS是另一个极具影响力的开源固件项目主打极简快速启动。它的设计哲学和 EDK2 完全相反EDK2 是完整 UEFI 环境功能全、代码量大、编译产物也大coreboot 则是最小化的固件启动方案尽量只做硬件初始化和引导加载这一件事然后快速把控制权交给 payload如 SeaBIOS、U-Boot、Linux 内核。coreboot 在上电后依次执行 bootblock、romstage、ramstage 和 payload其中对内存初始化、CPU 微码加载、北桥/南桥初始化都有非常具体的支持。很多 ChromeOS 设备用的就是 coreboot因为它可以让 Chromebook 做到秒级开机。服务器领域部分 OpenBMC 板子也配合 coreboot 使用。如果你感兴趣最大的门槛是 mainboard 目录下针对具体主板的代码支持度。coreboot 不像 EDK2 那样通用——它需要针对每块板子做移植。好在社区维护了一批主流主板比如 QEMU 的 q35、各类 Intel NUC、部分 Supermicro X11 系列跑起来不算太难。4.2 U-Boot嵌入式领域的老大哥如果你做嵌入式开发尤其是 ARM 平台那 U-BootDas U-Boot几乎绕不开。虽然它也支持 x86、RISC-V但主战场还是 ARM 的 SoC 平台。U-Boot 提供 U-Boot SPLSecondary Program Loader做极早期初始化然后加载主 U-Boot最终引导 Linux 内核。它和 UEFI 的关系是较新版本的 U-Boot 实现了 UEFI 接口的子集可以加载 UEFI 应用也可以用 UEFI 方式启动 GRUB 和 Windows。这个设计很聪明在嵌入式板子上前期用 U-Boot 特有的 FIT image 格式或者脚本方式引导后期想兼容统一启动流程时就能切到 UEFI 模式。我在一些 RK3588 的开发板上试过CONFIG_CMD_BOOTEFI开启后可以用 UEFI Shell 和 UEFI 启动项体验已经比较接近 x86 平台了。4.3 Slim BootloaderIntel 对精简启动的尝试Slim Bootloader 是 Intel 开源的精简启动固件方案定位介于 coreboot 和 EDK2 之间。它不像 EDK2 那么重但又支持 UEFI 接口能为嵌入式、IoT 设备提供快速启动能力。它采用 Stage 1/Stage 2 的分段设计Stage 1 负责 CPU/内存/芯片组的最小初始化Stage 2 加载 UEFI payload。不过近几年社区活跃度比 coreboot 低一些项目迭代不是那么快。4.4 其他值得关注的方向TianoCore 的 EDK2 还有几个衍生分支例如 edk2-platforms 里包含了大量 SoC/开发板的支持代码很多 NXP、AMD、Rockchip 平台的 UEFI 支持都从这里开始。Project Mu 是微软主导的 EDK2 衍生分支目标是更现代、模块化、更容易集成到 Windows 设备中微软自家的 Surface 固件据说就有一部分基于它。UEFI 固件更新方面有 fwupd 和 LVFSLinux Vendor Firmware Service。Linux 下通过fwupdmgr update就能刷很多设备的固件这套机制如今已经做成行业标准惠普、戴尔、联想都在往里推固件。开源硬盘固件方向OpenBMC 是 BMC基板管理控制器固件的开源实现用于服务器远程管理而像 OpenSSD、LightNVM 这类偏存储的社区也在尝试固态硬盘固件开源化。做一张表帮大家快速对比项目主要平台启动方式适用场景上手难度EDK2x86, ARM, RISC-VUEFI主板/UEFI固件/服务器/虚拟化中高corebootx86, ARM自定义payloadChromeOS、快速启动、嵌入式中高U-BootARM为主x86/RISC-VU-Boot脚本/EFI嵌入式、开发板、路由器中Slim Bootloaderx86UEFI payloadIntel嵌入式/IoT中OpenBMCBMC硬件Linux服务器远程管理中高5. 实操现场UEFI 引导疑难杂症与排查技巧这部分说点真正的干货。常年和 UEFI 打交道业务里最常见的不是固件怎么开发而是板子起不来的问题。我按排查顺序整理几类典型场景每个都是我自己踩过或帮人解决过的。5.1 问题一UEFI 引导盘做成 FAT32 还是 NTFS这个问题几乎每周都会出现。先说结论UEFI 规范要求 ESPEFI System Partition必须使用 FAT12/FAT16/FAT32 文件系统其中 x86_64 平台的引导文件路径通常是\EFI\BOOT\BOOTX64.EFI。大多数主板虽然也能从 NTFS、甚至 exFAT 的 U 盘引导但这属于厂商自己加了驱动和兜底逻辑不是规范保证的行为。我建议做 UEFI 启动盘一律用 FAT32分区表用 GPT引导文件放在 ESP 里。如果你在做一个 Windows 10/11 安装盘镜像超过 4GB单个 FAT32 分区放不下 install.wim那就用双分区方案——一个小 FAT32 分区放引导文件另一个数据分区放镜像或者用 Rufus 等工具自动处理。注意如果 U 盘是 FAT32但主板死活不识别先检查 Secure Boot 是否开启再把 CSM 关掉。FAT32 本身没问题问题十有八九在启动项路径或者分区表上。5.2 问题二BIOS 能识别硬盘但 PE 里看不到硬盘这个案例很典型。一块盘在 BIOS 界面状态正常进 PE 却看不到盘。我之前遇到过一块盘在 BIOS 里显示为Unconfigured Good其他盘显示Online系统里完全看不到。这是 RAID/HBA 卡的磁盘状态问题不是 UEFI 的锅。处理思路是进 RAID 卡的配置界面通常是 CtrlR 或 CtrlC把Unconfigured Good的盘手动配置为 JBOD 或者加入 Array。如果这块盘以前是 RAID 成员盘现在变成 Unconfigured那可能是阵列信息丢失需要重新 Import Foreign Configuration。这里有个经验Unconfigured Good 不等于坏盘千万不要一看没状态就急着做 Secure Erase先把 Foreign 配置导回来。如果是 NVMe 盘在 PE 里看不到优先检查有没有注入 NVMe 驱动。老版本的 WinPE 不带 NVMe 驱动需要手动dism注入驱动到 winre.wim 或 boot.wim 中。5.3 问题三BIOS 能检测到硬盘PE 看不到硬盘续再补一个常见原因SATA 模式设置错误。如果 BIOS 里 SATA 模式从 AHCI 改成了 RAID 或者 IDE个别 PE 没有对应驱动就认不到盘。解决方案是打开 BIOS把 SATA Mode 切回 AHCI。如果系统是 Windows 且已经安装在 RAID 模式下随便切换会导致系统蓝屏需要先改注册表再切或者用 PE 里注入 AHCI 驱动。另一个可能性是磁盘接口本身的问题。之前修一台戴尔老服务器BIOS 里能看到盘但进系统就丢盘后来发现是背板供电不稳。硬件问题往往被误判成固件问题这点必须留个心眼。5.4 问题四Legacy/BIOS Boot of UEFI-Only Media启动时提示error: BIOS/legacy boot of uefi-only media言下之意是你开启了 Legacy 启动模式CSM但引导介质只有 UEFI 引导文件。只需要关掉 CSM / 开启 UEFI Only或者在 BIOS 启动选项里改成 UEFI 引导即可。这个报错常见于新主板 老安装工具做的 U 盘。很多装机工具默认只拷了 UEFI 启动文件却没做 Legacy 兼容。反过来也一样如果介质是传统 MBR 引导主板只开 UEFI就会提示No bootable device。我的建议是能统一到 UEFIGPT 就统一2025 年没理由再用 Legacy MBR 装新系统。除非是老旧 Windows 7 或者特定工控软件否则 CSM 这个东西能关就关不仅多一层攻击面还拖慢启动速度。5.5 问题五ZBook 17 G2 卡 BIOS 的处理这个案例印象很深。朋友的 ZBook 17 G2 开机后卡在 HP Logo按任何键都没反应BIOS 基本进不去。排查过程如下先断开所有外设包括 USB 键盘鼠标、扩展坞、外接显示器只保留电源开机看能否进 BIOS。外设短路或引导冲突会导致固件初始化过程卡死。拔掉 CMOS 电池并断开交流电源等 30 秒后装回。这个方法对很多 HP 机型都有效等效于强制恢复默认设置。如果 BIOS 可以进检查 Boot Security 里的 Secure Boot 和启动项清空所有 BootOrder重启后让固件重新扫描。如果还是卡 Logo用烙铁松香法或者夹具夹住 Flash 芯片通过编程器直接刷写备份的 BIOS bin 文件。ZBook 17 G2 的 BIOS 芯片是 8MB 的 SPI Flash常见型号 W25Q64 或者 MX25L6445E。最后这台机器是刷 BIOS 解决的。这类问题的核心是卡 BIOS 不等于主板坏了优先用最小系统法和恢复默认设置排除实在不行用编程器救砖。不过用编程器刷机有风险操作前必须备份原固件。5.6 问题六D 大魔改 BIOS 到底是什么下面聊一个圈内话题。网上经常能看到D 大魔改 BIOS尤其是一些老主板配合新 CPU 或者 NVMe 引导的场景。所谓魔改 BIOS本质是在原厂固件基础上做定制修改加入最新 CPU 的微码、修改 VBIOS/GOP 驱动、解锁隐藏 BIOS 选项、嵌入 NVMe 引导模块、移除安全启动限制等。典型的应用场景是老主板比如 100 系、200 系芯片组想上志强 E3 v5/v6 或者魔改 ES 版 CPU或者老主板上没有 NVMe 模块想从 NVMe SSD 启动系统。D 大等大神在相关论坛放出魔改 BIOS 工具和成品在特定圈子里非常流行。这里我必须提醒几句第一魔改 BIOS 绕过官方验证存在刷砖、稳定性、硬件损坏风险自行承担第二很多主板厂商不提供后续微码更新用魔改 BIOS 可能导致内存兼容性、功耗调优、S3 休眠等问题第三安全启动被精简后系统更容易被启动级恶意软件攻击。我个人的态度是如果没有特殊需求例如老平台硬上新 CPU尽量用官方 BIOS实在要玩买块支持 drop-in 的二手主板往往比魔改更省心。5.7 问题七UEFI 运行时变量和 NVRAM 故障还有一个容易被忽略的坑NVRAM 空间不足或损坏。UEFI 的 BootOrder、Boot####、Secure Boot 数据库、平台密钥都存在 NVRAM对应 SPI Flash 的某个区域。频繁刷固件、装多系统、误操作设置可能导致 NVRAM 变量空间耗尽或者校验错误现象是固件设置无法保存、启动项丢失、开机后自动进 BIOS、甚至循环复位。处理办法进 UEFI Shell用dmpstore导出所有变量找到体积异常的变量并删除。用bcfg boot dump -b查看所有启动项用bcfg boot rm 序号清理无效启动项。用Reset NVRAM类型工具部分主板固件内置或通过 fwupd 平台复位。如果变量彻底损坏最终手段还是清 CMOS 或者编程器重刷固件。这个问题的诱因之一就是频繁在 Windows 和 Linux 之间切换启动项时BootOrder 被反复写入加上某些厂商固件的变量管理代码有 bug时间久了容易出问题。老实说UEFI 功能越多NVRAM 管理越复杂和 BIOS 时代最后一条指令决定引导谁的简单模型完全是两回事。6. 影响范围UEFI 和开源固件正在塑造什么6.1 对服务器与云计算的塑造在服务器领域UEFI ACPI PCIe 枚举带来的好处是显而易见的。传统 BIOS 在大规模服务器上存在很多不便无法直接通过固件 API 获取丰富的硬件拓扑、难以标准化远程固件更新、启动流程不好定制。UEFI 解决了这些问题让 BMC基板管理控制器可以通过 Redfish/IPMI 标准接口获取固件信息、远程挂载虚拟介质、远程修改启动项。具体到虚拟化场景KVM 用户经常会去下 OVMF UEFI 固件然后在 Libvirt/QEMU 里用 UEFI 模式装 Windows 或 Linux 虚拟机。OVMF 是 EDK2 的一个平台包换句话说虚拟化领域的基础固件也深度依赖 EDK2。如果你在virsh edit里看到loader typepflash的配置那就是 UEFI 固件在最底层工作。6.2 对 PC DIY 和系统安装的影响UEFI 对普通用户最大的影响其实是启动方式的选择。Windows 11 强制要求 UEFI Secure Boot TPM 2.0这直接导致大量老机器被挡在系统要求之外。虽然网上有各种绕过方案但从行业角度看微软通过固件要求倒逼供应链升级确实推动了整个生态的规范化。同时电脑是 UEFI 还是 Legacy 启动模式成为装机时的高频问题。最简单的判断方法开机进 BIOS Setup查看 Boot Mode 选项通常是 UEFI/Legacy/Compatible 等。Windows 下按 WinR 输入msinfo32查看 BIOS 模式一栏如果显示UEFI就是 UEFI 模式。Linux 下执行[ -d /sys/firmware/efi ] echo UEFI || echo Legacy。另外用 U 盘启动装系统时UEFI 模式要求 U 盘分区表为 GPTLegacy 模式常见 MBR很多装机失败是因为 U 盘格式和主板启动模式不匹配。6.3 对固件安全的影响UEFI 的安全模型比 BIOS 复杂得多也严格得多。Secure Boot 用 PK平台密钥、KEK密钥交换密钥、db签名数据库三级结构管理可信任的引导镜像平台固件在 SEC 阶段就建立信任根。加上 Intel Boot Guard / AMD Platform Secure Boot 等硬件信任链方案固件层面对抗 Bootkit 的能力大幅提升。当然有安全设计就有安全研究。固件漏洞如 LogoFAIL、Spectre/Meltdown 的微码侧信道屡见不鲜EDK2 的历史 CVE 也不少。做固件安全的朋友会去研究 UEFI Runtime 服务的内存保护、SMMSystem Management Mode隔离、变量空间溢出等方向。开源固件的好处是代码可审计问题能被更快发现和修复这也是我坚定支持开源固件生态的原因之一。6.4 对 ARM/RISC-V 生态的渗透很多人以为 UEFI 是 x86 的专利其实不是。ARM 平台的服务器如 Ampere Altra、华为鲲鹏服务器、部分 AWS Graviton 实例也支持 UEFI 引导很多是基于 EDK2 定制的。RISC-V 平台同样有 UEFI 规范移植OpenSBI U-Boot UEFI 的组合正在成为 RISC-V Linux 启动链路的常见选择。嵌入式领域U-Boot 的地位在短期内难以撼动但 UEFI 正在从服务器和 PC 向边缘计算设备渗透。比如一些网络设备、工业控制器采用 EDK2 作为固件基础就是为了获得标准化的 ACPI 支持和 Windows/Linux 双启动能力。开源固件生态的多点开花对上下游链条是好事。7. 实战经验与避坑清单最后把我个人操作中的体会和教训汇总一下都是文档里不容易翻到的细节。7.1 刷固件之前永远先备份不管是用官方 BIOS 刷新工具、编程器、还是魔改 BIOS第一步永远是备份当前固件。先备份到 U 盘、BMC 远程镜像或者用编程器把 Flash 内容读出来存好。没有备份就刷固件一旦刷坏可能连官网原版都找不回来。备份方式推荐三种BIOS Setup 自带刷新工具通常支持读取当前固件功能。Linux 下可用flashrom读取 SPI Flash。编程器直接接线读取是最可靠兜底方案但需要拆卸设备。7.2 修改 UEFI 启动项要谨慎Linux 下efibootmgr的常用操作# 查看当前启动项 efibootmgr # 添加一个启动项 efibootmgr -c -d /dev/nvme0n1 -p 1 -L Ubuntu -l \\EFI\\ubuntu\\shimx64.efi # 删除指定启动项 efibootmgr -B -b 0001 # 修改启动顺序 efibootmgr -o 0000,0002,0001注意-l参数里 EFI 文件路径是反斜杠并且 EFI 路径之前的\在 Shell 中需要写成\\。如果路径写错启动项虽然存在但实际无法引导。7.3 是否需要用编程器刷 BIOS编程器刷机不是万能的但确实是最后救命的稻草。常用的编程器有 CH341A、RT809H、土豪金烧录器等。用 CH341A 刷 8MB 的 SPI Flash 大约需要 1 到 2 分钟速度不算快但稳定。刷的时候要注意确认 Flash 芯片型号和电压不要乱接。WSON/QFN 封装最好用烧录座别硬飞线。刷写前确保原始固件完整备份并且校验和一致。部分主板的 BIOS 文件末尾带有 Descriptor 和 GBE 区域用编程器全片写入时不能只写 BIOS 区要整片写入否则可能造成 ME 或网卡 MAC 丢失。7.4 遇到固件更新失败怎么办固件更新失败是另一个高发问题。常见原因有电源波动或电池电量不足刷写中途断电。BIOS 更新工具拒绝更新因为当前版本和更新版本不匹配。扇区擦除失败或 Flash 芯片老化导致写入异常。Secure Boot 或写保护开启阻断固件更新。处理思路先接上交流电源关掉所有不必要的安全设置用官方工具重新尝试更新如果系统内刷新不成功尝试从 UEFI Shell 执行capsule.nsh脚本或 EFI 刷新工具再不行就只能编程器直刷。注意固件更新后首次开机通常很慢因为固件要重新初始化 NVRAM、重建变量这时候不要急着断电。7.5 从固件开发角度看未来最后说说我对这个方向的感觉。传统 BIOS 时代固件开发是很封闭的圈子工具链私有、资料稀少、对新手极不友好。EDK2 开源后整个行业的知识门槛已经大幅降低。仔细读过 EDK2 的代码会发现它虽然体积庞大但模块划分相当清晰几乎每一个硬件初始化模块都有对应的平台包示例。对新人来说从 OvmfPkg 开始、在 QEMU 里调试是最友好的一条路。开源固件生态的未来我认为会往这几个方向走安全启动和可测量启动会越来越普及TPM 2.0 会成为基础配置而非选配。固件更新的规范化程度会提高LVFS/fwupd 模式会从 PC 向服务器、嵌入式领域扩展。UEFI 的轻量化方案会继续发展coreboot U-Boot EDK2 拼接的混合方案会更多。固件供应链安全会得到更多关注源码级开源、构建过程可复现会成为企业选型考量。RISC-V 平台上UEFI 规范和 OpenSBI/U-Boot 的融合仍有大量工作但趋势已经明显。我在实际项目中最大的体会是固件开发不是改几个 register 就行的黑魔法它更像给硬件写第一份基础架构代码需要对 CPU 架构、外设总线、操作系统引导协议都有全局理解。但正因为它难这个领域的护城河才深。如果你有兴趣从 EDK2 开始哪怕只是把 OVMF 在 QEMU 里跑通已经比大多数只会在 BIOS Setup 里点鼠标的人强太多了。最后再分享一个实用小技巧在 UEFI Shell 里查看 ACPI 表、SMBIOS 信息、设备路径、内存映射用的最多的是dmem、devtree、acpi、pci、mm这些命令。第一次接触 UEFI Shell 的朋友先敲help -b把所有命令过一遍再配合 UEFI Shell 规范手册查每个命令的用法很快就能上手。调试固件问题的时候UEFI Shell 比任何图形界面都直观强烈建议每个做固件相关工作的人都把 Shell 用熟。
返回列表