B02 —— 内存条的身份证:SPD 芯片里到底存了什么
金句:没有 SPD 的内存,就像一个没有身份的人——系统不知道它是谁。
SPD 芯片的基本信息
每根 DDR 内存条都有一个 SPD(Serial Presence Detect)芯片,是一个 256 字节(或 DDR5 512 字节)的 EEPROM。
SPD 芯片规格:
容量:256 Bytes(DDR4)、512 Bytes(DDR5)
封装:8-pin SOIC,3mm × 5mm
位置:内存条金手指靠近右侧(缺口旁边)
通信:I2C 总线,地址 0x50/0x51/0x52(Channel 0/1/ECC)
I2C 总线特性:
- 时钟频率:400kHz(Fast Mode)
- 数据格式:MSB first
- 每个字节后需要 ACKSPD 字节分布(DDR4 256 字节详解)
DDR4 SPD 结构(256 Bytes):
Byte 0~1: 厂商标识(0x80=Samsung, 0xAD=SK Hynix, 0x98=Micron, 0x9E=Crucial)
Byte 2: 厂商特定(具体型号编码)
Byte 3: 颗粒类型(x4/x8/x16,0x0C=8Gb)
Byte 4: 颗粒组织(0x0A=8Gb x8 = 1GB per颗粒)
Byte 5~6: 密度(0x10=8GB, 0x20=16GB, 0x40=32GB)
Byte 7: Ranks(1=单 rank, 2=双 rank, 4=四 rank)
Byte 8: 排数(1=单面, 2=双面)
Byte 9: 电压(0x06=1.2V,D9=1.35V DDR4L)
Byte 12~13: JEDEC 标准频率(0x0C=1600, 0x14=2133, 0x18=2666, 0x1E=3200)
Byte 16~17: JEDEC CL-tRCD-tRP-tRAS
Byte 20~21: XMP 频率(如果有 XMP)
Byte 22~23: XMP 时序(CL-tRCD-tRP-tRAS)
Byte 24~25: XMP 电压
Byte 30: 内存条类型(0x02=DIMM, 0x01=SODIMM)
Byte 32~33: 模块高度(mm)
Byte 118~119:序列号(厂商流水号)
Byte 122~123:Manufacturing Date(年/周)
Byte 127: Checksum(所有前 127 字节的 CRC/校验和)从 SPD 数据重建内存信息
Linux 读取 SPD 示例(decode-dimms):
$ sudo decode-dimms
Handle 0x0027, DMI type 5, 24 bytes
Memory Array Handle: 0x0029
Error Information Handle: Not Provided
Total Width: 64 bits
Data Width: 64 bits
Size: 8192 MB
Form Factor: DIMM
Set: None
Locator: ChannelA-DIMM0
Bank Locator: BANK 0
Type: DDR4
Type Detail: Synchronous
Speed: 2666 MT/s
Manufacturer: Samsung
Part Number: M378A1K43BB2-CRC
Rank: 2
Configured Clock Speed: 2666 MT/s
SPD 时序参数(DDR4-2666 CL18):
CL=18, tRCD=18, tRP=18, tRAS=36
→ CL(ns) = 18/2666×2000 = 13.5nsXMP 和 EXPO 的 SPD 扩展
XMP/EXPO 实际上存在 SPD 的扩展区域(Byte 176~255):
Byte 176~191:XMP Header
- XMP 签名("XMP" 或 "EXPO")
- 版本号(XMP 2.0 / XMP 3.0)
- Profile 数量
Byte 192~255:XMP/EXPO Profile 数据
- Profile 1:DDR4-3600 CL18 1.35V
- Profile 2:DDR4-3200 CL16 1.35V(如果两个都支持)
BIOS 读取 SPD 时:
1. 先读取 Byte 12~13 的 JEDEC 频率(安全值)
2. 如果有 XMP,尝试读取 XMP Profile
3. 如果 CPU/主板支持 XMP 频率,使用 XMP 配置
4. 如果 XMP 超频失败(不稳定),回退到 JEDECSPD 在开机时的作用
BIOS 读取 SPD 的时机(POST 阶段):
1. 内存初始化第一步:读取 SPD
BIOS 通过 I2C 总线读取每个 DIMM 的 SPD
2. 解析 SPD:获取容量和速度
- 读 Byte 5~6 得到容量(如 16GB)
- 读 Byte 12~13 得到 JEDEC 频率(如 2666 MT/s)
- 读 Byte 20~21 得到 XMP 频率(如 3600 MT/s)
3. 选择频率和时序
- 如果启用 XMP,使用 XMP 配置(高频率+紧时序)
- 如果禁用 XMP,使用 JEDEC 配置
4. 内存 Training
- 基于 SPD 的时序参数,进行 Write Leveling 等校准
- 如果 SPD 数据损坏(checksum 错误),BIOS 可能忽略该 DIMM
5. 写入 ACPI 表
- 操作系统通过 ACPI SRAT(Static Resource Affinity Table)获取内存节点信息手动读取 SPD 的方法
Linux 下读取 SPD:
1. 安装 i2c-tools:
$ sudo apt install i2c-tools
2. 加载 EEPROM 模块:
$ sudo modprobe eeprom
3. 探测 I2C 总线:
$ sudo i2cdetect -l
i2c-1 808622C1 i2c <- 可能是内存 I2C 总线
4. 读取 SPD(假设在 0x50):
$ sudo i2cdump -y 1 0x50
0000: 80 8c 0c 0a 10 00 02 01 06 00 00 00 00 00 00 00
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...
5. 直接用 decode-dimms(更易读):
$ sudo decode-dimmsSPD 数据损坏和 ECC
SPD 数据损坏的症状:
1. Checksum 错误(Byte 127):
→ BIOS 忽略该 DIMM,不使用
→ 系统只能识别其他 DIMM
2. SPD 数据全为 0xFF:
→ EEPROM 损坏
→ BIOS 检测到并报错
SPD 损坏的原因:
- 静电放电(ESD)
- 电压冲击(开关机时的浪涌)
- 长时间高温(加速 EEPROM 老化)
ECC 内存的 SPD:
- ECC DIMM 有两个 SPD 芯片(0x50 和 0x52)
- 0x52 是给 ECC 控制器用的(单独校验)
- 如果 0x52 损坏,只有 ECC 功能失效,内存本身可能仍可用总结
- SPD 芯片:256B(DDR4)或 512B(DDR5)EEPROM,存储内存配置信息
- 关键字段:厂商/容量/频率/时序/电压/XMP profile/序列号/校验和
- XMP/EXPO:存在 SPD 扩展区域(Byte 176~255),多个 Profile 可选
- 开机流程:BIOS 读 SPD → 解析配置 → Training → 写入 ACPI 表
- Checksum:Byte 127 存储校验和,损坏会导致 BIOS 忽略该 DIMM
下篇预告(B03):计算机是怎么从按下电源键开始,一步一步把控制权交给操作系统的?Bootloader 的完整启动流程——从 BIOS/UEFI 到 GRUB 到 Kernel。
关注公众号「AI不着急」,回复”资料”获取内存学习路线图。
评论