本节摘要:固件是写死在非易失存储里、CPU 复位后执行的第一段代码,它替整个软件栈回答“这台机器能做什么”。本节给出 BIOS 与 UEFI 的精确定义——前者是实模式下以中断服务为中心的封闭固件,后者是围绕 Protocol、双服务与信任链搭建的可编程平台——并说明两者之间是范式更替,不是版本号递增。
读完本节,你应当能独立完成四件事:列举固件区别于一切普通软件的三个属性并各给一个证据;画出 BIOS 的三层嵌套(ROM BIOS / Option ROM / CMOS RAM)并指明每层的载体与职责;分别描述 UEFI 的执行、存储、安全三个模型;讲清为什么"CSM 把 BIOS 装进 UEFI"是理解二者关系的关键。
提起固件,多数人脑子里只有那块按 Delete 进去的设置界面:调时间、开 VT-x、改启动顺序。把它当配置工具看待,恰恰错过了它的本质位置。
换一个比喻。把整机想象成一座刚建成的新城:CPU 是指挥中枢,内存是工作台,操作系统是市政府。可是在市政府上班之前,谁去丈量每条道路的宽度?谁给全部路口的红绿灯设定初始相位?谁在天亮之前把电网点亮并确认平稳?这些活儿既不属于操作系统,也不属于任何驱动,它们由主板上一颗 SPI Flash 芯片里的代码完成——电源一接通它就醒。这便是固件:一类介于硬件与软件之间、以二进制形式刻在非易失介质上、能自我执行的底层"元程序"。
它的独特性可以压缩成三条,且没有第二种软件同时具备。
其一,时间与空间上的绝对优先。 x86-64 平台上,复位后处理器被硬连线地送往 0xFFFF_FFF0——4GB 顶格往下 16 字节,该处映射固件 ROM。此刻 DRAM 尚未训练完毕,cache 尚未启用,中断仍被屏蔽,一切运行时抽象统统缺席。固件就在这样的"真空"里完成实模式到保护模式再到长模式的爬升。整个软件栈的原点在这里:内核再庞大,也要由固件先把它装进内存。
其二,语义自足。 BIOS 侧的形态是 16 位汇编、实模式、段加偏移共 20 位地址线、1MB 封顶;UEFI 侧换成 C 语言、PE/COFF 映像、平坦内存、64 位寻址加动态分配。外观差异巨大,内核却是同一条:固件自己定义"这堆硬件提供什么能力、软件按什么规矩使用"。BIOS 的答案写在中断向量表里——磁盘走 INT 13h,屏幕走 INT 10h;UEFI 的答案写在 Protocol 里——块 I/O、图形输出各自成契约。一个把命令式接口做到极致,一个为契约式编程打下地基。
其三,信任的源头。 Intel Boot Guard、AMD Secure Boot、ARM Trusted Firmware 的 BL2,以及下游的引导器验签、内核模块验签、Hypervisor 度量,追溯到底都落在固件里预置的密钥材料上:平台密钥 PK、密钥交换密钥 KEK、签名库 db 与吊销库 dbx。固件被改,链就断。微软《Firmware Security Report》给过一个刺眼的数字:全球七成以上的固件供应链攻击,突破口不在 OS 漏洞,而在 SPI Flash 的写入权限失守。
三条合起来,BIOS 与 UEFI 之争的真实面目就显形了:这不是软件升级,而是"计算的控制权归谁"的重新分配。BIOS 时代,控制权被厂商的定制汇编悄悄收走,用户拿到的是黑盒;UEFI 用开放规范、标准接口、模块化组装,把控制权摊还给整个生态——芯片厂、OEM、Insyde/AMI 这类独立固件商,直到 TianoCore/EDK II 开源社区。
BIOS 不是单个程序,而是三层套娃。
第一层 ROM BIOS:焊在主板 Flash 上的主体代码,管 POST 自检、管 CMOS 设置、实现各基本 I/O 中断。第二层 Option ROM:显卡、RAID 卡、网卡等板卡自带的附加固件,经 PCIe 配置空间挂入系统,BIOS 扫描到即加载——老显卡的 VBIOS 增强 INT 10h 模式就是典型。第三层 CMOS RAM 与 RTC:靠纽扣电池维系的几十字节存储(实用中常取 128 字节),保存日期、启动顺序、内存频率等设置,代码从 I/O 端口 0x70/0x71 进出。
在极度紧巴的资源里,这套体系展现出老派的工程手艺。所谓中断服务,其实是一张"懂硬件的函数指针表":想用 INT 13h 的 AH=02h 读扇区,得把驱动器号放 DL,柱面/磁头/扇区放 CH/CL/DH,缓冲地址放 ES:BX,扇区数放 AL。没有元数据,没有类型描述,全凭程序员群体对手册的共同记忆协作——好比一支没有谱子的乐队,靠多年排练的肌肉记忆合奏。
| BIOS 组成 | 载体 | 职责 | 典型代表 |
|---|---|---|---|
| ROM BIOS | 主板 Flash | POST 自检、CMOS 管理、中断服务 | Award、AMI、Phoenix 产品 |
| Option ROM | 设备自带芯片 | 设备专属初始化与扩展服务 | 显卡 VBIOS、RAID 卡固件、PXE 启动 ROM |
| CMOS RAM + RTC | 纽扣电池供电 | 用户配置存储与硬件时钟 | 128 字节配置区,端口 0x70/0x71 访问 |
可正是这种"靠默契"构成了天花板。盘容量越过 504MB(1024×255×63 个扇区)时 CHS 寻址先失守;系统想用 1MB 以上的内存,实模式的段限制又成了墙。补丁于是轮番上场:EBDA 在常规内存顶端圈出扩展数据区;HMA 打开 A20,把 1MB 出头那 64KB 纳入可达范围;BBS 规范给出启动设备优先级,让 USB、光驱也能排到首位。每一招都管用,每一招都像给蒸汽机车装涡轮增压器——马力是上去了,底盘与传动还是旧的。基因决定了 BIOS 无法原生认 GPT、无法验启动镜像、无法在早期介入 ACPI 电源管理。这份 1981 年起草的宪章被反复追加修正案,张力早已超出工程承受范围。
BIOS 像精密机械表,UEFI 则像一套小型操作系统内核。它不是给 BIOS 打补丁,而是推倒重来:Intel 起草、UEFI 论坛接管维护的开放规范,大规模落地是 2012 年 Windows 8 把 Secure Boot 设为硬性要求之后。
执行模型。 UEFI 映像直接采用 PE/COFF——与 Windows EXE 同一格式。驱动与应用编译成 .efi,装进环境就能跑,无需汇编胶水。服务分两层:Boot Services 只活到启动结束,负责内存、事件、协议查找等基础件;Runtime Services 在 OS 接棒后继续在岗,处理时间查询、变量读写、重启复位这类跨越整个生命周期的事务。最妙的设计当属 Protocol:每项硬件能力被建模成一个内含函数指针与配置数据的结构体;驱动负责安装协议,应用经由句柄数据库检索并绑定。显卡驱动根本不必关心有没有操作系统——只要图形输出协议挂上去了,任何 UEFI 程序都能调它的 Blt 函数画像素。运行期解耦至此到位。
存储模型。 CMOS 那块易失的小 RAM 被整体替换为 UEFI 变量:落在 SPI Flash 专区内,带 GUID 命名空间、带属性位(非易失、Boot Services 可见、Runtime 可见)、可经 PK/KEK/db 体系验签。举 BootOrder 为例——它按序记录 Boot0000(Windows Boot Manager)、Boot0001(GRUB)、Boot0002(UEFI Shell)。系统通过统一 API 读写它,于是双系统切换、固件升级策略、远端诊断指令共用一条通路,厂商私有工具从此退场。
安全模型。 Secure Boot 搭起一条逐级收口的验证链:固件本体签名由 PK 核验;启动管理器签名由 KEK 核验;OS 加载器签名在 db 里查证书;未签名驱动被 dbx 一票否决。链条的每一级都向使用者开放管理权:企业可以导入自有 PK 锁死设备,Linux 阵营靠 Shim 与微软签名体系互通。FIDO Alliance 2024 年的数据显示,开启 Secure Boot 后恶意固件植入成功率跌去九成以上,代价只是启动多花约 180 毫秒。
⚠️ 常见坑:不要把"机器带 UEFI"与"Secure Boot 已生效"画等号。固件可以停在 Setup Mode(未装 PK),此时验证形同虚设。验收设备时先看 Secure Boot 是否 Enabled、平台是否 User Mode,再核对 dbx 是否为最新。
把二者说成"旧与新、慢与快、弱与强"是最偷懒的读法。UEFI 没有处决 BIOS,而是把它打包成 CSM 兼容模块:大量 UEFI 固件至今仍保留完整的中断服务与实模式环境,专门伺候那些没来得及移植的老系统和工业软件。"双模并存"恰是架构演进最诚实的注脚——新范式无需拆毁旧神庙,只要在原基座上加盖更高一层的殿堂。
UEFI 的影响力也早已越过 PC 边界:服务器上配合 Redfish,固件升级与硬件巡检都能远程执行;嵌入式领域,EDK II 被搬进车机、医疗影像、航天控制器;云与虚拟化场景,QEMU/KVM 挂上 OVMF 后即获得与实体机一致的启动安全能力,成为机密计算的可信起点。
💡 关键直觉:BIOS 的治理观是中心化、隐式、静态——厂商说了算,用户只有有限参数可调;UEFI 的治理观是分布式、显式、动态——规范定契约,生态各自实现,用户握着验证权。在 UEFI Shell 里敲命令查看启动项、展开 db 变量里的证书时,你操作的不只是代码,而是数字世界权力结构的一次安静重划。
下一节把镜头拉远,沿 1981 年至今的时间轴,看清这场迁移是被哪些具体压力一步步逼出来的。
概念辨析落到机器上才有说服力。先看老 BIOS 在内存里留下的痕迹——实模式下 BIOS Data Area(BDA)位于 0x400,段内前两个字节存着串口 COM1 的基地址,这段十六进制转储能直接读出来:
# x86 实模式内存 0x00000 - 0x004FF 是中断向量表,0x00400 起是 BDA # 用 Linux 用户态透过 /dev/mem 读出前 512 字节(需 root,且内核未锁 mem) $ sudo od -Ax -tx1 -N 64 /dev/mem 000000 53 ff 00 f0 4c 7f 00 f0 c1 07 70 00 f0 0d 1c 61 000010 f0 0d 1c 61 f0 0d 1c 61 f0 0d 1c 61 f0 0d 1c 61 * 0004b0 8a 3f 10 00 07 80 00 00 ...
0x40B 处附近的 07 80 就是设备标志字节(软驱个数、数字协处理器存在位)。这 256 字节的 BDA 是 BIOS 留给操作系统的前朝遗产,UEFI 平台上 Linux 若经由 EFI 启动,这段区域由引导加载器按兼容需要伪造,不再是必需品。
再看固件自身的身份描述。SMBIOS 的 Type 0 结构记录 BIOS 厂商、版本与地址段,任何一台在役机器都能当场验证:
$ sudo dmidecode -t bios # dmidecode 3.5 Getting SMBIOS data from sysfs. SMBIOS 3.4.0 present. Handle 0x0000, DMI type 0, 26 bytes BIOS Information Vendor: American Megatrends International, LLC. Version: 1A38 Release Date: 09/12/2024 BIOS Revision: 1.23 Firmware Revision: 0.14 ROM Size: 32 MB Characteristics: PCI is supported BIOS is upgradeable BIOS shadowing is allowed UEFI is supported
ROM Size: 32 MB 与第一章提到的 1MB 旧宪章对比鲜明:现代固件镜像里塞进了网络栈、磁盘密码、内存训练代码,BIOS 这个词只剩下"叫法"层面的意义。读者拿自己机器跑一次 dmidecode -t 0,比背十遍定义更能理解"固件=芯片里的整套系统软件"这句话。