Skip to content

集成子设备

核心三大件(CPU、内存、硬盘)之外,CPU 芯片内部和主板上还集成了大量专用硬件单元,它们是计算机正常运行的基础设施。这些子设备不通过外部总线连接,而是直接集成在芯片或主板上,通过 MMIO 或专用信号线与 CPU 交互,在 Linux 设备模型中大多被归类为平台设备。

CPU 子设备

CPU 芯片内部集成的子设备直接参与指令执行和内存访问,是处理器核心功能的重要组成部分。

MMU 与 TLB

MMU(Memory Management Unit)是 CPU 中负责虚拟地址到物理地址转换的硬件单元。现代操作系统都使用虚拟内存机制,每个进程拥有独立的虚拟地址空间,MMU 在每次内存访问时完成地址翻译,使进程以为自己独占了整个内存空间。

MMU 通过页表完成地址转换。以 x86_64 的四级页表为例,虚拟地址被拆分为四段索引,依次查 PGD(Page Global Directory)→ PUD(Page Upper Directory)→ PMD(Page Middle Directory)→ PTE(Page Table Entry),最终得到物理页帧号。每次内存访问都需要四次内存读取来完成页表遍历,开销巨大。为此 CPU 引入了 TLB(Translation Lookaside Buffer),它是一个硬件缓存,存储最近使用的虚拟地址到物理地址的映射关系。TLB 命中时,地址转换只需一个时钟周期;TLB 未命中时才需要遍历页表,并将结果写入 TLB。现代 CPU 通常有分离的指令 TLB(ITLB)和数据 TLB(DTLB),以及多级 TLB 结构来提高命中率。

在 Linux 内核中,进程切换时需要刷新 TLB(通过 cr3 寄存器写入新的页表基址,x86 硬件自动完成刷新),这是进程切换开销的重要来源。内核还通过 huge pages(大页)机制减少 TLB 条目数量,提高 TLB 命中率,在数据库、虚拟化等大内存工作负载中效果显著。

中断控制器

中断控制器是 CPU 管理外部中断信号的硬件单元,负责收集、优先级仲裁和分发中断请求。x86 平台使用 APIC(Advanced Programmable Interrupt Controller) 体系,ARM 平台使用 GIC(Generic Interrupt Controller)

x86 的 APIC 体系包含两个组件。Local APIC 集成在每个 CPU 核心内部,负责接收 IPI(处理器间中断,用于核间通信)和外部中断,支持中断优先级和中断掩码。I/O APIC 位于芯片组中,负责接收外部设备的中断信号(如网卡、硬盘控制器),将其路由到指定 CPU 的 Local APIC。每个 I/O APIC 有 24 个输入引脚(Redirection Entry),可以独立配置中断向量、目标 CPU、触发模式和优先级。现代 x86 系统使用 x2APIC 扩展,将 APIC 寄存器访问从 MMIO 改为 MSR(Model Specific Register),支持超过 255 个 CPU 核心的中断路由。

ARM GIC 的架构类似但实现不同。GICv3/GICv4 支持中断虚拟化(为虚拟机分配独立的中断号空间)、亲和性路由(基于 CPU 亲和性自动分发中断到最近的核)和 LPI(Locality-specific Peripheral Interrupt,用于 MSI 等大量中断源)。在 ARM 服务器平台(如鲲鹏、Ampere)上,GIC 配合 SMMU(ARM 的 IOMMU)和 ITS(Interrupt Translation Service)实现 PCIe 设备的 MSI 中断路由。

Linux 内核的中断子系统对应了这些硬件。底层的中断芯片驱动(如 apic.cgic.c)直接操作硬件寄存器,上层的中断框架(irq_domain)将硬件中断号映射为 Linux 虚拟中断号,再通过 request_irq 分发给具体驱动。开发者通常不需要直接操作中断控制器,但理解其路由机制对于多核系统的中断亲和性调优至关重要。

TSC

TSC(Time Stamp Counter)是 x86 CPU 内部的一个 64 位寄存器,每个时钟周期自动递增。通过 rdtsc 指令可以读取其值,精度等于 CPU 主频的倒数(例如 3GHz 的 CPU,TSC 精度约为 0.33 纳秒)。TSC 是 Linux 内核高精度定时器的基础时钟源之一。

早期 CPU 的 TSC 频率等于 CPU 核心频率,在 CPU 频率动态调节(DVFS)时 TSC 速率不稳定,导致它不可靠作为时间源。现代 CPU(Nehalem 及之后的 Intel,Zen 及之后的 AMD)引入了 Invariant TSC,TSC 以固定频率运行,不受 CPU 频率调节影响,成为可靠的高精度时钟源。内核启动时通过 tsc_khz 变量记录 TSC 频率,clocksource 框架会自动检测 TSC 是否 invariant,选择最佳时钟源。

TSC 还广泛用于性能测量。rdtsc 前后各读一次,差值即为代码执行耗时(需除以 TSC 频率换算为秒)。Linux 提供 rdtsc 的封装函数 rdtscll,以及更高层的 ktime_get_nslocal_clock 等时间获取接口。在用户空间,可以使用 clock_gettime(CLOCK_MONOTONIC_RAW) 获取基于 TSC 的时间戳。

Cache

Cache(缓存)是位于 CPU 核心与主存之间的高速 SRAM 存储器,用于缓解两者之间越来越大的速度差距。现代 CPU 的访问延迟大约是:L1 约 1ns、L2 约 3-10ns、L3 约 30-50ns,而主存约 60-100ns。没有缓存的话,CPU 大量时间将浪费在等待内存响应上。

CPU 缓存采用多级层次结构L1 最小最快,分为指令缓存(I-Cache)和数据缓存(D-Cache),每个核心独占,通常各 32-64KB。L2 容量较大(256KB-1MB),每个核心独占,速度介于 L1 和 L3 之间。L3 容量最大(8MB-64MB 甚至更多),所有核心共享,速度最慢但远快于主存。

缓存的基本管理单位是缓存行(Cache Line),典型大小为 64 字节。内存读取以缓存行为粒度:CPU 读取一个字节时,包含该字节的整个缓存行都会被加载到缓存中。写入策略上,现代 CPU 普遍采用写回(Write-back)模式:写入只修改缓存,不立即写回主存,当缓存行被驱逐时才写回。相比写直达(Write-through),写回大幅减少了内存访问次数,但增加了缓存一致性维护的复杂度。

在多核系统中,缓存一致性是必须解决的问题。当多个核心的缓存中存在同一内存地址的副本时,某个核心修改了该地址,其他核心的副本必须被更新或失效,否则会读到旧数据。主流的缓存一致性协议是 MESI 协议,通过四种状态(Modified、Exclusive、Shared、Invalid)标记每个缓存行,硬件自动在核心间发送消息来维护一致性。当某个核心要写入处于 Shared 状态的缓存行时,必须先向其他持有该行的核心发送 Invalidating 消息使其失效,这个等待过程可能导致写入延迟。内核和应用程序可以通过缓存行对齐__aligned(64))和False Sharing 避免来优化多核性能。

Linux 内核与缓存相关的几个重要机制包括:huge pages 通过增大页尺寸来减少 TLB 条目数量和页表遍历层级,间接提高缓存利用率;CONFIG_NUMA 感知缓存和内存的物理拓扑,将进程调度到靠近其内存分配的 NUMA 节点上,减少跨节点的远程内存访问;cgroupmemory.numa_stat 可以观察进程的内存访问局部性。在用户空间,perf stat -e cache-references,cache-misses 可以直接测量缓存命中率,numactl 工具可以控制进程的内存分配策略。

PMU

PMU(Performance Monitoring Unit)是集成在每个 CPU 核心内部的硬件性能监控单元,包含一组可编程的计数器(通常 4-8 个固定计数器加若干通用计数器),用于统计微架构级别的事件,如指令执行数、缓存命中/缺失次数、分支预测正确/错误次数、周期数等。

PMU 的工作方式是:内核或用户程序将感兴趣的事件类型写入 PMU 控制寄存器,PMU 开始在硬件层面计数对应事件的发生次数。计数溢出时 PMU 可以触发中断,内核在中断处理中采样当前指令地址(IP),这就是 perf record 采样 profiling 的底层原理。Linux 内核的 perf 子系统kernel/events/)统一管理 PMU 的分配、事件调度和计数器读取,向上提供 perf_event_open 系统调用,用户空间的 perf 命令和 libpfm 库都基于此接口。

固定计数器监测特定事件,如 cpu-cycles(时钟周期数)、instructions(已执行指令数)、cache-references(缓存访问次数)。通用计数器可以监测数百种微架构事件,如 LLC-misses(L3 缓存缺失)、branch-misses(分支预测失败)、rNNN(Intel 的参考事件编号)。在 /sys/bus/event_source/devices/cpu/events/ 下可以查看当前 CPU 支持的所有事件。

在工程实践中,PMU 是性能调优的关键工具。通过 perf stat 可以快速获取程序运行期间的硬件事件统计(IPC、缓存命中率、分支预测准确率等),定位性能瓶颈。通过 perf record -g 可以采集调用链火焰图,分析热点函数。需要注意的是,PMU 计数器是有限的硬件资源,多个工具或进程同时使用时需要内核进行时间片轮转调度,这会引入测量误差。在虚拟化环境中,PMU 资源需要通过 perf 虚拟化(Intel PT 或 vPMU)分配给虚拟机使用。

主板子设备

主板上的子设备通过芯片组或专用芯片与 CPU 连接,提供系统级的基础功能。

IOMMU

IOMMU(Input/Output Memory Management Unit)是位于 I/O 设备与内存控制器之间的 DMA 地址翻译单元,功能类似于给设备配了一个"MMU"。虽然现代 Intel/AMD 平台的 IOMMU 与 CPU 封装在同一块芯片(die)上,但它属于处理器的非核心部分(Uncore/System Agent),不属于任何 CPU 核心,不参与指令执行。在 ARM SoC 中,SMMU 是独立的 IP 模块。

没有 IOMMU 时,DMA 设备直接使用物理地址访问内存,存在两个问题:设备只能访问物理内存的地址范围内(32 位设备在 64 位系统上最多寻址 4GB),且设备可以访问任意物理内存,存在安全隐患。IOMMU 通过建立设备端的地址翻译表(IO 页表),将设备看到的总线地址翻译为物理地址,同时限制设备的可访问范围。

IOMMU 的核心功能包括 DMA 地址翻译(使 32 位设备能在 64 位系统上使用全部内存)、DMA 隔离(限制设备只能访问被授权的内存区域,防止恶意设备发起 DMA 攻击)和中断重映射(将设备的 MSI 中断翻译并路由到指定的 CPU,配合虚拟化实现中断直通)。x86 平台的 IOMMU 称为 VT-d(Intel)或 AMD-Vi(AMD),ARM 平台称为 SMMU(System Memory Management Unit)。

在 Linux 内核中,IOMMU 子系统由 drivers/iommu/ 管理。内核启动参数 intel_iommu=on 启用 Intel VT-d。启用 IOMMU 后,内核会为每个设备创建 IO 页表,DMA 映射 API(dma_map_single 等)在底层通过 IOMMU 完成地址翻译。对于 PCI 直通(Passthrough)给虚拟机的场景,IOMMU 是必要前提,它确保直通设备无法访问宿主机的内存。

I/O APIC

I/O APIC 是 x86 平台上位于芯片组(Intel PCH / 传统南桥)中的中断收集与分发单元,与 CPU 核心内部的 Local APIC 配对工作。CPU 子设备章节提到的 Local APIC 负责接收中断并触发核心处理,而 I/O APIC 负责在上游收集外部设备的中断信号并路由到下游的目标 CPU。

I/O APIC 内部维护一组重定向表(Redirection Table),每个条目对应一个中断输入引脚(通常 24 个),可以独立配置中断向量号、目标 CPU 的 APIC ID、触发模式(边沿/电平)和极性(高有效/低有效)。当某个引脚收到外部设备的中断信号时,I/O APIC 通过 APIC 总线或系统中断线将中断消息发送到目标 CPU 的 Local APIC,Local APIC 再根据优先级决定是否立即通知 CPU 核心处理。

多核系统上,I/O APIC 支持将不同设备的中断路由到不同 CPU 核,实现中断负载均衡。内核的 IRQ affinity 机制(通过 /proc/irq/xxx/smp_affinity 配置)在底层就是修改 I/O APIC 重定向表中的目标 CPU 字段。不过 I/O APIC 的路由粒度是设备级别而非队列级别,一个设备的中断只能固定路由到一个 CPU,无法像 MSI-X 那样为每个队列分配独立的中断向量。这也是现代高性能设备(网卡、NVMe)普遍采用 MSI-X 而非 INTx 的原因之一。

一个系统中可以有多个 I/O APIC,通过 ACPI 的 MADT(Multiple APIC Description Table)表描述每个 I/O APIC 的 MMIO 基地址和中断输入范围。内核在启动时解析 MADT,通过 MMIO 读取并配置 I/O APIC 的重定向表。在 /proc/interrupts 中可以看到以 IO-APIC 开头的中断条目,对应通过 I/O APIC 路由的传统中断。

需要注意的是,现代 x86 系统中 I/O APIC 的角色正在被弱化。PCIe 设备普遍使用 MSI/MSI-X 中断(由设备直接向 CPU 的 Local APIC 发送中断消息,绕过 I/O APIC),只有使用传统 INTx 中断的 PCIe 设备和少数遗留 ISA 中断仍然依赖 I/O APIC。但在服务器平台和嵌入式 x86 SoC 上,I/O APIC 仍然是不可或缺的中断路由组件。

RTC

RTC(Real-Time Clock)是主板上负责维持系统时间的硬件,即使系统断电也能通过主板上的纽扣电池(CR2032)持续计时。RTC 通常集成在南桥芯片(PCH)中,通过 I2C 总线(I2C 地址 0x68)与 CPU 通信,也支持 CMOS 端口(I/O 端口 0x70/0x71)访问。

RTC 的精度较低(典型精度为每月 ±10-20 秒),不适合高精度计时场景。内核启动时从 RTC 读取时间作为系统初始时间(rtc_hctosys),此后由内核的软件时钟(基于 TSC 或 HPET)维护时间,RTC 仅在系统关机时写回时间。用户空间通过 /dev/rtc0/dev/rtc 设备文件与 RTC 交互,也可以通过 hwclock 命令读取和设置硬件时钟。

在嵌入式平台上,RTC 通常是一个独立的芯片(如 DS3231、RX8025),通过 I2C 总线连接到 SoC。设备树中会描述 RTC 芯片的 I2C 地址和中断配置,内核的 RTC 子系统(drivers/rtc/)提供统一的 API,上层应用通过 /sys/class/rtc/ 接口或 ioctl 访问。

Watchdog

Watchdog(看门狗定时器)是一种硬件定时器,用于检测和恢复系统故障。其工作原理是:软件定期"喂狗"(向 Watchdog 寄存器写入特定值来重置计数器),如果软件因死锁、死循环或崩溃而未能及时喂狗,计数器溢出后 Watchdog 会触发硬件复位,强制重启系统。

Watchdog 在嵌入式设备和服务器中广泛使用。服务器上通常配置 softdog(软件看门狗,基于内核定时器实现)或硬件看门狗(如 iTCO,集成在 Intel 芯片组中)。Linux 内核的 Watchdog 子系统(drivers/watchdog/)提供了统一框架,用户空间通过 /dev/watchdog 设备文件进行交互:打开设备即启动看门狗,定期执行 ioctl(WDIOC_KEEPALIVE) 喂狗,关闭设备即停止看门狗。如果打开设备时设置了 Magic Closeioctl(WDIOC_SETOPTIONS, WDIOS_ENABLECARD)),则只有向设备写入特定魔数('V')才能安全关闭,防止进程异常退出后看门狗停止工作。

在 systemd 管理的系统上,systemd-watchdog 服务会定期喂狗,systemd 的各个核心服务(如 journald、networkd)也各自向 watchdog 注册心跳。如果某个核心服务无响应,systemd 会标记该服务为失败并尝试重启;如果 systemd 自身无响应,硬件看门狗将触发系统复位。

PCI 控制器

PCI 控制器(PCI Host Bridge)是 CPU 与 PCIe 总线之间的桥梁,它本身是一个平台设备,负责将 CPU 的内存访问请求路由到 PCIe 总线,并将 PCIe 设备的配置空间映射到 CPU 可访问的地址范围。

PCI 控制器的驱动(如 Intel 平台的 pcieport 驱动、ARM 平台的 pcie-rockchippcie-qcom)在 probe 时完成以下工作:配置控制器的寄存器基地址和 MMIO 窗口(ECAM 配置空间窗口、MMIO32/MMIO64 窗口);设置链路宽度和速率(x1/x4/x8/x16,Gen1/Gen2/Gen3/Gen4/Gen5);执行链路训练,建立与下游设备的物理连接;将控制器注册为 PCI 主桥,触发 PCI 核心层的总线枚举流程。

PCI 控制器还管理 PCIe 的高级特性。ASPM(Active State Power Management) 允许 PCIe 链路在空闲时进入低功耗状态(L0s、L1),节省功耗。AER(Advanced Error Reporting) 捕获 PCIe 总线上的错误(如 CRC 错误、完成超时、不可纠正错误),通过中断通知内核处理。热插拔(Hotplug) 支持运行时插入和移除 PCIe 设备,通过 PCIe 插槽的 Presence Detect 引脚和 Power Fault 引脚检测设备变化。

在设备树中,PCI 控制器的描述包括寄存器范围、中断映射(MSI 和 INTx)、总线范围等。在 ACPI 中,PCI 主桥通过 MCFG 表描述 ECAM 配置空间的基地址,通过 _CRS 方法描述 MMIO 和 I/O 资源窗口。

USB 控制器

USB 控制器(Host Controller)是 CPU 管理 USB 总线的硬件接口,负责将内核的 USB 请求转换为总线上的实际信号传输。目前主流的 USB 主机控制器标准是 xHCI(eXtensible Host Controller Interface),它同时支持 USB 2.0 和 USB 3.0/3.1/3.2 设备,替代了早期的 UHCI/OHCI(USB 1.1)和 EHCI(USB 2.0)。

xHCI 控制器内部维护了两套数据结构:设备上下文数据结构(Device Context) 描述每个 USB 设备的端点配置和传输环(Ring Buffer)地址;传输环 是主机和设备之间数据传输的队列,内核将 URB 的信息写入传输环,xHCI 控制器自动从环中读取并执行传输,完成后在事件环(Event Ring)中写入完成通知。这种基于环的结构使得批量传输可以高效流水线化。

xHCI 控制器驱动(drivers/usb/host/xhci-hcd.c)在 probe 时完成硬件初始化:通过 MMIO 配置控制器的运行参数(如中断节流间隔、端点上下文大小);分配设备上下文和传输环的 DMA 内存;注册中断处理函数;将根集线器(Root Hub)注册到 USB 核心。USB 核心通过 Root Hub 发现下游设备,后续的设备枚举和驱动匹配由 USB 核心处理,xHCI 控制器只负责底层的信号传输。

在嵌入式平台上,USB 控制器(如 DWC3、ChipIdea)通常作为平台设备通过设备树描述。设备树中包含控制器的寄存器基地址、时钟、复位信号、PHY(物理层)配置等。控制器驱动 probe 后,由内核创建 Root Hub 并触发 USB 总线枚举。

HPET

HPET(High Precision Event Timer)是 x86 平台上的高精度硬件定时器,由 Intel 和微软联合定义,精度可达 100ns 甚至 10ns 级别。HPET 包含一个 64 位递增计数器和最多 32 个独立的比较器(定时器通道),每个比较器可以独立配置为单次触发或周期触发模式,当计数器值与比较器值匹配时产生中断。

HPET 的设计初衷是替代传统的 PIT(Programmable Interval Timer,8254)和 RTC 定时器,提供更高精度和更多通道的定时服务。在内核的 clocksource 框架中,HPET 是可选的时钟源之一,通常与 TSC 共存。内核启动时会评估各时钟源的精度和可靠性,自动选择最优方案:如果 TSC 可用且标记为 invariant(恒定频率),内核优先使用 TSC 作为时钟源;如果 TSC 不可靠(早期 CPU 或虚拟化环境中),则回退到 HPET。

HPET 作为时钟事件设备(clockevent device)时,用于为内核提供单次定时和周期性定时的能力,驱动内核的调度器 tick 和高精度定时器(hrtimer)。不过现代 CPU 提供了 LAPIC Timer(Local APIC 内置的定时器),每个核心独立,精度高且不需要经过总线访问,因此内核通常优先使用 LAPIC Timer 作为 per-CPU 的时钟事件设备,HPET 作为备选。

/sys/devices/system/clocksource/clocksource0/available_clocksource 中可以查看系统支持的时钟源,/sys/devices/system/clocksource/clocksource0/current_clocksource 显示当前选中的时钟源。用户可以通过内核启动参数 clocksource=hpet 强制使用 HPET,但在大多数现代系统上这不是必要的。

EC

EC(Embedded Controller)是笔记本和服务器主板上的一个专用低功耗单片机(通常是 8051 或 ARM Cortex-M 内核),独立于主 CPU 运行。EC 负责管理一系列底层的平台功能,即使系统处于关机或待眠状态,EC 仍然在运行。

EC 的主要职责包括:键盘矩阵扫描(笔记本键盘的行列扫描和按键编码)、风扇调速(根据温度传感器读数通过 PWM 控制风扇转速)、电源按键和盖子开合检测(通知内核执行电源状态切换)、电池管理(充放电控制、电量上报)、LED 指示灯控制、热键处理(Fn 组合键)。在服务器上,EC 还负责 PSU(电源供应单元)监控、故障 LED 管理和机箱入侵检测。

EC 通过 LPC(Low Pin Count)总线或现代的 eSPI(Enhanced Serial Peripheral Interface) 总线与 CPU 通信。LPC 是 Intel 定义的低引脚数并行总线,带宽约 16MB/s,用于 EC 与 CPU 之间的低速命令和数据交换。eSPI 是 LPC 的替代方案,基于 SPI 协议,引脚更少、带宽更高(最高 66MHz),支持带外管理(OOB,即使在系统关机时也能通过 eSPI 访问 EC)。

在 Linux 内核中,EC 的驱动位于 drivers/platform/x86/(Intel 平台)或 drivers/acpi/(通过 ACPI EC 接口)。ACPI 定义了 EC 的标准接口,通过 ACPI 的嵌入式控制器区域(EC Region)访问 EC 的寄存器空间。内核的 acpi_ec 模块在启动早期初始化 EC,为 ACPI 的电源管理方法(如 _PTS_WAK)提供底层支持。用户空间可以通过 /sys/bus/acpi/devices/ 查看 EC 设备信息。对于服务器平台,IPMI(Intelligent Platform Management Interface)子系统提供了更完整的带外管理能力,但底层仍然依赖 EC 或 BMC(Baseboard Management Controller)硬件。

SATA/AHCI 控制器

SATA(Serial ATA)控制器是主板与 SATA 存储设备(机械硬盘、SATA SSD、光驱)之间的接口控制器。现代 SATA 控制器普遍实现 AHCI(Advanced Host Controller Interface) 规范,这是 Intel 定义的标准寄存器接口,所有支持 AHCI 的 SATA 控制器都可以使用同一个内核驱动(ahci)管理,无需各厂商单独提供驱动。

AHCI 控制器内部为每个 SATA 端口维护一组命令槽(Command Slot,通常 32 个)和一套命令列表(Command List)。内核将 SATA 命令(如读、写、DMA 传输)封装为命令表(Command Table),挂载到命令列表的空闲槽位上,然后向端口命令寄存器写入该槽位编号来触发执行。控制器硬件自动完成命令队列的调度、DMA 数据传输和状态更新,完成后通过中断通知内核。这种基于命令槽的设计天然支持 NCQ(Native Command Queuing),即硬盘可以同时接收多个 I/O 请求并按最优顺序执行,显著减少机械硬盘的磁头寻道次数。

AHCI 控制器的寄存器通过 MMIO 映射到物理地址空间,内核在 probe 时通过 PCI 配置空间的 BAR 获取基地址。控制器支持多种中断模式:传统 INTx、MSI 和 MSI-X,其中 MSI 是最常见的配置。在 ACPI 平台上,AHCI 控制器通过 ACPI 的 _ADR_GTF 方法配置端口参数。

在嵌入式平台上,SATA 控制器(如 ahci-mvebuahci-ceva)作为平台设备通过设备树描述,设备树中包含控制器的寄存器范围、时钟、复位信号和 PHY 配置。这些控制器驱动的功能与 PCI AHCI 驱动相同,只是初始化方式不同。

随着 NVMe SSD 的普及,SATA/AHCI 的带宽瓶颈(SATA 3.0 理论上限 600MB/s)日益明显,在高性能存储场景中逐渐被 PCIe NVMe 取代。但 SATA 仍然是大容量存储(机械硬盘、企业级冷存储)的主流接口,AHCI 驱动也是 Linux 内核中最稳定的存储驱动之一。

SPI Flash

SPI Flash 是主板上存放 BIOS/UEFI 固件的非易失性存储芯片,通过 SPI(Serial Peripheral Interface)总线连接到 CPU 或芯片组。SPI Flash 容量通常为 8MB-32MB,在系统断电后仍然保持数据不丢失,是计算机启动时 CPU 执行的第一段代码的来源。

SPI Flash 内部按区域划分,主要包含:UEFI 固件代码(系统启动的初始化代码和运行时服务)、ACPI 表(DSDT、SSDT 等硬件描述信息)、SMBIOS 数据(服务器硬件资产信息)、Intel ME/AMD PSP 固件(独立于主 CPU 运行的管理引擎固件)、以及 NVRAM 区域(存储启动配置和 CMOS 设置)。在现代安全启动(Secure Boot)流程中,SPI Flash 中还存放 UEFI 签名密钥数据库(db、dbx、KEK、PK)。

SPI Flash 的访问通过主板上的 SPI 控制器 进行,该控制器通常集成在 PCH 中。CPU 通过 MMIO 访问 SPI 控制器的寄存器,配置时钟频率、片选信号和数据传输参数,然后通过标准的 SPI 协议(CLK、MOSI、MISO、CS# 四根信号线)读写 Flash 芯片。读取速度通常为 30-50MB/s(Dual/Quad SPI 模式下可达更高),写入需要先擦除整个扇区(通常 4KB-64KB)再写入,写入寿命受擦写次数限制(典型 10 万次)。

在 Linux 中,SPI Flash 驱动位于 drivers/mtd/spi-nor/(MTD 子系统)或 drivers/spi/(SPI 子系统)。内核可以将 SPI Flash 映射为 MTD 设备(/dev/mtd0),支持读、写、擦除操作。用户空间常用工具 flashrom 可以读取、备份和更新 SPI Flash 中的固件内容。需要注意的是,在系统运行期间直接写入 BIOS 区域可能导致系统不稳定,flashrom 通常在写入前会进行安全检查并建议在纯 DOS 或专用环境下执行固件更新。在服务器平台上,BMC/IPMI 提供了更安全的带外固件更新方式,通过独立的 BMC 芯片访问 SPI Flash,不影响主机系统的运行。