☰
coreboot 的 Intel Sandy Bridge 北桥:Native RAM Initialization 与 ME Cleaner 技术全解析
2026/10/15 2:19:04 网站建设 项目流程
  • 固件
  • 嵌入式
  • 操作系统
  • 驱动开发

【免费下载链接】coreboot

Read-only mirror of https://review.coreboot.org/coreboot.git. Synced every hour. We don't handle Pull Requests.

项目地址:https://gitcode.com/gh_mirrors/co/coreboot
点击查看免费下载

本文围绕 coreboot 仓库中 Documentation/northbridge/intel/sandybridge/index.md 及其子文档,系统讲解 Intel 第二代(Sandy Bridge)与第三代(Ivy Bridge)酷睿处理器内存控制器(北桥)的初始化原理、原生内存初始化(Native RAM Initialization)的实现细节、频率选择策略、读取训练算法、MCHBAR 寄存器布局,以及如何通过 me_cleaner 缩减 Intel ME 固件以回收 Flash 空间。读完本文,你将掌握 coreboot 在 Sandy/Ivy Bridge 平台上"如何不依赖闭源 mrc.bin 完成内存初始化"的完整技术脉络,并能落地配置USE_NATIVE_RAMINIT、XMP/熔丝覆盖、MRC cache 复用、S3 恢复与 ME 分区裁剪等实战操作。

一、章节导航与文档总览

Documentation/northbridge/intel/sandybridge/index.md是 coreboot 中关于 Intel Sandy Bridge 北桥的官方文档入口,其目录树指向三份核心文档:

  • Native RAM Initialization(nri.md)
  • RAM initialization feature matrix(nri_features.md)
  • ME Cleaner(me_cleaner.md)

其中nri.md又通过 toctree 展开四份深度子文档:寄存器文档(nri_registers.md)、频率选择(nri_freq.md)、读取训练(nri_read.md)。这些文档构成了 coreboot 在 Sandy/Ivy Bridge 平台上开源内存初始化的第一手技术资料。

需要特别强调的是,这套文档的撰写背景是:Intel 的内存控制器属于闭源硬件,coreboot 社区通过逆向工程梳理出了可编程寄存器与训练算法,并在 src/northbridge/intel/sandybridge 下实现了完整的开源 raminit 代码(核心文件为raminit.c、raminit_native.c、raminit_common.c、raminit_iosav.c)。

二、内存初始化的职责范围

在 Sandy Bridge / Ivy Bridge 上,内存初始化代码必须承担大量工作(见nri.md),主要包括:

  1. 选择工作频率(Operating frequency)
  2. 选择公共时序(Common timings)
  3. 施加频率相关的补偿值
  4. 对所有已插 DIMM 的通道执行读取训练(Read training)
  5. 对所有已插 DIMM 的通道执行写入训练(Write training)
  6. 调整地址与命令信号的延迟网络
  7. 对所有已插 DIMM 的通道执行 DQS 训练
  8. 编程内存映射(Memory map)
  9. 上报 DRAM 配置
  10. 错误处理

这些职责与源码结构一一对应:raminit.c中的init_dram_ddr3()(src/northbridge/intel/sandybridge/raminit.c)是训练总入口,内部依次完成 SPD 探测、频率/CAS 选择、通道训练、ECC scrub、正常模式切换与report_memory_config()上报。

2.1 符号定义约定

nri.md与nri_freq.md、nri_read.md共用一套术语表,理解后续内容前必须先掌握:

符号含义单位有效范围
SCKDRAM 系统时钟周期时间s—
tCKDRAM 系统时钟周期时间(定点表示)1/256 ns—
DCK数据时钟周期时间(两个 SCK 沿之间的时间)s—
timAIO 相位(IO 信号的相位延迟)1/64 DCK[0-512)
SPD每条 DIMM 上 EEPROM 中厂商预置的时序bytes—
REFCK参考时钟,100 或 133MHz100, 133
MULTDRAM PLL 倍频器—[3-12]
XMP极限内存配置文件(Extreme Memory Profiles)——

在读取训练章节还会引入 DQS(Data Strobe,用于采样各 lane DQ 信号的数据选通信号)。

三、Native Raminit 与 mrc.bin 两条路线

nri_features.md开篇对比了内存初始化的两条可选路线,这在 Kconfig 中对应USE_NATIVE_RAMINIT开关(src/northbridge/intel/sandybridge/Kconfig):

路线一:Native raminit(开源)

  • 完全开源,代码就在src/northbridge/intel/sandybridge/raminit_native.c等文件中;
  • 对大多数板卡的大多数频率都能工作,但仍可能存在需要修复的错误;
  • 对在 romstage 中的位置没有要求。

路线二:mrc.bin raminit(闭源 blob)

  • 使用 Intel System Agent 二进制(默认路径3rdparty/blobs/northbridge/intel/sandybridge/systemagent-r6.bin,见MRC_FILE配置,src/northbridge/intel/sandybridge/Kconfig);
  • 没有已知错误,但必须被放置在 romstage 中的固定偏移处(raminit_mrc.c负责该路径)。

USE_NATIVE_RAMINIT默认值为y,即 coreboot 默认推荐使用开源实现。选择 mrc.bin 路径时,DCACHE_RAM_MRC_VAR_SIZE默认变为0x9000,用于给 MRC 预留变量空间。

3.1 已实现功能矩阵

nri_features.md给出了一份非常详尽的特性矩阵,这里完整转述并补充 Kconfig 佐证:

通道与容量

  • 单通道与双通道:支持、已实现、可用;
  • 最多 4 个插槽:支持、已实现、可用;
  • 每通道最多 4 个 rank:支持、已实现、可用。

从源码看,通道数、每通道槽位数的探测来自CAPID0_A寄存器(src/northbridge/intel/sandybridge/raminit.c 中的nb_slots_per_channel()与nb_number_of_channels())。

支持频率

  • DDR3-1066(533 MHz):支持、已实现、可用;
  • DDR3-1600(800 MHz):支持、已实现、可用;
  • DDR3-1866(933 MHz):支持、已实现、可用;
  • DDR3-2133(1066 MHz):支持、已实现、可用;
  • DDR3-1400(700 MHz)、DDR3-1800(900 MHz)、DDR3-2000(1000 MHz)、DDR3-2200(1100 MHz)、DDR3-2400(1200 MHz):Ivy Bridge 独占,自 coreboot 4.6 起支持、已实现、可用。

支持 CAS 延迟(CL)

  • CL6、CL7、CL8、CL9:支持且已实现,可用性存疑(矩阵中标为?);
  • CL10、CL11:支持、已实现、可用;
  • CL12、CL13、CL14、CL15:自 coreboot 4.6 起支持且已实现(CL13 标记为可用,其余标?)。

MRC cache(上次训练的时序缓存)

  • S3 恢复:支持、已实现、可用;
  • 正常启动:支持、已实现、可用,CRC16 差异时重置。

XMP 支持

  • XMP Profile 1:支持、已实现、可用(仅 1.5V 电压配置档);
  • XMP Profile 2:支持、已实现,但未激活(not activated)。

ECC 支持

  • ECC:自 coreboot 4.13 起支持、已实现、可用;对应 Kconfig 的RAMINIT_ENABLE_ECC(src/northbridge/intel/sandybridge/Kconfig)。

四、频率选择机制

nri_freq.md详细描述了频率选择的全过程,这是内存初始化中最先确定、影响全局的决策。

4.1 SPD 与 XMP

每条 DIMM 的 SPD(Serial Presence Detect)由厂商出厂烧录了多种时序,其中之一规定该 DIMM 的最大工作时钟频率,以定点值 tCK 存储,并被向下取整到最接近的支持频率。部分 SPD 还包含可选的 XMP 数据,宣告更高频率的"性能模式"。

XMP 生效条件:当前 raminit 能解析 XMP Profile 1 与 Profile 2,但只有XMP Profile 1在同时满足以下条件时才会被采用:

  • 宣告 1.5V 工作电压;
  • 通道内已安装 DIMM 数不超过 XMP 编码的限制。

否则回退到常规 SPD 时序。源码dram_find_spds_ddr3()中依次判断 XMP profile 有效性、dimms_per_channel限制与电压(src/northbridge/intel/sandybridge/raminit.c),条件不满足时调用spd_decode_ddr3()回落。

对应的 Kconfig 覆盖选项:

  • NATIVE_RAMINIT_IGNORE_XMP_MAX_DIMMS(自 coreboot 4.7 起):忽略 XMP 对每通道最大 DIMM 数的限制,允许每通道插两根 DIMM 即使 XMP 不允许;
  • NATIVE_RAMINIT_IGNORE_XMP_REQUESTED_VOLTAGE:允许使用请求 1.65V 的 XMP 配置,而不是回退到非 XMP 设置(源码 249-258 行验证了该分支)。

注意:NATIVE_RAMINIT_IGNORE_XMP_REQUESTED_VOLTAGE在仓库中同样存在,因为原生 raminit 目前只支持 1.5V 操作。Kconfig 帮助文本明确指出这些是"超频选项,请小心处理"(src/northbridge/intel/sandybridge/Kconfig)。

4.2 软熔丝(Soft fuses)

板卡制造商会在芯片中编程"软"熔丝,指示其支持的最大 DRAM 频率。但这类熔丝并不构成硬件限制,因此被称为"软"熔丝——可以被忽略:

  • Sandy Bridge 读取CAPID0_A的 DMFC 位(低 3 位);
  • Ivy Bridge 读取CAPID0_B的 DMFC 位((reg32 >> 4) & 0x7)。

源码get_mem_min_tck()(src/northbridge/intel/sandybridge/raminit_native.c)完整实现了这一逻辑:根据 CPU 基址修订(BASE_REV_SNB)选择寄存器,并按位段映射到TCK_533MHZ~TCK_1333MHZ。Ivy Bridge 的映射表明显更长,与特性矩阵中 Ivy Bridge 支持更多频率一致。

coreboot 默认遵守该上限,除非开启CONFIG_NATIVE_RAMINIT_IGNORE_MAX_MEM_FUSES(自 coreboot 4.7 起支持)。想要让内存跑在 DIMM 的"标称"频率上的超频用户需要启用它。忽略熔丝可能导致系统不稳定!

4.3 硬熔丝(Hard fuses)

"硬"熔丝由 Intel 编程,限制给定 CPU/板卡/芯片组可用的最大频率。当前没有寄存器可在设置频率前读取该限制——内存 PLL 无法锁定即表示所选倍频不可用,此时 coreboot 会逐级尝试下一个更小的倍频,直到 PLL 锁定。

4.4 Devicetree 覆盖

devicetree 寄存器max_mem_clock_mhz用于覆盖板卡制造商的"软"熔丝设置,可强制一个最小工作频率。它在芯片配置结构体中定义(src/northbridge/intel/sandybridge/chip.h),例如 666 表示 DDR3-1333、800 表示 DDR3-1600。get_mem_min_tck()中cfg->max_mem_clock_mhz非零时优先返回对应的 tCK。

4.5 参考时钟与倍频

Sandy Bridge 支持 133 MHz 参考时钟(REFCK),Ivy Bridge 额外支持 100 MHz。参考时钟与 DRAM 倍频按以下公式决定 DRAM 频率:

REFCK * MULT = 1 / DCK

注意:Ivy Bridge 的 100 MHz REFCK 自 coreboot 4.6 起支持。源码在find_cas_tck()中通过CAPID0_B的PLL_REF100_CFG位((reg32 >> 21) & 0x7)探测 100 MHz 参考时钟支持,并在normalize_tclk()中处理不支持的频率回落(src/northbridge/intel/sandybridge/raminit_native.c)。

Sandy Bridge 支持频率表(SCK × MULT × 133 MHz REFCK):

SCK [MHz]DDR [MHz]倍频 MULT参考时钟 REFCK
400DDR3-8003133 MHz
533DDR3-10664133 MHz
666DDR3-13335133 MHz
800DDR3-16006133 MHz
933DDR3-18667133 MHz
1066DDR3-21338133 MHz

Ivy Bridge 支持频率表(额外支持 100 MHz REFCK 档位,自 coreboot 4.6 起):

SCK [MHz]DDR [MHz]倍频 MULT参考时钟 REFCK
400DDR3-8003133 MHz
533DDR3-10664133 MHz
666DDR3-13335133 MHz
800DDR3-16006133 MHz
933DDR3-18667133 MHz
1066DDR3-21338133 MHz
700DDR3-14007100 MHz
800DDR3-16008100 MHz
900DDR3-18009100 MHz
1000DDR3-200010100 MHz
1100DDR3-220011100 MHz
1200DDR3-240012100 MHz

4.6 倍频选择算法

nri_freq.md给出了 coreboot 选择最大工作频率的伪代码:

if devicetree's max_mem_clock_mhz > 0: freq_max := max_mem_clock_mhz else: freq_max := soft_fuse_max_mhz for i in SPDs: freq_max := MIN(freq_max, ddr_spd_max_mhz[i])

可见:当插入不同最大频率的 DIMM 时,取最慢 DIMM 的频率,以避免对其超频。选定频率后得到 PLL 倍频;若 PLL 锁定(见"硬熔丝"一节)则该频率用于所有 DIMM,此后直到断电都无法再更改倍频;若 PLL 不锁定,则逐级使用更小的倍频直到找到可用的。

五、读取训练(Read Training)算法

nri_read.md深入解释了读取训练序列:其目的是补偿 DQS 与 SCK 之间的 skew(偏移),并找到最小可用的往返延迟(roundtrip delay)。

5.1 背景:Fly-By 拓扑

每块板卡的布线拓扑都不同,且可搭配任意的 DDR3 内存模块组合,这会在内存 lane 之间引入不同 skew。DDR3 引入的 "Fly-By" 布线拓扑构成了 DQS-SCK skew 的最大来源。内存代码需要实测 skew 并激活延迟门(delay gates)来"补偿"skew。

读取训练时,DRAM 与控制器进入特殊模式:每次读指令后,DRAM 输出预定义模式,控制器在给定延迟后采样 DQS。由于模式已知,每条 lane 的实际延迟即可被测量。读取训练编程的值只影响 DRAM 到内存控制器方向的数据传输!

5.2 硬件延迟能力

硬件包含两类延迟逻辑块:

  • 可将某 lane/rank 的 DQ/DQS 延迟一个或多个时钟周期的块(即 IO delay);
  • 可按每个 lane 以 1/64 DCK 为粒度延迟信号的块(即 IO phase)。

所有延迟值都通过写 MCHBAR 中的寄存器由软件控制。

IO phase:可在[0-512) * 1/64 DCK范围内调节。将其递增 64 等价于 IO delay 递增 1。

IO delay:将 DQ/DQS 信号延迟一个或多个时钟周期。

往返时间(Roundtrip time):内存控制器发出读命令后等待数据返回的时间。由于时钟域交叉、多个延迟实例与相位插值器,信号往返内存控制器的默认时间为 55 DCKs。真实往返时间必须实测:发出读命令后,计数器递减到零才激活输入缓冲。

5.3 训练算法步骤

算法需要同时确定三个参数:roundtrip time、IO delay、IO phase。

  1. 同步到数据相位(Synchronize to data phase):第一次测量对相位[0-64) * 1/64 DCK采样所有 DQS 值,搜索低数据符号(low data symbol)的中点,把 timA 调整到该相位,使后续测量与低数据符号对齐。代码假设初始 roundtrip time 使测量落在交替模式的数据相位中。

  2. 定位前导(Finding the preamble):与交替模式(010101...)的数据相位不同,前导由两个高数据周期组成。代码在保持 timA 不动的情况下递减 IO delay/RTT 并采样 DQS:读到 "low" 说明还在数据相位,读到 "high" 即找到前导。roundtrip time 与 IO delay 持续调整直到所有 lane 对齐。下图展示了 roundtrip time 为 49 DCKs、IO delay(蓝点处)为 6 DCKs 时 lane 0-3 的 timA 分布。

注意:采样数据已按 timA 平移,前导此时与相位对齐。

  1. 精细调整(Fine adjustment):由于 timA 仍指向数据符号中点,需加上偏移 32,使其指向前导的下降沿。为减小抖动引入的误差,相位从timA - 25扫描到timA + 25,每个点采样 DQS 100 次,找出每个上升沿(实为前导下降沿)的中点作为最终 IO phase。结果如图所示:lane 0-2 会被调整 -10 相位,而 lane 3 本身已经正确。

nri_read.md还附了三张不同 roundtrip 值(55、54、53 DCKs)下的 timA 采样图,直观展示了信号中的抖动——每次采样发生在不同的循环迭代中,且结果寄存器每个 lane 只有一个位:

在源码侧,训练序列的硬件执行依赖 IOSAV(I/O Subsequence and Validation)机制:raminit_iosav.c中iosav_write_sequence()将 MRS、PRE、ACT、RD、WR、ZQCS 等命令子序列编程进 IOSAV 寄存器组并触发执行(src/northbridge/intel/sandybridge/raminit_iosav.c),训练结果则通过文档描述的 lane training result 寄存器读回。

六、MCHBAR 寄存器(非官方文档)

nri_registers.md是社区逆向出来的 MCHBAR 寄存器空间非官方文档(文档自己声明:不完整且可能有错,请谨慎对待)。MCHBAR 通过 PCI(0:0:0) 设备的寄存器 0x48 启用。

6.1 寄存器编址规律

文档按"通道 0 × lane 0-7"组织,每个 lane 有三类寄存器,呈现清晰的偏移规律:

  • Lane training result 寄存器(64 位,如MCHBAR + 0x4、0x204、0x404...,间隔 0x200):位 0-63,每一位对应 64 个 IO delay 设置之一的训练结果;
  • Read delay settings 寄存器(32 位,Rank 0-3 各一,如MCHBAR + 0x10/0x14/0x18/0x1c):包含 IO phase、DQS 上升沿相位、IO delay、DQS 下降沿相位;
  • Write delay settings 寄存器(24 位,Rank 0-3 各一,如MCHBAR + 0x20/0x24/0x28/0x2c):包含 DQ IO phase、DQS IO phase、DQS IO delay、DQ IO delay。

以MCHBAR + 0x10(Channel 0、lane 0、Rank 0 的读延迟设置寄存器)为例:

位段描述
0:5IO phase shift,单位 1/64 DCK
6:11DQS phase shift on rising edge,单位 1/64 DCK
16:18IO delay,单位 DCK
20:25DQS phase shift on falling edge,单位 1/64 DCK

写延迟寄存器(如MCHBAR + 0x20)布局如下:

位段描述
0:5DQ IO phase shift,单位 1/64 DCK
8:13DQS IO phase shift,单位 1/64 DCK
15:17DQS IO phase shift,单位 DCK
20DQ IO phase shift,单位 DCK

6.2 特殊寄存器摘要

除逐 lane 的延迟寄存器外,文档还记录了以下关键全局寄存器(均在 Channel 0 语境下):

  • MCHBAR + 0x1810COMP1 Register:ODT(位 9-11)、CLK drive up(位 21-23)、CTRL drive up(位 27-29);
  • MCHBAR + 0x320cCommand crossover enable Register:CLK phase low(位 0-5)、CLK phase high(位 12)、Enable hardware(位 14)、Enable on slot 1/2(位 17/27);
  • MCHBAR + 0x4000TC_DBP:tRCD、tRP、CAS、CWL、tRAS 各 4 位;
  • MCHBAR + 0x4004TC_RAP:tRRD、tRTP、CKE、WTR、tFAW、tWR,以及 Command 3-state options(位 29)与 CMD stretch(位 30-31,00b=1N、10b=2N、11b=3N);
  • MCHBAR + 0x400cOTHP ODT control:tXPDLL、tXP、ODT stretch 等;
  • MCHBAR + 0x4024Roundtrip time Register:RTT Rank 0/1 DIMM 0/1 各 8 位;
  • MCHBAR + 0x4028SC_IO_LATENCY:IO latency 与 roundtrip - I/O compensation;
  • MCHBAR + 0x4200~0x423cRAM training queue:地址、命令 IO(!RAS/!CAS/!WE)、cooldown(命令后等待的时钟周期数),0x4284为执行队列的启动寄存器;
  • MCHBAR + 0x4298/0x4e98TC Refresh parameters:tREFI(位 0-15)、tRFC(位 16-24)、tREFIx9(位 25-32,应编程为8.9 * tREFI / 1024);
  • MCHBAR + 0x42a4SRFTP:tXSDLL、tXS_offset、tZQOPER、tMOD;
  • MCHBAR + 0x4cb0PM Power-down config:PDWN_idle_counter(位 0-7,最小应大于等于最差往返时间加突发长度)、PDWN_mode(位 8-10:0x0=No power down、0x1=APD、0x2=PPD、0x3=APD+PPD、0x6=PPD-DLLoff、0x7=APD+PPD+DLLoff);
  • MCHBAR + 0x4e94TC Refresh parameters:OREF_RI、Refresh_HP_WM、Refresh_panic_WM;
  • MCHBAR + 0x5000Global channel size control:CH_A(位 0-1)、CH_B(位 2-3)、CH_C(位 4-5)定义最大/中等/最小通道;
  • MCHBAR + 0x5004Address Decode Register:DIMMA/DIMMB 容量(256 MB 倍数)、DAS 槽位映射、rank 数、DRAM 宽度(x8/x16)、Rank interleave enable、Enhanced interleave enable、High order Rank interleave 与 ECC 使能(位 24-25:00b=无 ECC、01b=IO 上 ECC、11b=IO 与 ECC 逻辑均开启);
  • MCHBAR + 0x5030Global DDR3 control:DDR reset(位 1)、DCLK enable(位 2)、IO reset(位 5);
  • MCHBAR + 0x5034Version Register:MRC version;
  • MCHBAR + 0x5060PM Self refresh config:Idle_timer 与 SR_Enable;
  • MCHBAR + 0x5e00MC_BIOS_REQ:选定的倍频(位 0-7,100 MHz 时 [7,12]、133 MHz 时 [3,19])、位 8 指示 100 MHz 参考时钟(Ivy Bridge 独有)、位 31 为 PLL busy;
  • MCHBAR + 0x5e04MC_BIOS_DATA:当前活动倍频;
  • MCHBAR + 0x5f08RCOMP control:Force RCOMP(位 8)。

这些寄存器与上文算法一一对应:比如读取训练算法最终就是把 IO phase、IO delay、roundtrip time 分别写入Read delay settings与Roundtrip time寄存器,训练队列寄存器则承载 IOSAV 命令序列的地址与冷却周期。

七、SMBIOS 上报与 dmidecode 验证

内存初始化完成后,coreboot 通过 SMBIOS type 17 上报内存配置(自 coreboot 4.4 起支持)。在 GNU/Linux 下运行dmidecode -t 17即可查看:

Handle 0x0045, DMI type 17, 34 bytes Memory Device Array Handle: 0x0042 Error Information Handle: Not Provided Total Width: 64 bits Data Width: 64 bits Size: 8192 MB Form Factor: DIMM Set: None Locator: ChannelB-DIMM0 Bank Locator: BANK 2 Type: DDR3 Type Detail: Synchronous Speed: 933 MHz Manufacturer: 0420 Serial Number: 00000000 Asset Tag: 9876543210 Part Number: F3-1866C9-8GSR Rank: 2 Configured Clock Speed: 933 MHz

重要解读:dmidecode 打印的内存频率是当前活动频率,既不是双倍数据率,也不是 SPD 中编码的最大频率。例中 DDR3-1866 的"Speed"显示为 933 MHz(即实际工作频率 SCK,非标称 1866 MT/s 的双倍速率)。

对应源码实现位于raminit.c中的report_memory_config(),并最终汇入setup_sdram_meminfo()(src/northbridge/intel/sandybridge/raminit.c)。

八、MRC Cache:训练结果复用与 S3 支持

命名澄清:MRC cache这个名字可能造成误导——在 Native RAM init 场景下并没有 MRC(Memory Reference Code),只是历史原因沿用了这个名称。

原理:MRC cache 是 Flash 中 coreboot 可写的部分。启动结束时 coreboot 把内存训练结果写入 Flash 以备后续使用,因为内存训练非常耗时。存储训练结果有两个收益:

  1. 正常启动时更快(跳过重新训练);
  2. 支持 S3 恢复——S3 恢复时 RAM 内容还在但训练结果无法存在 RAM 里(因为必须先配置好内存控制器才能访问 RAM)。

失效机制:内存配置改变时必须使 MRC cache 失效。检测方法是对每根 DIMM 计算 CRC16 并存入 MRC cache,下次启动比对。

源码链路完整印证了文档(自 coreboot 4.4 起):

  • 保存:save_timings()调用mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, ctrl, sizeof(*ctrl))(src/northbridge/intel/sandybridge/raminit.c),在非 fast boot 的启动末尾执行;
  • 加载:mrc_cache_current_mmap_leak()尝试读取缓存(src/northbridge/intel/sandybridge/raminit.c);
  • 校验:缓存读取后先比对 CPUID(防止换过 CPU),再通过verify_crc16_spds_ddr3()校验 SPD CRC16 是否与当前 DIMM 一致(src/northbridge/intel/sandybridge/raminit.c);
  • S3 兜底:S3 恢复时若无可用缓存,直接system_reset()重新冷启动(src/northbridge/intel/sandybridge/raminit.c)。

raminit_mrc.c(mrc.bin 路线)同样通过save_mrc_data()/prepare_mrc_cache()使用同一套缓存基础设施(src/northbridge/intel/sandybridge/raminit_mrc.c)。

九、错误处理与调试

9.1 降级策略

目前唯一支持的错误处理方式是:禁用失败的通道并重启内存训练序列(自 coreboot 4.5 起)。因为内存通道彼此独立运行,这种降级很可能成功。若没有任何 DIMM 能被初始化,coreboot 会调用die()停机——屏幕保持黑屏直到断电。部分平台提供额外的反馈指示。

init_dram_ddr3()末尾的实现是:首次try_init_dram_ddr3()失败后,printram("Disable failing channel."),通过disable_channel(&ctrl, GET_ERR_CHANNEL(err))屏蔽失败通道再次尝试;若仍失败则die("raminit failed")(src/northbridge/intel/sandybridge/raminit.c)。

诊断技巧:如果发现dmidecode -t 17只报告了实际内存容量的一半,很可能是发生了致命的初始化失败。项目的基本立场是:一块能工作但物理内存更少的板子,远比一块根本无法启动的板子要好。

9.2 调试与日志

  • 尝试对调内存模块,或换不同品牌的内存;
  • 若无效,可查阅"Debugging"章节或在 ticket.coreboot.org 上报工单,附上用 EHCI debug 抓取到的完整 RAM init 日志;
  • 启用 Kconfig 选项DEBUG_RAM_SETUP可获得详尽的内存训练日志(该选项由NORTHBRIDGE_INTEL_SANDYBRIDGE自动 select,即HAVE_DEBUG_RAM_SETUP,src/northbridge/intel/sandybridge/Kconfig)。

调试时建议使用外部调试器(串口或 EHCI debug 棒)——内存初始化失败时板子可能完全无法启动,CBMEM 也就不可用。

9.3 Lenovo ThinkPad 专属死亡指示

Lenovo ThinkPad 有额外特性来指示"RAM init 失败且 coreboot 已死亡"(die()由此得名)。通过 Kconfig 选项(自 coreboot 4.7 起):

  • H8_BEEP_ON_DEATH:蜂鸣提示;
  • H8_FLASH_LEDS_ON_DEATH:闪烁 LED 提示。

对应实现位于 EC 驱动中(src/ec/lenovo/h8/Kconfig 与 src/ec/lenovo/h8/panic.c),panic.c中分别处理 LED 闪烁与蜂鸣逻辑。

十、ME Cleaner:裁剪 Intel ME 固件

me_cleaner.md介绍如何在构建流程中"清理"Flash 中的 ME 分区。清理会尽量多地移除 ME 固件分区中的代码;在这种状态下ME 会报错并停止运行。

重要警告:使用"清理过的"ME 分区可能引发问题,使用前务必仔细评估!

10.1 已观察到的副作用

使用 cleaned ME 后的已知问题包括:

  • LPC 总线不稳定:
    • SuperIO 功能异常;
    • TPM 功能异常;
    • 高总线活动时系统随机关机。

报 Bug 前请务必用未修改的 IFD 和 ME 段测试,再向 coreboot 项目报告问题。

10.2 缩减 Intel ME 固件体积教程

默认情况下,清理后的 ME 固件仍会占据与原分区相同的空间。可以修改固件分区布局来回收空间给 coreboot 使用:缩减后的 Intel ME 固件让ifd、gbe、me三个区域合计占用不到 128 KiB,剩余空间全部留给bios区域。

第 1 步:获取完整 ROM

需要一份包含完整 Intel ME 固件的完整可用 ROM。

第 2 步:运行 me_cleaner

对一个完整 ROM(下称fulldump.rom)运行 me_cleaner。完整 ROM 应包含:IFD、完整可用的 Intel ME、GbE(可选)、BIOS(任意固件)。

./util/me_cleaner/me_cleaner.py -D patched_desciptor.bin -M stripped_me.bin fulldump.rom -t -r -S

生成的产物:

  • 打补丁的 IFD:patched_desciptor.bin
  • 裁剪后的 Intel ME:stripped_me.bin

打补丁的 IFD 设置了AltMeDisable位,并修改了 Flash 布局。me_cleaner 脚本在仓库 util/me_cleaner/me_cleaner.py 中,其命令行参数与-D(提取描述符)、-M(提取 ME 镜像)、-S(软禁用)、-r(重定位 FTPR 分区)、-t(截断 ME 分区空余部分)一一对应(util/me_cleaner/me_cleaner.py)。

注意:coreboot 允许在构建过程中选择CONFIG_ME_CLEANER,但它不会重做 Flash 布局,只会从 ME 中移除文件并设置 AltMeDisable 位。

第 3 步:构建 coreboot
  1. 把上一步生成的两个文件纳入 coreboot 构建系统;
  2. 增大 CBFS 容量:
    • 8 MiB ROM:0x7E0000
    • 12 MiB ROM:0xBE0000
    • 16 MiB ROM:0xFE0000
  3. 因为已经手动跑过 me_cleaner,不要在 Kconfig 中再次启用 me_cleaner。
第 4 步:刷写 ROM

由于修改了布局,必须用外部编程器把完整 ROM刷入 Flash(刷写教程见 Documentation/tutorial/flashing_firmware/index.md)。确保 ROM 包含所有分区:IFD、EC(可能未用)、GbE(可能未用)、ME、BIOS。

十一、结语

coreboot 在 Sandy/Ivy Bridge 平台上的技术积累是一份难得的"开源固件逆向内存控制器"范本:从CAPID0_A/B熔丝读取、SPD/XMP 解析、REFCK * MULT频率公式、timA/IO delay 读取训练算法,到MCHBAR + 0x4一类的寄存器位段描述,全部沉淀在 Documentation/northbridge/intel/sandybridge 下的文档中,并与 src/northbridge/intel/sandybridge 的源码实现一一呼应。对于希望理解内存训练原理、参与 coreboot 开发或尝试 ME 裁剪的读者,这一组文档连同raminit.c、raminit_native.c、raminit_iosav.c、nri_registers.md是最直接的起点。

  • 固件
  • 嵌入式
  • 操作系统
  • 驱动开发

【免费下载链接】coreboot

Read-only mirror of https://review.coreboot.org/coreboot.git. Synced every hour. We don't handle Pull Requests.

项目地址:https://gitcode.com/gh_mirrors/co/coreboot
点击查看免费下载
上一篇:Kleros Curate 的 MetaEvidence 检索与编写:以 onchain 事实源驱动 Token 化审核列表的完整指南
下一篇:Vuls内存优化案例研究:从问题诊断到解决方案实施

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询