从BIOS到UEFI:深入解析固件技术栈与EDK2开源实现
2026/9/6 10:25:44 网站建设 项目流程

如果你过去几年装过台式机、刷过主板、或者只是因为 Windows 11 提示“这台电脑的磁盘布局不受 UEFI 支持”而抓狂过,那你一定体会过这种荒谬感:满世界教程都在讲“进 BIOS 设置”,可你按 Del 进去看到的东西,和十年前教材里那张蓝底白字的 BIOS 截图根本不是一回事。它支持鼠标、支持中文、甚至能联网。然后你再去网上下一个“BIOS 升级”文件,后缀是 .cap 或 .bin,却怎么也看不明白里面到底封装了什么。

一个很反直觉的事实是:你的电脑里其实已经没有 BIOS 了——或者说,“BIOS”这个词还在用,但底层那套东西,早就被换成了 UEFI。另一个更反直觉的事实是,UEFI 并不是一个简单的“新版 BIOS”,它是一个运行在计算机最底层的小型操作系统,有自己的驱动模型、自己的加载器、自己的协议栈。而围绕它的开源实现 EDK2,现在几乎成了从服务器到嵌入式设备、从云数据中心到家用主板上都绕不开的固件基础设施。这篇文章想做的事,就是把从 BIOS 到 UEFI 的来龙去脉、固件底层技术栈、以及 EDK2 在开源生态里的位置,按一个固件工程师平时看待问题的方式,拆开讲一遍。

1. 经典 BIOS 的死穴:为什么一套能开机几十年的东西,最后还是被淘汰

很多人会问:BIOS 用了那么多年,不是挺稳定的吗?为什么非要折腾出 UEFI?这个问题的答案,其实要回到 BIOS 出生的年代去看。它的底层设计,是一个为 8086 处理器准备的、运行在 16 位实模式下的程序。1981 年 IBM PC 诞生时,这种设计完全够用,但三十多年后,它变成了制约整个计算机产业向前走的枷锁。

1.1 16 位实模式:被锁死在 1MB 地址空间里的古董

实模式最大的问题是地址空间。16 位处理器通过“段基址:偏移量”的方式寻址,最大只能访问 1MB 内存,其中还要扣除从 0xC0000 到 0xDFFFF 这段留给显卡、RAID 卡、网卡等扩展卡的 Option ROM 空间,实际留给操作系统和应用程序的“常规内存”只有 640KB。

640KB 在 1981 年是巨大资源,放到今天连一张微信聊天截图都装不下。为了在这 640KB 里塞进更多东西,BIOS 时代发展出了一套以中断调用为核心的服务模型:Int 10h 管显示、Int 13h 管磁盘、Int 16h 管键盘。操作系统启动时,必须依赖这些中断例程来访问硬件,而一旦进入 32 位保护模式,这套中断机制就用不上了,操作系统只能重新写驱动接管一切。

所以 BIOS 对现代操作系统来说,实际只扮演了“把引导扇区读进来”的角色。那它为什么还要留在系统里?因为硬件厂商需要一个统一标准来让显卡、硬盘在裸机上可见,需要一个界面来配置启动顺序、CPU 参数、内存时序。但这一切功能,都被锁死在 16 位实模式这个“蜗牛信箱”里。

1.2 外设驱动依赖 Option ROM,兼容性全是“约定大于配置”

BIOS 时代扩展设备的做法是:设备带着一块 Option ROM,系统启动时扫描 0xC0000~0xDFFFF 区域,找到合法的 ROM 头(0x55AA 标志),就把控制权交给它。听起来很巧妙,但 Option ROM 里的代码是 16 位的、是实模式的、是厂商按自家硬件写的。这意味着三件事:

第一,现代主板要想在 BIOS 模式下用 NVMe 固态硬盘,必须让 NVMe 设备也提供一个扩展开机 ROM,或者主板厂商把 NVMe 驱动集成进 BIOS,在实模式下模拟 IDE/SCSI 接口。这就是网上大量“BIOS 添加 NVMe 模块”魔改教程的根源。

第二,显卡的 Option ROM 不仅要支持 UEFI,还要兼容老的 CSM 传统模式。很多人刷显卡 VBIOS 时纠结该选 GOP 还是 UEFI 版本,就是因为不知道新旧两套体系对显示设备初始化方式的差异。

第三,BIOS 设置项全部存放在 CMOS 里,由一颗靠电池供电的 RTC 芯片维持。所以“拔电池重置 BIOS”这个做法才会成为装机圈的基本常识。也正因为数据存储简单,BIOS 里能保存的设置项很少、很零散,无法支撑现代安全启动所需要的大规模密钥管理。

1.3 没有隔离、没有校验,固件层的恶意代码无法被清扫

BIOS 时代还有一个致命缺陷:安全。BIOS 代码在执行时没有签名校验、没有完整性度量,主板厂商在出厂时烧录一份二进制,之后此后的更新完全依赖“写保护引脚”和“用户自己别乱刷”。2000 年前后有研究者展示过在 BIOS 里植入恶意代码,重装操作系统也无法清除,因为它位于操作系统之下,杀毒软件根本看不见。

近些年的安全研究更是公开了多款主流主板上可被利用的 SMM 漏洞链,攻击者可以在系统最高特权级之外再建立一个不被监控的执行环境。UEFI 的 Secure Boot、Measured Boot、平台密钥体系,本质上就是在回应这些过去三十年都没解决的固件级安全问题——虽然它也远不是完美的。

2. UEFI 的底层逻辑:一台运行在 C 语言世界里的“迷你操作系统”

如果说 BIOS 是写在汇编层面的“小工具集”,那 UEFI 就是一套完整的、面向对象思想驱动的固件平台。它最大的变化不是界面好不好看、支不支持鼠标,而是把固件从“实模式中断服务程序”变成了一套基于函数调用接口、驱动模型、句柄管理的现代软件基础设施。

2.1 按下电源键后的头几十毫秒:SEC 与 PEI

你按下电源键,CPU 从复位向量取到的第一个指令,执行的是 SEC(Security)阶段。这一段代码通常做三件事:建立临时的执行环境、验证下一阶段固件的可信度、把系统带到 PEI(Pre-EFI Initialization)阶段。

PEI 阶段最重要的任务是训练内存。CPU 不知道自己连着多大的内存颗粒、每条 DIMM 的时序参数应该设多少,PEI 代码读取 SPD 数据、配置内存控制器、做内存训练,然后把临时 RAM(Cache-as-RAM)里的数据迁移到真正的内存中。这也是为什么硬件发烧友会看主板的 Debug 灯和 POST 码:Q 码从 15 跳到 32、55、62 的过程,就是 PEI 阶段在一步步初始化芯片组、PCH、内存和 PCIe。

在笔记本平台上,PEI 阶段还会做一件容易被忽略的事:和 EC(Embedded Controller)通信。EC 负责键盘扫描、风扇调速、电池充放电,BIOS/UEFI 需要读 EC 的寄存器来判断电池状态、温度,甚至通过 ACPI 给它下发命令。不少笔记本启动故障,查到最后是 EC 固件和 UEFI 固件之间的握手没完成。

2.2 DXE:固件的“设备管理器”和“服务注册表”

内存就绪后,固件进入 DXE(Driver eXecution Environment)阶段,这是整个 UEFI 最核心的部分。DXE 驱动以模块化方式存在,每个驱动在初始化时向一个全局的 Handle Database 注册自己支持的 Protocol——你可以把它理解成一个运行在固件层的“服务注册表”:某段代码声明“我实现了 Graphics Output Protocol”,另一个驱动就可以通过查找这个 Protocol 的 GUID 拿到它的接口指针,调它的函数绘图。

这套设计解决了 BIOS 时代最痛的问题:不再靠内存地址约定和中断向量通信,而是靠接口抽象。固件里插多少设备、装多少驱动,全部通过 GUID 和 Handle 动态管理。新增一个 PCIe 设备,就多加载一个对应驱动;没有设备,相关驱动就不需要执行。

DXE 阶段还会初始化 ACPI 表、MPS 表、SMBIOS 表,这些表是操作系统启动后查询硬件拓扑、电源管理信息的依据。也就是说,UEFI 固件不只是“启动加载器”,它还在内存里留下了一整套数据结构,交给操作系统做运行时管理和设备发现。

2.3 BDS 与 UEFI Shell:启动项的选择不再靠“79 个字符的字符串”

BIOS 时代,启动顺序就是 CMOS 里存的一串硬盘/光驱次序,最多再支持个快捷键调出启动菜单。UEFI 的 BDS(Boot Device Selection)阶段则更接近一个操作系统引导器:它读取 NVRAM 变量中的 BootOrder、Boot0000、Boot0001 等条目,每个启动条目指向一个 EFI 应用程序,可以是 Windows Boot Manager、GRUB、或者是 UEFI Shell。

这个设计的延展性很强。你可以往 NVRAM 里加一条启动项指向一个诊断工具,诊断工具跑完再自动跳回硬盘。也可以启动进入 UEFI Shell,在里面敲命令:map -r映射文件系统,dh查看句柄和协议,drivers列出所有已加载驱动,bcfg管理启动项。很多主板厂商隐藏的“刷写工具”“内存测试工具”,本质就是往固件里塞了几个 UEFI 应用程序,你只是在界面里看不到而已。

也因此,UEFI 的界面可以做得很花哨:图形化菜单、鼠标拖拽、中文字体渲染,都不再是技术障碍。门槛不在显示能力,而在于各家 OEM 愿不愿意投入人力去做一套好用的交互。

2.4 Runtime Service:关机之后,固件为什么还在“干活”

DXE 和 BDS 阶段跑完,控制权交给操作系统,但这不意味着固件可以退休了。UEFI 留了一组 Runtime Services 常驻内存,等 OS 接管主内存后,以虚拟地址映射的方式继续提供:SetVariable 用来写 NVRAM 变量、GetTime 读取实时时钟、ResetSystem 实现软重启和关机、UpdateCapsule 用于固件升级。

这些服务里最容易出 bug 的就是 Runtime 阶段的变量访问。因为运行时固件代码要和操作系统内核并存于内存中,还要处理物理地址和虚拟地址的映射切换,一处映射写错,系统休眠唤醒就蓝屏,或者bcdedit修改引导配置后重启不生效。固件工程师排查这类问题,用的工具往往是 WinDbg 和串口日志,而不是普通程序员熟悉的 IDE。

3. 开源固件版图:EDK2、coreboot、LinuxBoot 的三国杀

说到 UEFI 的生态,绕不开三支力量:Intel 主导的 EDK2/TianoCore,主打“最小初始化”的 coreboot,以及企业级场景里越来越活跃的 LinuxBoot。看懂它们的定位区别,也就看懂了整个开源固件生态的格局。

3.1 EDK2/TianoCore:凭什么成为事实标准

EDK2 的官方名字是 UEFI Development Kit 2,由 Intel 在 TianoCore 项目下开源维护。它实现了完整的 UEFI 2.x 规范、PI 规范,以及大量平台驱动、文件系统、网络栈、安全启动组件。如果你买了一台品牌机,它的 UEFI 设置界面底下十有八九写着“AMI Aptio”或“Insyde H2O”——这些商业固件,大半代码都是从 EDK2 衍生出去的。

EDK2 的价值不只是代码,它更确立了一套固件工程的组织方式:MdePkg 是公共头文件和基础库,MdeModulePkg 是通用模块,OvmfPkg 是专门为 QEMU/KVM 虚拟机准备的固件,EmulatorPkg 可以把 UEFI 环境编译成一个普通应用程序在宿主机上跑。这套结构让“学习 UEFI 开发”变得有路径可走,而不是面对一团寄存器。

Intel 后来开放了 FSP(Firmware Support Package),把内存初始化和 CPU 初始化的闭源二进制以固定接口提供给 EDK2 平台代码调用,进一步拉低了做一块主板的门槛。现在的开源主板项目,比如 Dasharo、System76 固件,基本都是 EDK2 + FSP 的组合。可以这么说,只要你想做一块“真能跑操作系统”的 x86 主板固件,EDK2 就是最省事的起点。

3.2 coreboot:不把所有事都干完,是一个很好的设计哲学

coreboot 的前身是 LinuxBIOS,它换了个思路:固件只做必须做的硬件初始化(CPU、内存、芯片组、PCIe 枚举),做完之后立刻把控制权交给一个 payload(负载)。这个 payload 可以是 U-Boot、Deepin 内核对 payload、UEFI 的 iPXE、SeaBIOS,也可以是 coreboot 自己的引导器。

因为不做完整的 DXE/BDS 流程,coreboot 的启动速度极快:在很多 x86 主板上,从按下电源键到看到 GRUB 菜单只要一两秒。Chromebook 是它最成功的量产案例,Google 要求固件尽可能简洁、可审核、更新快,于是干脆绕开了 UEFI 那套重量级框架。

coreboot 的代价是不提供像 UEFI 那样丰富的运行时服务:没有标准化的 Secure Boot 变量存储,没有统一 Capsule 升级接口,很多功能要由 payload 层面补全。所以它在嵌入式设备、网络设备中很受欢迎,但在桌面 PC 和服务器市场,和 EDK2 相比仍属于小众选择。

3.3 LinuxBoot:把 Linux 塞进固件,企业级场景的“激进派”

LinuxBoot 的玩法更极端:它把一个小型 Linux 内核直接编译成固件的一部分,作为 coreboot 的 payload 或替代传统 UEFI 的 DXE 驱动环境。Linux 内核里有最丰富的驱动、文件系统支持、网络协议栈,拿来当固件用,意味着服务器的存储控制器、网卡、NVMe 磁盘都可以用成熟的内核驱动来初始化,而不用依赖 BIOS 厂商为每个新硬件单独写固件驱动。

这个方案在 Facebook、Google 的服务器农场里落地过,好处是启动极快、可维护性极强、固件里的逻辑可以直接用 Linux 用户态工具去调试。缺点也很现实:LinuxBoot 在 PC 领域没法普及,因为消费级主板需要标准化的 UEFI 安全启动链路和 OEM 的认证支持,LinuxBoot 在这套合规体系里很难嵌入。

3.4 三者的关系不是替代,而是互补

很多初学者会问:选 EDK2 还是 coreboot?这个问题本身就不太成立。现实中它们经常共存:coreboot 做早期初始化,然后用一个 UEFI payload(比如 coreboot 社区维护的 EDK2 port)把 UEFI 运行时环境建立起来;LinuxBoot 则会让 UEFI 只保留最必要的 DXE 驱动,把启动权尽早交给 Linux。

固件行业真正缺的不是“哪一个统一天下”,而是可组合、可裁剪、可验证的模块化方案。EDK2、coreboot、LinuxBoot 三者各有位置,将来更可能的趋势是相互融合:coreboot 吸收 EDK2 的驱动模型,EDK2 也在反向学习 coreboot 的精简思路。你在热搜里看到的“固件差分升级开源项目”,某种程度上也是这个融合趋势的产物。

4. EDK2 现状观察:从代码结构到开发者生存指南

作为工程实践者,我更关心 EDK2 现在到底好不好用、坑在哪。下面这些是这两年实际写 EDK2 平台代码、调 QEMU 固件时攒下来的经验,不是什么官方文档会写透的东西。

4.1 源码构成:DEC、DSC、INF 三件套

EDK2 里所有代码组织成“包”(Package),每个包下面有三种描述文件:

  • .dec声明这个包里对外暴露的 GUID、Protocol、PPI、PCD。可以理解为包的“对外 API 列表”。
  • .inf是单个模块的构建描述,声明源文件、依赖的库类、入口函数。可以理解为“一个程序单元的 Makefile”。
  • .dsc是平台描述文件,告诉构建工具这个平台要收集哪些模块、用什么编译宏、装配哪些库。可以理解为“整台机器的生产清单”。

这三者的关系很像做饭:DSC 是宴席菜单(今天要做哪些菜),DEC 是食材总库(菜市场里有什么),INF 是每道菜的菜谱(鱼香肉丝怎么炒、放多少盐)。写平台代码时最常见的错误,就是往模块里加了一个库却忘记在 DSC 里声明,结果链接时一堆未定义符号,报了错又不知道去哪找。

建议新手一开始不要扎进真实主板的 DSC 里,先去看 OvmfPkg 和 EmulatorPkg。这两个平台的 DSC 已经把“最小可启动固件”需要哪些模块展示清楚了,比翻规范高效得多。

4.2 构建系统:一个很不“现代”但实用的 Python 套件

EDK2 的构建工具叫 BaseTools,本质上是一套 Python 脚本。命令很简单:

git clone https://github.com/tianocore/edk2.git cd edk2 git submodule update --init make -C BaseTools source edksetup.sh build -p OvmfPkg/OvmfPkgX64.dsc -b DEBUG -t GCC5

但第一次跑通这个流程的人,几乎都会在环境上栽跟头。EDK2 对工具链版本非常敏感,GCC5 这个配置名指的不是 GCC 5.x 版本,而是 EDK2 里一套固定的编译器参数模板;Python 版本、gcc 版本不对,构建过程会报出一些完全看不懂的内部错误。

我踩过的坑是:Ubuntu 22.04 默认的 gcc 12 编译较老版本的 EDK2 时会触发语法告警被人为升级为错误;解决办法是在target.txt里指定一套专门编译固件的交叉工具链,或者直接切到较新的 edk2-stable 分支。EDK2 每个季度发一个edk2-stable202311这样的稳定版本,新手不要追 master,master 经常因为新特性导致 OvmfPkg 编译失败,白折腾一晚上。

4.3 调试固件的三板斧:打印、串口、GDB

调试固件和调试用户态程序完全不是一个体验。这里给三件最常用的工具排个序:

第一是 DEBUG 打印。EDK2 的 DebugLib 在任何阶段都能吐日志,编译时指定-D DEBUG_ON_SERIAL_PORT=TRUE,QEMU 的串口就能收到固件日志。DEBUG((DEBUG_INFO, "Hello, value = %d\n", Value))这句代码救过所有固件工程师的命。

第二是串口调试器。真机上要焊调试串口、接逻辑分析仪或者 USB 转串口工具,速度慢但能看到固件死在哪个阶段。POST 卡上的十六进制代码就是靠这种机制实现的。

第三是 GDB 远程调试。QEMU 里启动固件时加-s -S参数,可以让 QEMU 暂停并开放 1234 端口等待 GDB 连接,配合target remote :1234add-symbol-file加载 EFI 模块符号,你能像调试普通 C 程序一样看固件在哪个函数里崩溃。这种调试方式在真实主板上很难复现,所以很多固件开发者会在 QEMU 里先把逻辑调通,再移植到真机平台。

4.4 关于“魔改 BIOS”这个生态,我多说两句

网上至今还有大量“魔改 BIOS”下载站和刷写教程,从修改微码、解锁功耗墙、导入 SLIC,到给老主板添加 NVMe 启动模块,本质上都是对固件二进制做后处理。作为一个从业者,我会提醒你三条事实:

第一,魔改 BIOS 的风险是真实存在的。固件里有一大块压缩的 UEFI 卷和模块,任何粗暴的替换都可能破坏模块间的 GUID 引用,刷进去后轻则无法进系统,重则板子变砖需要编程器强刷。

第二,现在的固件验证越来越严格。随着安全启动、Boot Guard 等机制普及,改过的固件可能根本过不了验证,或者被芯片组直接拒绝启动。这并不是“厂商故意恶心你”,而是整条供应链的安全设计。

第三,如果目的是学习固件原理,魔改别人的二进制远不如自己拿 OVMF 固件练手来得高效——OVMF 是可以自行编译、签名、修改的,哪怕把 BIOS 卷搞坏了,删掉文件重来一遍,成本为零。

5. 亲手跑一个 EDK2 环境:从编译 OVMF 到 UEFI Shell

讲了这么多理论,最好还是动一次手。在 QEMU 虚拟机里用 OVMF 固件跑 UEFI,是零成本理解整个启动流程的最佳路径,也是所有 EDK2 新人的第一课。

5.1 编译 OVMF 并启动

环境准备不做复杂设置,Ubuntu/Debian 下先把依赖装齐:

sudo apt install build-essential uuid-dev nasm python3 python3-pip qemu-system-x86 git clone https://github.com/tianocore/edk2.git cd edk2 git submodule update --init --recursive make -C BaseTools source edksetup.sh

然后编译 OVMF(Open Virtual Machine Firmware):

build -p OvmfPkg/OvmfPkgX64.dsc -b DEBUG -t GCC5

编译输出在Build/OvmfX64/DEBUG_GCC5/FV/,里面有两个关键文件:OVMF.fd 是完整的固件映像,可以直接作为 QEMU 的 BIOS 使用;OVMF_CODE.fd 和 OVMF_VARS.fd 是代码区和变量区分离的版本,方便测试 NVRAM 读写。

启动命令:

qemu-system-x86_64 -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -m 4096 -smp 4 -nographic

如果一切顺利,你会看到 TianoCore 的 logo 和 UEFI Shell 的启动界面,然后出现Shell>提示符。这里我专门提醒一下:-nographic模式下串口输出和调试日志都会显示在终端,非常适合观察固件启动流程;如果只想看图形界面,去掉这个参数即可。

5.2 在 UEFI Shell 里体验“固件的命令行”

进入 Shell 后,先用map -r看看当前的设备映射:

Shell> map -r

它会列出所有可用的文件系统、块设备和句柄别名,比如FS0:是 ESP 分区,BLK0:是磁盘。输入drivers可以看到当前固件加载了哪些驱动,dh可以列出句柄数据库,pci可以枚举 PCI 设备。这些命令组合起来,就是在固件层完成了一次完整的设备枚举——和操作系统里设备管理器干的事情相似,只是更底层。

Shell 还支持写.nsh脚本文件,类似 Windows 的批处理。你可以建一个startup.nsh放在 FAT 格式的 U 盘里的 ESP 分区根目录,QEMU 指定 U 盘为启动盘后,固件会自动执行脚本里的命令。很多硬件诊断工具就是这么做的。

5.3 写一个最小 DXE 驱动,并让它跑起来

最后这个例子非常小,但它能让你看清 EDK2 模块的基本骨架。新建一个目录OvmfPkg/HelloDxe/,创建两个文件。

HelloDxe.inf

[Defines] INF_VERSION = 0x00010005 BASE_NAME = HelloDxe FILE_GUID = 9B78F5F4-3C8A-4C49-8CE0-9B75A6E32201 MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 ENTRY_POINT = HelloDxeEntry [Sources] HelloDxe.c [Packages] MdePkg/MdePkg.dec [LibraryClasses] UefiDriverEntryPoint UefiLib DebugLib

HelloDxe.c

#include <Uefi.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiLib.h> EFI_STATUS EFIAPI HelloDxeEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { gST->ConOut->OutputString (gST->ConOut, L"\r\nHello from my DXE driver!\r\n"); return EFI_SUCCESS; }

然后在OvmfPkg/OvmfPkgX64.dsc[Components]段加上一行:

OvmfPkg/HelloDxe/HelloDxe.inf

重新编译后启动 QEMU,会在 Shell 加载到 DXE 阶段看到一行输出。你还可以在 Shell 里手动加载:

Shell> load fs0:\HelloDxe.efi

这个几十行代码的小驱动,完整走过了编译、放进固件、运行时执行的全流程。理解了它,再去看 EDK2 里那些几百行的复杂驱动,思路就不会乱了。

6. 固件生态的下一站:安全、更新与异构

最后聊一点行业趋势。UEFI 和 EDK2 不是终点,它正在被安全、更新机制、新硬件形态不断重塑。

6.1 Secure Boot 与平台信任链:从“没人管”到“层层签名”

Secure Boot 的核心机制是 PK、KEK、db、dbx 四级密钥体系:平台密钥(PK)由用户管理,密钥交换密钥(KEK)授权给操作系统厂商,db 是受信任的签名数据库,dbx 是黑名单。固件在启动每个 EFI 应用程序时都会验证签名是否在 db 中且不在 dbx 中。

在 2020 年前后,有研究团队公开过绕过 Secure Boot 的攻击链,之后整个行业对固件安全明显加码。现在的方向是 Measured Boot:用 TPM 2.0 对固件、驱动、引导加载器、内核做逐级哈希度量,把 PCR 注册表留给操作系统做远程证明。对于做固件的人来说,这意味着以后的固件代码不仅要“能跑”,还要“跑得可证明”。

6.2 Capsule 与固件差分升级:不能只靠“下载全量包”

以前更新主板固件的方案是把整个 BIOS 芯片内容读出来、改好、再刷回去。UEFI 标准化了 Capsule 更新机制:操作系统通过 UpdateCapsule 运行时服务,把一个封装好的固件更新包交给固件处理,固件在重启后的早期阶段完成自更新。这个机制比传统 Windows 下的刷写工具安全得多,也让 Linux 生态里的fwupd+ LVFS 成了可能。

“固件差分升级”在开源社区的流行并不奇怪:IoT 设备、服务器 BMC、路由器固件动辄几十 MB,OTA 全量推送流量成本高,差分升级能大幅缩减包体。但固件差分比应用层差分更难,因为固件内部有大量压缩段、GUID 索引、镜像签名,任何一处对不上更新就会失败。现在不少项目选择把固件拆成多个小 Capsule、分别做差分包,这是比较务实的路径。

6.3 异构平台与云原生固件:EDK2 在 ARM 和 RISC-V 上的机会

Intel/AMD 统治 x86 的时代里,UEFI 和 EDK2 是绑定关系。但 ARM 服务器和 RISC-V 的崛起正在改变这个局面。ARM 平台常见的方案是 SCP 固件 + U-Boot + EDK2:EDK2 负责标准 UEFI 接口,U-Boot 负责快速加载引导镜像,二者通过设备树和 DT 描述文件衔接。微软强制要求 ARM 设备支持 UEFI 启动,也让 EDK2 在 ARM 生态里站稳了脚跟。

RISC-V 这边,EDK2 已有 RISC-V64 的官方支持,配合 OpenSBI 完成 M 模式向 S 模式的跳转。虽然还没到 x86 那种成熟度,但至少“跑一个最小 UEFI Shell”已经不是问题。固件工程师这些年依然是招聘市场上的硬通货,原因很简单:系统越复杂、安全要求越高,底层固件就越没人敢大意。

我自己做固件的体会是:这个领域最大的门槛不是硬件,而是信息密度太高,官方规范数千页,开源代码动辄几百万行,光靠看文档很容易迷失。最有效的路子就是先让 EDK2 在 QEMU 里跑起来,对着源码改一个驱动、加一个打印、看一次启动日志,整个知识树就会被点亮。等你哪一天能自己往 OVMF 里塞一个自写的 DXE 驱动,再回头去看网上那些“魔改 BIOS”的教程,会发现它们讨论的问题,其实都只是固件生态里很小的一块。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询