《计算机固件安全技术》第2章 计算机固件的发展与技术基础
最近在看《计算机固件安全技术》一书,纸上得来终觉浅,遂写点小记录。由于笔记没有层次,用大模型进行排版。
一、影子内存(Shadow RAM)
影子内存(Shadow RAM)是指将原本位于慢速 ROM(如 BIOS 芯片)中的代码,复制(或“影射”)到更快的主内存(RAM)中,并让 CPU 从 RAM 中执行这些代码,以提高系统启动和运行效率的一种技术。
二、开源BIOS项目
- TinyBIOS
- OpenBIOS
- LinuxBIOS
- Bochs
三、前期初始化三部分
- CPU 初始化
- 内存初始化
- 系统芯片组初始化
3.1 CPU 初始化
IA-32 处理器有 3 种工作模式:
- 实地址模式:提供处理器初始运行环境。
- 保护模式:32 位处理器的本机操作模式。
- 虚拟 8086 模式(原文“8060”为笔误):允许处理器在保护模式下运行 8086 模式软件并支持多任务环境。
加电后,第三代固件将处理器从实地址模式转换为保护模式。
3.2 内存初始化
DRAM 要正常运行,需进行参数设置。
DRAM 主要相关参数:
- RAS-to-CAS Delay:RAS 到 CAS 的延迟时间,设置不当会造成内存读取错误。
- RAS Precharge Time:RAS 在 DRAM 重置前预留的预充电时间,设置太短会导致数据丢失。
- CAS Latency Time:CAS 触发信号前的延迟时间,影响读写操作。
- DRAM Data Integrity Mode
- Host/DRAM Frequency:DRAM 运行频率。
- DRAM Row Boundary Registers (DRB):共 8 个,用于计算 RAM 大小。
内存条右侧的 8 针、256 字节 EEPROM 芯片称为 SPD(Serial Presence Detect),记录内存的速度、容量、电压等参数信息。
初始化内存必须通过 SPD 获取参数,并据此配置 DRAM 控制器。
读取 SPD 通过南桥上的 SMBus 总线进行。
3.3 系统芯片组初始化
- 系统芯片组:专为简化主板设计的芯片集合。
- 初始化极其复杂,通常需厂商提供初始化代码。
主要总线接口:
3.3.1 LPC 总线
- 取代传统 ISA 总线的新接口规范。
- 将 ISA 的地址/数据分开译码改为类似 PCI 的共享译码方式。
- 主板上的 Super I/O 芯片、Flash ROM 芯片、TPM 芯片通常通过 LPC 总线连接南桥。
3.3.2 SMBus 总线
- 系统管理总线(System Management Bus)。
- 低速率接口,含两组信号线。
- 用于符合 SMBus 协议的外围组件的检测、定位、参数读写等。
3.3.3 ATA 总线
- 专用于硬盘的接口标准,共 7 个版本。
- 最新 SATA 采用串行传输。
- 固件按 ATA 标准配置硬盘,发送/接收命令、数据、响应,以读取数据并引导操作系统。
3.3.4 USB 总线
- 提供中低速外设扩展能力。
- 支持热插拔,实现即插即用。
3.3.5 PCI 总线
- 第二代局部总线,取代 ISA/EISA/VESA。
- 当前最广泛使用的计算机标准总线。
PCI 总线处理包含两部分:
- PCI 总线配置
- PCI 总线枚举(采用深度优先搜索算法)
PCI 配置机制:
-
PCI 兼容配置机制:
通过 32 位 I/O 端口0CF8h和0CFCh访问配置寄存器。 -
PCI Express 增强配置机制(MMIO):
每个 PCI 功能的 4KB 配置空间映射到 256MB 对齐的存储空间中,通过直接内存访问实现配置(内存映射 I/O,MMIO)。
| 存储器地址 bit 位 | 说明 |
|---|---|
| 63:28 | 256MB 对齐基址高位,由固件 BIOS 分配 |
| 27:20 | 目标总线号 |
| 19:15 | 目标设备号 |
| 14:12 | 目标功能号 |
| 11:2 | 目标双字偏移(寄存器地址) |
| 1:0 | 所选双字内起始字节位置 |
注:“存储器地址”并非访问主存的地址,而是 CPU 用于访问 PCIe 设备配置空间的“配置地址编码”,包含总线号、设备号、功能号、寄存器偏移等信息,由 PCIe 控制器解析。
PCI 配置需已知目标设备的总线号和设备号。
四、固件典型规范
- ACPI(高级配置与电源管理接口)规范
- SMBIOS(系统管理 BIOS)规范 —— 核心是 SMBIOS 结构表
五、EFI 与 UEFI
- EFI 发展为 UEFI。
- UEFI 结构分为:
- UEFI 实体
- 平台初始化框架(PI Framework)
六、MCU固件
注:本章主要内容围绕x86架构计算机固件(如BIOS/UEFI)展开,未直接讨论MCU(微控制器)固件。但可从技术基础、初始化流程、总线接口、存储访问等角度,对比指出MCU固件的异同点,帮助建立跨平台理解。
6.1 与前述内容的相关性(间接关联点)
(1)影子内存概念在MCU中不常见
- PC BIOS 使用 Shadow RAM 是为加速从慢速ROM执行代码。
- MCU 通常直接从内部Flash执行代码(XIP, eXecute In Place),无“影子内存”需求。
- 部分高性能MCU(如Cortex-M7)可能使用Cache或TCM(紧耦合内存)优化访问,但机制与Shadow RAM不同。
(2)初始化流程类似,但复杂度不同
- 前述“CPU初始化、内存初始化、芯片组初始化”三阶段,在MCU启动流程中同样存在:
- CPU初始化:设置堆栈指针、中断向量表、时钟源、核心寄存器(如Cortex-M的SCB)。
- 内存初始化:配置SRAM、外部SDRAM(如有)、MPU/MMU(如支持)。
- 外设/芯片组初始化:初始化GPIO、UART、SPI、I²C、ADC等外设控制器 —— 类似PC中“系统芯片组初始化”,但MCU集成度高,无需“南桥/北桥”。
区别:MCU固件通常由厂商提供启动文件(startup_xxx.s)和HAL库完成,无需像PC固件那样处理多总线枚举、ACPI、SMBIOS等复杂规范。
(3)总线接口对比
- PC中讨论的 LPC、SMBus、PCIe、USB、ATA 等,在MCU中通常简化或替换:
- SMBus → MCU常用 I²C(SMBus是I²C子集,MCU多支持I²C主/从模式)。
- LPC → MCU无对应总线,低速外设直接挂接在APB/AHB总线上。
- PCIe/PCI → MCU一般不支持,高性能MCU或SoC可能支持,但需专用IP核。
- SPD读取 → MCU若驱动DDR,也可能通过I²C读取SPD,但非标配流程。
(4)固件规范差异
- PC固件遵循 ACPI、SMBIOS、UEFI PI 等开放标准。
- MCU固件无统一规范,由芯片厂商定义启动流程、寄存器映射、外设驱动接口(如STM32 HAL、NXP MCUXpresso、ESP-IDF等)。
- MCU固件常为“裸机”或RTOS环境,无“操作系统引导”概念(除非运行Linux的MCU/MPU)。
(5)配置空间与寄存器访问
- PC中PCIe设备通过“配置空间地址编码”访问寄存器。
- MCU中外设寄存器直接通过内存映射地址(MMIO) 访问,地址固定,无需“总线号/设备号/功能号”寻址。
例:STM32的GPIOA基址为
0x4002 0000,直接读写该地址范围即可控制引脚 —— 比PCIe配置机制简单直接。
6.2 核心区别总结
| 对比维度 | PC固件(BIOS/UEFI) | MCU固件 |
|---|---|---|
| 目标平台 | x86/x64 通用计算机 | 嵌入式微控制器(ARM Cortex-M, RISC-V等) |
| 启动介质 | SPI Flash(BIOS芯片) | 内部Flash / 外部QSPI Flash |
| 是否需要Shadow RAM | 是(加速执行) | 否(XIP执行或Cache优化) |
| 初始化复杂度 | 极高(CPU/内存/芯片组/总线/ACPI/SMBIOS) | 中低(时钟/内存/外设) |
| 总线支持 | PCI/PCIe/LPC/SATA/USB等 | I²C/SPI/UART/CAN/USB(设备模式)等 |
| 配置机制 | PCIe配置空间、ACPI表、SMBIOS表 | 寄存器直接映射、厂商SDK |
| 固件标准 | UEFI、ACPI、SMBIOS | 无统一标准,厂商自定义 |
| 操作系统引导 | 是(引导OS Loader) | 通常否(裸机/RTOS),少数引导Linux |