eMMC 协议详解

面向对象:嵌入式固件工程师(eMMC 设备端/主机端固件开发)
适用规范:JEDEC JESD84-B51(eMMC 5.1)及此前各版本
文档性质:工程参考文档,命令号、寄存器偏移等关键信息以 JEDEC 规范及 Linux 内核实现(include/linux/mmc/mmc.hdrivers/mmc/core/mmc.c)为准
版本:v1.0 | 日期:2026-08-15

1. eMMC 概述

1.1 什么是 eMMC

eMMC(embedded MultiMediaCard,嵌入式多媒体卡)是一种将 NAND Flash 存储介质存储控制器(Controller) 封装在同一芯片(BGA 封装)内的嵌入式存储标准,由 JEDEC(JESD84 系列规范)定义。控制器内部运行固件(Firmware),对主机(Host)屏蔽了 NAND 的物理特性(擦除、磨损、坏块、ECC 等),向上提供与”块设备”类似的标准接口。

eMMC 的定位:

  • 面向嵌入式系统:手机、平板、机顶盒、车载、工控、IoT 等,作为不可拆卸的板载存储。
  • 替代方案:UFS(面向高性能移动设备,串行接口)、SD/eMMC 卡(可拆卸)、SPI NOR/NAND(低端)。
  • 接口简单:并行总线(CLK/CMD/DAT0–7),主机侧无需复杂 PHY,成本低、成熟度高。

1.2 版本演进

版本 JEDEC 规范 主要新增特性
eMMC 4.0 JESD84-A41 基础协议;引入 CMD6 SWITCH、EXT_CSD、HS 模式(26/52 MHz)、Boot 分区
eMMC 4.1 JESD84-A42 安全性增强(RPMB 前身)、中断
eMMC 4.2 JESD84-A43 小幅修订
eMMC 4.3 JESD84-A44 增强/通用分区(GPP)、RPMB、可靠写、Sanitize 前身特性
eMMC 4.4 / 4.41 JESD84-A441 DDR 模式(52 MHz DDR,104 MB/s)、8-bit 总线普及
eMMC 4.5 JESD84-B45 HS200(200 MHz SDR,200 MB/s)、Cache、Packed Commands、BKOPS、HPI、TRIM
eMMC 5.0 JESD84-B50 HS400(200 MHz DDR,400 MB/s)、FFU(现场固件升级)、Sanitize、数据标签
eMMC 5.1 JESD84-B51 命令队列 CMDQ(深度≤32)、HS400ES(增强选通)、生命周期监控
5.1A / 5.1B JESD84-B51A/B51B 勘误与澄清(如生产日期字段调整)

注:JEDEC 已将 eMMC 冻结在 5.1,后续存储演进由 UFS 承担。当前量产 eMMC 绝大多数为 5.0/5.1。

各版本对应 EXT_CSD_REV(EXT_CSD 字节 192):

EXT_CSD_REV 对应版本
1 4.0
2 4.1
3 4.2
4 4.3
5 4.4 / 4.41
6 4.5
7 5.0
8 5.1

1.3 eMMC 与 NAND、SD、UFS 的关系

特性 裸 NAND eMMC SD 卡 UFS
接口 并行 I/O 并行(CLK/CMD/DAT) 并行(同源协议) 串行 M-PHY
控制器 无(主机直接管) 内置 内置 内置
坏块/ECC/磨损均衡 主机负责 控制器负责 控制器负责 控制器负责
主机复杂度
典型带宽 依颗粒 最高 400 MB/s(HS400) 最高 ~200 MB/s(UHS-II 除外) 最高 2.9 GB/s(UFS 3.1)
使用场景 高密度低成本 中低端嵌入式 可拆卸存储 高端手机/SSD 级

eMMC 协议与 SD 同源(SD 由 MMC 演进而来),命令集高度相似,但存在关键差异(见 §4.7),开发时不可混用。

1.4 分层架构

从主机固件开发视角,整个系统分三层:

1
2
3
4
5
6
7
8
9
10
11
12
13
┌─────────────────────────────────────────────┐
│ 主机(SoC/CPU) │
│ ├─ 存储驱动/文件系统(块设备层) │
│ └─ eMMC 主机控制器(Host Controller,如 │
│ DW-MMC、SDHCI、厂商自研 IP) │
├─────────────────────────────────────────────┤
│ 物理总线:CLK / CMD / DAT0–7 / DS / RST_N │
├─────────────────────────────────────────────┤
│ eMMC 设备 │
│ ├─ 主机接口(命令解码、响应生成、数据 FIFO) │
│ ├─ 控制器固件(FTL、磨损均衡、坏块管理、GC) │
│ └─ NAND Flash 阵列 │
└─────────────────────────────────────────────┘

从 eMMC 设备固件开发视角,协议栈可进一步拆分为:

  1. 物理层:CLK 同步、上电复位、信号电压(VCC/VCCQ)。
  2. 链路层:命令/响应帧格式、CRC7/CRC16 校验、位宽(x1/x4/x8)、SDR/DDR。
  3. 命令层:命令集、状态机(idle→ready→ident→stby→tran→data→rcv→prg→dis)。
  4. 寄存器层:OCR/CID/CSD/EXT_CSD 的读取与维护。
  5. 数据层:块读/写、擦除/TRIM/Discard、命令队列、RPMB。
  6. 内部管理层(不可见):FTL、磨损均衡、坏块管理、垃圾回收、掉电保护、寿命监控。

2. 硬件接口与信号

2.1 引脚定义

eMMC 采用 BGA 封装(典型 153-ball FBGA),信号定义如下:

信号 方向 说明
CLK Host→Device 时钟输入,全部信号在该时钟边沿采样。注意:CLK 是单端输入,设备不产生时钟
CMD 双向 命令/响应线,开漏(初始化阶段)或推挽(高速阶段)
DAT0–DAT7 双向 数据线,支持 x1/x4/x8 三种位宽
DS Device→Host 数据选通(Data Strobe),仅在 HS400 模式下由设备输出,与数据同相的 200 MHz 时钟
RST_N Host→Device 硬件复位(低有效)。是否可用由 EXT_CSD[162] RST_N_FUNCTION 决定
VCC 主电源(Core/Flash 供电):2.7–3.6 V
VCCQ I/O 电源:3.3 V / 1.8 V / 1.2 V,决定信号电平
VSS / VSSQ

2.2 上电与复位

上电时序(主机侧必须满足):

  1. 将 VCC、VCCQ 拉至工作电压。
  2. 等待电源稳定(power ramp 时间依器件不同,规范要求主机至少等待 1 ms 以上再开始初始化)。
  3. 保持 CLK 运行(初始化阶段频率 ≤ 400 kHz,即 f_OD/f_init),CMD/DAT 上拉或处于正确状态。
  4. 若 RST_N 被使能,可拉低 ≥ 1 个时钟周期完成硬件复位;否则用 CMD0 软件复位。

设备侧要求:上电后设备在收到有效命令前保持 idle 状态;检测到供电异常(掉电/欠压)时必须安全停止(见 §12.7 掉电处理)。

2.3 电压与信号电平

  • VCC:3.3 V 档(2.7–3.6 V),给控制器与 NAND 供电。
  • VCCQ:I/O 信号电平,支持 3.3 V / 1.8 V / 1.2 V。HS200/HS400 模式要求 1.8 V 或 1.2 V 信号。
  • 设备支持的电压窗口通过 OCR 寄存器 上报(§5.1),主机通过 CMD1 协商。
  • 信号电压切换 是纯主机侧行为(切换 VCCQ 电源轨),无专用命令;切换后必须重新初始化或按规范流程恢复(典型做法:降频 → 切电压 → 重新调谐/初始化)。

2.4 总线宽度与推挽/开漏

  • 初始化阶段:x1 位宽、开漏(Open-Drain),便于多设备仲裁(eMMC 通常单设备,但协议保留广播命令语义)。
  • 进入高速阶段后:推挽(Push-Pull),位宽可切至 x4/x8。
  • 位宽切换通过 CMD6 写 EXT_CSD[183] BUS_WIDTH 完成(见 §6.4、§7.3)。

2.5 关键时序参数(设备侧上报)

主机必须依据设备上报值设置超时:

参数 来源 说明
TAAC / NSAC CSD[119:104] 数据访问时间(Nac 计算依据),即从收到 CMD17/18 到首块数据的时间上限
max_dtr(TRAN_SPEED) CSD[103:96] 最大传输速率
S_A_TIMEOUT EXT_CSD[217] Sleep/Awake(CMD5)超时,单位 100 ns × 2^n
ERASE_TIMEOUT_MULT EXT_CSD[223] 擦除超时 = 300 ms × 该值
TRIM_MULT / SEC_TRIM_MULT / SEC_ERASE_MULT EXT_CSD[232]/[229]/[230] TRIM/安全 TRIM/安全擦除超时倍率
PART_SWITCH_TIME EXT_CSD[199] 分区切换超时,单位 10 ms(不小于 300 ms 兜底)
GENERIC_CMD6_TIME EXT_CSD[248] CMD6 通用切换超时,单位 10 ms
POWER_OFF_LONG_TIME EXT_CSD[247] 长关机通知(POWER_OFF_LONG)超时,单位 10 ms
OUT_OF_INTERRUPT_TIME EXT_CSD[198] HPI 中断超时,单位 10 ms

3. 通信基础:命令与响应

3.1 命令帧格式(48 bit)

主机在 CMD 线上发送的命令为固定 48 bit

字段 位位置 位宽 说明
Start bit 47 1 bit 起始位,恒为 `0`
Dir(Transmission) bit 46 1 bit 传输位:`1` = 主机→设备(命令);`0` = 设备→主机(响应)
CMD index bit 45:40 6 bit 命令索引,共 64 条命令(CMD0–CMD63,实际定义见 §4)
Argument bit 39:8 32 bit 命令参数,随命令不同含义不同(地址、参数、标志等)
CRC7 bit 7:1 7 bit 对 bit[46:1](传输位至参数末位)计算,生成多项式 `x^7 + x^3 + 1`(0x89)
End bit 0 1 bit 结束位,恒为 `1`

3.2 响应帧格式

3.2.1 48 bit 响应(R1/R1b/R3/R4/R5/R6/R7)

字段 位位置 位宽 说明
Start bit 47 1 bit 起始位,恒为 `0`
Dir(Transmission) bit 46 1 bit 传输位:`0` = 设备→主机(响应)
保留 bit 45:40 6 bit 恒为 `0`
内容 bit 39:8 32 bit 响应内容(Card Status / OCR / 参数等),随响应类型不同而异
CRC7 bit 7:1 7 bit 响应帧的 CRC7
End bit 0 1 bit 结束位,恒为 `1`

各 48 bit 响应类型:

类型 内容(bit[39:8]) 说明
R1 32 bit Card Status 常规状态响应(多数命令)
R1b 32 bit Card Status + DAT0 忙信号 R1 且命令执行期间设备拉低 DAT0(写、擦除、切换等)
R3 32 bit OCR 仅 CMD1,上报工作电压与能力
R4 32 bit 参数 仅 CMD39 FAST_IO(工厂/调试用)
R5 32 bit 参数 仅 CMD40 GO_IRQ_STATE
R6 RCA(16 bit) + Card Status(16 bit) 仅 CMD3,返回相对地址
R7 保留 8 bit + 电压(8 bit) + 回显(24 bit) CMD8(本协议中为 SEND_EXT_CSD 命令,无 R7;R7 属 SD 兼容定义,eMMC 不产生)

3.2.2 136 bit 响应(R2)

R2 用于 CMD2(ALL_SEND_CID)、CMD9(SEND_CSD)、CMD10(SEND_CID):

字段 位位置 位宽 说明
Start bit 135 1 bit 起始位,恒为 `0`
Dir(Transmission) bit 134 1 bit 传输位:`0` = 设备→主机(响应)
保留 bit 133:128 6 bit 恒为 `0`
内容(CID / CSD) bit 127:1 127 bit CID 或 CSD 寄存器内容
CRC7 bit 7:1 7 bit 对 bit[134:1](整个内容区)计算
End bit 0 1 bit 结束位,恒为 `1`

3.3 CRC7 计算

  • 多项式:x^7 + x^3 + 1(即 0x89),初始值 0x00。
  • 覆盖范围:传输位开始至参数位结束(48 bit 帧的 bit[46:1])。
  • 固件实现要点:主机控制器通常硬件完成 CRC 生成/校验;设备固件侧需对收到的 CMD 校验 CRC、对发出的 Response 生成 CRC。CRC 错误时设备忽略该命令,不更新状态(部分命令按规范返回 COM_CRC_ERROR 状态位)。

3.4 数据线上的帧(CRC16)

数据块在 DAT 线上传输时,每块后跟 16 bit CRC(多项式 x^16 + x^12 + x^5 + 1,0x1021):

1
DAT0..n: [数据块 512B][CRC16(16 bit)][End bit(1)]

读方向:设备发送;写方向:主机发送,设备校验。CRC 校验失败的处理见 §8.6。

3.5 命令类型(协议语义)

类型 说明
bc(Broadcast) 广播命令,无响应 CMD0、CMD4、CMD15
bcr(Broadcast with response) 广播命令,所有设备同时响应 CMD1、CMD2、CMD3
ac(Addressed) 点对点命令,无数据 CMD7、CMD9、CMD13…
adtc(Addressed with data transfer) 点对点命令,带数据 CMD17/18/24/25、CMD8

3.6 命令类别(Command Classes,CCC)

CSD[95:84] 的 12 位 CCC 表明设备支持的命令类(固件应据其裁剪命令集):

类别 包含命令
0 基本 CMD0,1,2,3,4,7,9,10,12,13,15
1 流式读 CMD11(遗留)
2 块读 CMD16,17,18
3 流式写 CMD20(遗留)
4 块写 CMD16,24,25,26,27
5 擦除 CMD32–38
6 写保护 CMD28,29,30
7 锁卡 CMD16,42
8 厂商特定 CMD55,56,57 等
9 I/O 模式 CMD5,39,40
10 切换 CMD6

3.7 设备状态机

R1 响应的 Card Status[12:9](CURRENT_STATE)返回当前状态:

1
2
3
4
5
idle ──CMD1──▶ ready ──CMD2──▶ ident ──CMD3──▶ stby ──CMD7──▶ tran

idle ◀──CMD0──(任意状态) ├─▶ data(读/写传输中)
dis ◀──CMD15──(stby/tran) ├─▶ rcv(写数据接收中)
prg ◀──────────(编程/擦除忙) └─▶ dis(非激活)
状态 说明
idle 0 上电/复位后,仅响应 CMD0/CMD1
ready 1 CMD1 协商成功(OCR busy 清除)
ident 2 CMD2 发送 CID 后
stby 3 已分配 RCA(CMD3 完成),等待 CMD7 选中
tran 4 已选中,可执行数据传输命令
data 5 数据传输中(读方向)
rcv 6 写数据接收中
prg 7 编程/擦除中(DAT0 忙)
dis 8 CMD15 后非激活,只能复位恢复

主机固件通常用 CMD13(SEND_STATUS)轮询状态/忙;设备固件则必须精确维护状态机与每个命令的合法状态转换。


4. 命令集详解

4.1 完整命令表(CMD0–CMD63)

下表汇总 eMMC 全部命令(标注类型/参数/响应/类别,参照 JEDEC 5.1 与 Linux mmc.h)。

CMD 名称 类型 参数 响应 类别 说明
0 GO_IDLE_STATE bc 0x0(或 0xFFFFFFFA 进入 Boot 模式) 0 复位至 idle;带 0xFFFFFFFA 参数用于 Boot 操作(§9)
1 SEND_OP_COND bcr [31:0] OCR(电压窗口) R3 0 电压协商;同时可令设备退出 Boot 模式
2 ALL_SEND_CID bcr 0x0 R2(CID) 0 读取全部设备的 CID
3 SET_RELATIVE_ADDR bcr [31:16] RCA R6 0 为设备分配相对地址 RCA
4 SET_DSR bc [31:16] DSR 0 设置驱动级寄存器(若 CSD.dsr_imp=1)
5 SLEEP_AWAKE ac [31:16] RCA,[15] 唤醒标志 R1b 9 睡眠(flag=0)/唤醒(flag=1),超时见 S_A_TIMEOUT
6 SWITCH ac 见 §4.3 R1b 10 写/切换 EXT_CSD 字段,是模式切换的核心命令
7 SELECT/DESELECT_CARD ac [31:16] RCA(0=去选) R1b 0 选中/取消选中设备
8 SEND_EXT_CSD adtc 0x0 R1 + 512B 数据 2 读取完整 EXT_CSD(512 字节)
9 SEND_CSD ac [31:16] RCA R2(CSD) 0 读取 CSD 寄存器
10 SEND_CID ac [31:16] RCA R2(CID) 0 读取 CID 寄存器
11 READ_DAT_UNTIL_STOP adtc 地址 R1 + 流数据 1 流式读(遗留,4.4 后不推荐)
12 STOP_TRANSMISSION ac 0x0 R1b 0 中止多块传输/擦除等;写方向返回忙
13 SEND_STATUS ac [31:16] RCA R1 0 读状态字(最常用的轮询命令)
14 BUS_TEST_R adtc 0x0 R1 + 数据 2 总线测试读(写测试模式后校验)
15 GO_INACTIVE_STATE ac [31:16] RCA 0 设备进入 dis 状态(仅复位可恢复)
16 SET_BLOCKLEN ac [31:0] 块长 R1 2 设块长(块寻址设备忽略,恒 512B)
17 READ_SINGLE_BLOCK adtc [31:0] LBA R1 + 数据 2 单块读
18 READ_MULTIPLE_BLOCK adtc [31:0] LBA R1 + 数据 2 多块读(CMD23 预定义或 CMD12 中止)
19 SEND_TUNING_BLOCK / BUS_TEST_W adtc 0x0 R1 + 数据 2 写测试数据/调谐块(写测试模式)
20 WRITE_DAT_UNTIL_STOP adtc 地址 R1 + 流数据 3 流式写(遗留)
21 SEND_TUNING_BLOCK_HS200 adtc 0x0 R1 + 64B 调谐块 2 HS200/HS400 调谐专用(§7.4)
22 保留
23 SET_BLOCK_COUNT adtc [31:0] 块数 R1 2 预定义多块读/写块数;RPMB 必需
24 WRITE_BLOCK adtc [31:0] LBA R1 4 单块写(数据后 DAT0 忙)
25 WRITE_MULTIPLE_BLOCK adtc [31:0] LBA R1 4 多块写(CMD23 预定义或 CMD12 中止)
26 PROGRAM_CID adtc 0x0 R1 + 128bit 4 写 CID(出厂/一次性)
27 PROGRAM_CSD adtc 0x0 R1 + 128bit 4 写 CSD(出厂)
28 SET_WRITE_PROT ac [31:0] 组地址 R1b 6 设置写保护组
29 CLR_WRITE_PROT ac [31:0] 组地址 R1b 6 清除写保护组
30 SEND_WRITE_PROT adtc [31:0] 组地址 R1 + 32B 6 读取 256 位写保护状态
31 保留
32/33 ERASE_WR_BLK_START / END ac [31:0] 地址 R1 5 字节寻址设备的擦除边界(遗留;块寻址设备用 CMD35/36)
34 保留
35 ERASE_GROUP_START ac [31:0] 起始 LBA R1 5 块寻址擦除起始边界
36 ERASE_GROUP_END ac [31:0] 结束 LBA R1 5 块寻址擦除结束边界
37 保留
38 ERASE ac 见 §4.4 R1b 5 执行擦除/TRIM/Discard(含安全变体)
39 FAST_IO ac 复杂(寄存器读写) R4 9 直接访问设备寄存器(工厂/调试)
40 GO_IRQ_STATE bcr 0x0 R5 9 进入中断状态(测试/调试)
41 保留
42 LOCK_UNLOCK adtc [31:0] 标志 R1b + 数据 7 卡加锁/解锁(口令设置,一般不用)
43 WRITE_EXTR_SINGLE adtc 见 §4.5 R1 + 数据 4 写 EXT_CSD 单字节/扇区(5.1 扩展)
44 QUEUE_TASK_PARAMS ac 见 §4.6 R1 2/4 CMDQ:任务参数(操作码、任务号、优先级等)
45 QUEUE_TASK_ADDR ac [31:0] LBA R1 2/4 CMDQ:任务起始地址
46 EXECUTE_READ_TASK adtc [20:16] 任务号 R1 + 数据 2 CMDQ:执行读任务
47 EXECUTE_WRITE_TASK adtc [20:16] 任务号 R1 + 数据 4 CMDQ:执行写任务
48 CMDQ_TASK_MGMT ac [20:16] 任务号/清除标志 R1b 2/4 CMDQ:任务管理(取消/等待/清除)
49–54 保留
55 APP_CMD ac [31:16] RCA R1 8 厂商特定命令前缀(SD 兼容语义,eMMC 一般不用)
56 GEN_CMD adtc [0] 读/写标志 R1 + 数据 8 通用数据传输命令(厂商特定)
57 保留
58/59 SPI 模式专用(eMMC 不使用 SPI)
60–63 保留

4.2 核心命令要点

  • CMD0:软件复位。arg=0x0 复位到 idle;arg=0xFFFFFFFA 进入 Boot 模式(配合 §9)。Boot 模式下若使能了 Boot ACK,设备对 CMD0 返回 R1。
  • CMD1:参数为”主机可提供的电压”(置位对应 OCR 位),设备用 R3 返回”设备需要且主机支持”的电压交集,并置位 OCR busy 位直至就绪。主机需循环发送直至 busy 清除。
  • CMD3:多设备仲裁用;单设备场景主机通常直接分配 RCA=1。
  • CMD7:arg=0 为去选(设备回 stby);arg=RCA<<16 为选中(回 tran)。从 stby 直接切到另一设备的 tran 会隐式去选原设备。
  • CMD8:一次性读出 512 字节 EXT_CSD。设备固件须将 EXT_CSD 缓存到 RAM 以便快速响应;主机通常在初始化时读取并解析。
  • CMD12:中止多块传输。读中止:R1,需在 2 个时钟内发出(对 DAT 状态机);写中止:R1b(等待编程结束)。
  • CMD13:最常用的状态查询。arg 必须携带当前 RCA。设备固件应保证其开销极低(不回 FTL)。

4.3 CMD6 SWITCH 详解(设备固件高频接触的命令)

参数格式:

1
2
3
4
bit  31:26    25:24          23:16           15:8        7:3      2:0
┌────────┬───────────────┬───────────────┬───────────┬────────┬────────┐
│ 保留(0) │ Access Mode │ EXT_CSD 索引 │ 值 Value │ 保留(0)│Cmd Set │
└────────┴───────────────┴───────────────┴───────────┴────────┴────────┘

Access Mode(位[25:24]):

模式 语义
00b 命令集切换 切换命令集(EXT_CSD[504] S_CMD_SET)
01b 置位(Set Bits) 将索引字节中与 Value 对应的位置 1
10b 清位(Clear Bits) 将索引字节中与 Value 对应的位清 0
11b 写字节(Write Byte) 将索引字节写为 Value(最常用)
  • 响应为 R1b(执行期间 DAT0 忙)。
  • 写只读字段返回 SWITCH_ERROR(R1 位 7)。
  • 超时:优先用字段专属超时(如 PART_SWITCH_TIME、GENERIC_CMD6_TIME)。
  • 常见用途:HS_TIMING(185)、BUS_WIDTH(183)、PART_CONFIG(179,分区切换)、CACHE_CTRL(33)、BKOPS_EN(163)、CMDQ_MODE_EN(15)、POWER_CLASS(187)、ERASE_GROUP_DEF(175)、RST_N_FUNCTION(162)等。

设备固件实现 CMD6 的注意点:

  1. 区分”模式切换类”(HS_TIMING/BUS_WIDTH,切换后必须更新内部时序参数)与”普通配置类”。
  2. 模式切换类命令后,主机可能立刻改变时钟频率,固件必须在 CMD6 完成(busy 释放)前 完成内部重配置。
  3. 写保护字段(PART_CONFIG 中已保护位)必须拒绝并回 SWITCH_ERROR。

4.4 CMD38 ERASE 参数

CMD38 的 32 位参数决定操作类型(配合 CMD35/36 或 CMD32/33 定义的范围):

参数值 操作 说明
0x00000000 Erase 标准擦除:将范围内数据置为擦除态(0x0 或 0xFF,见 ERASED_MEM_CONT)
0x00000001 TRIM 逻辑擦除:将范围内逻辑块标记为无效(性能好,数据可读回 0/FF)
0x00000003 Discard 丢弃:主机声明数据不再需要,设备可自由回收(不保证擦除态)
0x80000000 Secure Erase 安全擦除:物理擦除并确保旧数据不可恢复(需 SEC_FEATURE_SUPPORT 支持)
0x80000001 Secure TRIM(阶段 1) 安全 TRIM 第一步
0x80008000 Secure TRIM(阶段 2) 安全 TRIM 第二步(两阶段机制防掉电漏洞)
  • 响应 R1b(忙)。
  • 范围语义:Erase/TRIM 的范围必须是擦除组(erase group)的整数倍且组对齐;Discard 可任意块。
  • 擦除组大小:若 EXT_CSD[175] ERASE_GROUP_DEF=1,则取 EXT_CSD[224] HC_ERASE_GRP_SIZE(单位 512 KB);否则取 CSD 的 erase_grp_size。
  • 超时:Erase = 300 ms × ERASE_TIMEOUT_MULT[223];TRIM = 300 ms × TRIM_MULT[232];Secure = 300 ms × SEC_ERASE_MULT[230]/SEC_TRIM_MULT[229]。

设备固件必须实现:范围对齐检查(越界/未对齐返回 ADDRESS_OUT_OF_RANGE 或 ERASE_PARAM)、擦除队列管理、与正在进行的写/GC 的并发互斥。

4.5 CMD43 WRITE_EXTR_SINGLE

  • eMMC 5.1 引入,用于写入 EXT_CSD 之外的”扩展数据区”(设备厂商自定义的字节/扇区级扩展字段)。
  • 参数:索引/扇区号 + 单字节/单扇区标志;数据随后在 DAT 线传输。
  • 设备固件若未实现,应返回 ILLEGAL_COMMAND。

4.6 CMDQ 队列命令(CMD44–48)

eMMC 5.1 命令队列(详见 §8.5)使用五条命令:

CMD 功能 参数要点
44 QUEUE_TASK_PARAMS [20:16] 任务号;其余位携带:操作码(CMD17/18/24/25)、优先级、数据方向(读/写)、可靠写标志、FUA、块数
45 QUEUE_TASK_ADDR [31:0] 起始 LBA
46 EXECUTE_READ_TASK [20:16] 任务号;随后在 DAT 线读出数据
47 EXECUTE_WRITE_TASK [20:16] 任务号;随后在 DAT 线接收数据
48 CMDQ_TASK_MGMT 取消指定任务 / 清除完成队列 / 等待完成(R1b)

注意:CMDQ 使用 CMD44–48(与 SD 规范中 CMD60–63 的实现不同),开发时勿混淆。


5. 寄存器:OCR / CID / CSD

eMMC 设备向主机暴露四类寄存器:OCR、CID、CSD、EXT_CSD。前三者通过命令读取(CMD1/CMD2/CMD9),EXT_CSD 通过 CMD8 一次性读出 512 字节。

5.1 OCR(Operation Conditions Register,32 bit)

通过 CMD1 的 R3 响应读取。

字段 说明
31 Card busy 上电初始化未完成时=0;完成后=1。主机轮询 CMD1 直至此位置 1
30 CCS(Card Capacity Status) 1 = 高容量(块寻址,LBA);0 = 低容量(字节寻址)。≥2GB 设备必须为 1
29:24 保留
23:8 电压窗口(2.0–3.6 V) 每 0.1 V 一位:位 8 = 2.0–2.1 V … 位 23 = 3.5–3.6 V
7 低电压(1.65–1.95 V) 支持 1.8 V 类电源
6:0 保留

设备固件要求:CMD1 在电压协商成功后(设备完成初始化)才置 busy 位;在电压不匹配时必须保持忙或返回不支持。

5.2 CID(Card Identification Register,128 bit)

通过 CMD2(R2)读取。eMMC(v4+)布局:

字段 位宽 CID 位 说明
MID 8 [127:120] 厂商 ID(JEDEC 分配,如三星 0x15、海力士 0x90、美光 0x13 等)
OID 16 [119:104] OEM/应用 ID(厂商自定义)
PNM 48 [103:56] 产品名(6 个 ASCII 字符)
PRV 8 [55:48] 产品版本(高 4 位=主版本,低 4 位=次版本)
PSN 32 [47:16] 序列号(厂商唯一)
MDT 8 [15:8] 生产日期:位[15:12]=月(1–12),位[11:8]=年(基准 1997,值+1997)
CRC 7 [7:1] CID 的 CRC7
未用 1 [0] 恒为 1

生产日期注意:按 JESD84-B451(eMMC 4.5)起,若解码出的年份 < 2010,则需 +16 年(应对 4.41 时代字段设计不足);5.1B(rev≥9)进一步规定 < 2023 时 +16。设备固件按规范填写即可,主机端解码时按上述规则处理。

5.3 CSD(Card Specific Data Register,128 bit)

通过 CMD9(R2)读取。eMMC 使用 CSD Structure 1.2(位[127:126]=1)。关键字段:

字段 位宽 CSD 位 说明
CSD_STRUCTURE 2 [127:126] =1(v1.2,eMMC 使用)
SPEC_VERS(mmca_vsn) 4 [125:122] 规范版本(0–4,见 §1.3 的版本映射)
TAAC 8 [119:112] 数据访问时间(mantissa+exponent 编码)
NSAC 8 [111:104] 数据访问时间(时钟数,×100)
TRAN_SPEED 8 [103:96] 最大传输速率(如 0x32 = 25 MHz,0x5A = 50 MHz,0x2B = 100 MHz 等)
CCC 12 [95:84] 命令类别位图(§3.6)
READ_BL_LEN 4 [83:80] 最大读块长(log2(字节),≥9)
READ_BL_PARTIAL 1 [79] 支持部分块读(eMMC 恒 0)
WRITE_BLK_MISALIGN 1 [78] 写块不对齐支持
READ_BLK_MISALIGN 1 [77] 读块不对齐支持
DSR_IMP 1 [76] 实现 DSR(配 CMD4)
C_SIZE 12 [73:62] 容量编码(低容量设备用;高容量以 EXT_CSD SEC_CNT 为准
C_SIZE_MULT 3 [49:47] 容量倍率(配合 C_SIZE)
ERASE_GRP_SIZE 5 [46:42] 擦除组大小(a,组大小 = (a+1)×(b+1) 写块)
ERASE_GRP_MULT 5 [41:37] 擦除组倍率(b)
WP_GRP_SIZE 5 [36:32] 写保护组大小(组数)
WP_GRP_ENABLE 1 [31] 写保护组使能
R2W_FACTOR 3 [28:26] 写/读时间比(编程时间推导)
WRITE_BL_LEN 4 [25:22] 最大写块长(log2(字节))
WRITE_BL_PARTIAL 1 [21] 部分块写(恒 0)
FILE_FORMAT_GRP / COPY / PERM_WRITE_PROT / TMP_WRITE_PROT 4 [15:12] 文件格式组、复制标志、永久/临时写保护(出厂字段)
FILE_FORMAT 2 [11:10] 文件格式
ECC 2 [9:8] ECC 类型
CRC 7 [7:1] CRC7
未用 1 [0] 恒为 1

容量说明(设备固件必须处理):

  • 容量 < 2 GB:主机可用 CSD 的 C_SIZE 计算容量。
  • 容量 ≥ 2 GB:必须置 OCR.CCS=1,容量以 EXT_CSD[212–215] SEC_CNT(扇区数,每扇区 512 B)为准,CSD 容量字段失效。
  • 设备固件需保证 SEC_CNT = 各分区扇区数之和(boot+RPMB+GPP+User 的可用区域)。

6. 扩展寄存器 EXT_CSD 详解

EXT_CSD 共 512 字节,通过 CMD8 一次性读取;写入通过 CMD6(多数字段)或 CMD43(扩展字段)。以下为固件开发最常涉及的字段(偏移依据 JEDEC 5.1 / Linux mmc.h)。

6.1 字段总表(按偏移)

偏移 名称 访问 说明
15 CMDQ_MODE_EN R/W 命令队列使能(bit0=1 使能,§8.5)
25–28 FFU_ARG R/W FFU 参数(固件升级,§12.3)
26 FFU_STATUS R FFU 执行状态(0x00=成功,0x10=错误等)
27 FFU_FEATURES R FFU 特性(bit0=支持多块写模式,bit1=支持 CMD23 模式等)
28 FFU_CNT R FFU 镜像块数(部分实现)
29 HPI_FEATURES R 高优先级中断特性(§12.4)
32 FLUSH_CACHE W 写 1 触发 cache 刷写(R1b,超时最长 30 s 量级)
33 CACHE_CTRL R/W bit0=1 使能写缓存
34 POWER_OFF_NOTIFICATION R/W 关机通知:0=不支持,1=上电(ON),2=短关机,3=长关机(§12.7)
35/36 PACKED_FAILURE_INDEX / PACKED_CMD_STATUS R Packed 命令错误信息(4.5–5.0 遗留)
44 CMDQ_DEPTH R 队列深度(bit[4:0]+1,最大 32;≤2 视为不支持)
45 CMDQ_SUPPORT R bit0=1 支持 CMDQ
54–55 EXP_EVENTS_STATUS R 异常事件状态(bit0=紧急 BKOPS,bit1=动态容量告警等)
56–57 EXP_EVENTS_CTRL R/W 异常事件使能
61 DATA_SECTOR_SIZE R 逻辑扇区大小:0=512 B,1=4096 B
136–139 ENH_START_ADDR R/W 增强区起始地址(4 字节,块寻址时 ×512)
140–142 ENH_SIZE_MULT R/W 增强区大小(×擦除组,见 §10.4)
143–154 GP_SIZE_MULT R/W GPP1–GPP4 大小(每区 3 字节,×擦除组)
155 PARTITION_SETTING_COMPLETED R/W 分区配置完成标志(bit0,置 1 后分区配置锁定)
156 PARTITION_ATTRIBUTE R/W 分区属性(bit0=User 区为增强区)
160 PARTITION_SUPPORT R 分区支持:bit0=GPP 支持,bit1=增强区支持
161 HPI_MGMT R/W HPI 管理:写 1 使能
162 RST_N_FUNCTION R/W RST_n 功能:0=禁用,1=永久使能(不可改),2=可配置使能
163 BKOPS_EN R/W 后台操作使能:bit0=手动,bit1=自动(§12.5)
164 BKOPS_START W 写 1 触发手动 BKOPS
165 SANITIZE_START W 写 1 触发 Sanitize(§12.2)
166 WR_REL_PARAM R 可靠写参数:bit2=支持可靠写,bit4=支持 RPMB 可靠写
167 WR_REL_SET R/W 可靠写分区设置(只对支持可靠写的分区有效)
168 RPMB_MULT R RPMB 大小倍率(×128 KB)
169 FW_CONFIG R/W bit0=1 禁止 FFU
171 USR_WP R/W User 区写保护(动态/永久)
173 BOOT_WP R/W Boot 区写保护(bit0=上电保护使能,bit2=永久保护使能等)
174 BOOT_WP_STATUS R Boot 区写保护状态
175 ERASE_GROUP_DEF R/W bit0=1 时擦除组取 HC_ERASE_GRP_SIZE(512 KB 为单位)
177 BOOT_BUS_WIDTH R/W Boot 总线配置:bit[2:0]=宽度(0/1/2=x1/x4/x8),bit[4:3]=模式(0=SDR,1=DDR),bit5=RESET_BOOT_BUS_WIDTH
178 BOOT_CONFIG_PROT R/W Boot 配置保护(防误改 179)
179 PART_CONFIG R/W 分区配置(见 §6.2)
181 ERASED_MEM_CONT R 擦除态内容:0=0x00,1=0xFF
183 BUS_WIDTH R/W 总线宽度(见 §6.3)
184 STROBE_SUPPORT R bit0=1 支持增强选通(HS400ES)
185 HS_TIMING R/W 时序模式(见 §6.4)
187 POWER_CLASS R/W 电源等级选择(配合 PWRCL* 寄存器)
192 REV R EXT_CSD 修订号(版本映射见 §1.2)
194 STRUCTURE R EXT_CSD 结构版本(0–2)
196 CARD_TYPE R 支持的时序模式位图(见 §6.5)
197 DRIVER_STRENGTH R 支持的驱动强度(type 0–4 位图)
198 OUT_OF_INTERRUPT_TIME R HPI 中断超时(×10 ms)
199 PART_SWITCH_TIME R 分区切换超时(×10 ms)
200–203 PWR_CL_26/52(1.95/3.6 V) R 26/52 MHz 电源等级
212–215 SEC_CNT R 用户区扇区数(4 字节小端),容量判定依据
217 S_A_TIMEOUT R Sleep/Awake 超时(100 ns × 2^n)
221 HC_WP_GRP_SIZE R 高容量写保护组大小(×擦除组)
222 REL_WR_SEC_C R 可靠写扇区数
223 ERASE_TIMEOUT_MULT R 擦除超时倍率(×300 ms)
224 HC_ERASE_GRP_SIZE R 高容量擦除组大小(×512 KB)
226 BOOT_MULT R Boot 分区大小(×128 KB)
229/230 SEC_TRIM_MULT / SEC_ERASE_MULT R 安全 TRIM/擦除超时倍率(×300 ms)
231 SEC_FEATURE_SUPPORT R 安全特性:bit0=Secure Erase,bit2=安全块级擦除,bit4=安全 GC,bit6=Sanitize
232 TRIM_MULT R TRIM 超时倍率(×300 ms)
236–239/253 PWR_CL_200/DDR_52/DDR_200 R 高速模式电源等级
246 BKOPS_STATUS R BKOPS 状态等级(≥2=紧急)
247 POWER_OFF_LONG_TIME R 长关机超时(×10 ms)
248 GENERIC_CMD6_TIME R CMD6 通用超时(×10 ms)
249–252 CACHE_SIZE R 写缓存大小(4 字节)
254–261 FIRMWARE_VERSION R 固件版本(8 字节,5.0+)
267 PRE_EOL_INFO R 预寿命终结信息(0=正常,1=正常(>90%),2=警告,3=严重)
268/269 DEVICE_LIFE_TIME_EST_TYP_A/B R 估计寿命(0–10,A=MLC 区,B=SLC 区)
307 CMDQ_DEPTH R 队列深度(5.1 位置;与 44 并存,5.1 实际用 307)
308 CMDQ_SUPPORT R 队列支持(5.1)
493 SUPPORTED_MODE R bit0=支持 FFU
498/499 TAG_UNIT_SIZE / DATA_TAG_SUPPORT R 数据标签特性(5.0)
502 BKOPS_SUPPORT R bit0=支持 BKOPS
503 HPI_FEATURES R bit0=HPI 用 CMD13,bit1=HPI 用 CMD12
504 S_CMD_SET R/W 当前命令集(bit0=Normal)

注:44/45 与 307/308 同为 CMDQ 深度/支持字段——JEDEC 5.1 将正式定义放在 307/308,早期草案字段在 44/45;实现时应以 307/308 为准。


6.2 EXT_CSD[179] PART_CONFIG(分区配置)

1
2
3
4
5
bit  7          6:5            4       3       2:0
┌───────────┬──────────────┬───────┬───────┬──────────┐
│BOOT_ACK │BOOT_PARTITION│保留 │保留 │PARTITION │
│_ENABLE │_ENABLE │ │ │_ACCESS │
└───────────┴──────────────┴───────┴───────┴──────────┘
  • BOOT_ACK_ENABLE[7]:1 = 允许 Boot 操作时设备发送 ACK 响应。
  • BOOT_PARTITION_ENABLE[6:5]:00 = 非启动设备;01 = 从 Boot1 启动;10 = 从 Boot2 启动;11 = 保留。
  • PARTITION_ACCESS[2:0]:当前访问分区:000=User,001=Boot1,010=Boot2,011=RPMB,100–111=GPP1–4。
  • 切换分区用 CMD6 写该字节;切换后需等待 PART_SWITCH_TIME(≥300 ms 兜底)。
  • 分区切换期间设备不接受数据传输命令。

6.3 EXT_CSD[183] BUS_WIDTH(总线宽度)

模式
0x0 x1 SDR(默认)
0x1 x4 SDR
0x2 x8 SDR
0x3 / 0x4 保留
0x5 x4 DDR(DDR52)
0x6 x8 DDR(DDR52 或 HS400)
bit7(0x80,与 0x6 组合) 增强选通(HS400ES)
  • 切换 BUS_WIDTH 后主机必须同步调整自身控制器位宽,否则通信失败。
  • 设备固件收到 BUS_WIDTH 写请求时,在 busy 释放前完成内部数据通路位宽重配置。

6.4 EXT_CSD[185] HS_TIMING(时序模式)

模式 时钟/带宽(x8)
0x0 Legacy / 向后兼容(Backward Compatible) ≤25 MHz(或 26 MHz)
0x1 High Speed(HS) ≤52 MHz
0x2 HS200 200 MHz SDR,200 MB/s
0x3 HS400 200 MHz DDR,400 MB/s
0x4 HS400ES HS400 + 增强选通
  • 切换顺序有严格约束(见 §7.3):Legacy→HS→HS200→HS400 必须逐级切换,不允许直接跳级
  • HS200/HS400 切换后必须执行调谐(HS400ES 除外,见 §7.4)。

6.5 EXT_CSD[196] CARD_TYPE(能力位图)

含义
0 支持 26 MHz(HS26)
1 支持 52 MHz(HS52)
2 支持 DDR52 @ 1.8/3.3 V I/O
3 支持 DDR52 @ 1.2 V I/O
4 支持 HS200 @ 1.8 V
5 支持 HS200 @ 1.2 V
6 支持 HS400 @ 1.8 V
7 支持 HS400 @ 1.2 V
8 支持 HS400ES

设备固件必须如实上报;主机据此决定可用的最高模式(同时受主机能力约束)。


7. 设备识别与初始化流程

7.1 初始化序列总览(主机视角)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
上电/复位(CLK ≤ 400 kHz,x1,开漏)

├─ CMD0 (arg=0) ────────────────► idle

├─ CMD1 (arg=主机电压窗口) ───────► R3(OCR)
│ └─ 循环直到 OCR busy 位=1(就绪)──► ready

├─ CMD2 ─────────────────────────► R2(CID)──► ident

├─ CMD3 (arg=RCA) ──────────────► R6(RCA)──► stby

├─ CMD9 (RCA) ──────────────────► R2(CSD)

├─ CMD7 (RCA<<16) ──────────────► R1b ──► tran

├─ CMD8 ─────────────────────────► R1 + 512B EXT_CSD(解析全部能力)

├─ 选择总线宽度(CMD6: BUS_WIDTH=0x2/0x1)+ 总线测试(可选)

├─ 选择时序模式(CMD6: HS_TIMING)+ 调谐(HS200/HS400)

└─ 使能可选特性(Cache、BKOPS、HPI、CMDQ、POWER_OFF_NOTIFICATION)──► 正常工作

7.2 各步骤要点

  1. CMD1 电压协商:主机第一次发 CMD1 用 arg=0x0(只查询),第二次用自身支持的电压窗口。设备以”主机窗口 ∩ 设备窗口”返回 R3,并保持 busy 直到内部初始化完成。若交集为空,主机应放弃。
  2. RCA 分配:单设备场景 RCA 取 1;多设备场景每设备不同(bit[31:16],bit[15:0] 恒 0)。设备固件保存 RCA,后续所有 ac 命令都要求匹配 RCA(不匹配的 CMD13/CMD7 等应忽略或按规范处理)。
  3. CMD7 选中:arg = RCA<<16。若 arg=0 则去选(回 stby)。选中后进入 tran 状态,才能执行数据传输。
  4. 读取 EXT_CSD:CMD8 返回 512 字节。主机解析 CARD_TYPE、BOOT_MULT、PART_CONFIG、SEC_CNT、HC_ERASE_GRP_SIZE、CMDQ/HPI/BKOPS 等能力。
  5. 总线宽度切换:先尝试 x8(若主机支持),失败则 x4,再失败保持 x1。可用 CMD14/CMD19(BUS_TEST_R/W)校验位宽是否真实生效——写 0x5A 测试块再读回比对,或比较不同位宽下读取的 EXT_CSD 只读字段是否一致(Linux 的 mmc_compare_ext_csds 方法)。
  6. 时序模式升级:按 §7.3 逐步升级并调谐。
  7. 特性使能:Cache(CACHE_CTRL=1,超时建议 ≥1.6 s)、BKOPS(自动模式优先)、HPI、CMDQ、POWER_OFF_NOTIFICATION(关机前)。每个都通过 CMD6 完成,注意各自超时。

7.3 时序模式切换序列(严格顺序)

Legacy → HS(≤52 MHz)

  1. CMD6 写 HS_TIMING=0x1(用 GENERIC_CMD6_TIME 超时)。
  2. 主机将 CLK 提升至 ≤52 MHz。

→ HS200(200 MHz SDR)

  1. 先将 I/O 电压切至 1.8 V 或 1.2 V(主机电源轨操作)。
  2. CMD6 写 HS_TIMING=0x2,CLK ≤ 200 MHz。
  3. 执行 HS200 调谐(CMD21,见 §7.4)。

→ HS400(200 MHz DDR)

  1. 先在 HS200 下完成调谐(HS400 复用 HS200 的调谐结果)。
  2. CMD6 写 HS_TIMING=0x1(回退到 HS,CLK ≤ 52 MHz)。
  3. CMD6 写 BUS_WIDTH=0x6(x8 DDR)。
  4. CMD6 写 HS_TIMING=0x3(HS400),CLK 升至 200 MHz。
  5. 此后设备驱动 DS 引脚(数据选通)。

→ HS400ES(设备支持且 STROBE_SUPPORT=1 时):

  1. 重复 HS400 的 1–3 步(HS200 调谐仍需要,用于 CMD 采样点)。
  2. CMD6 写 BUS_WIDTH=0x86(x8 DDR + 增强选通位)。
  3. CMD6 写 HS_TIMING=0x4。

降级/回退:任何模式失败时主机应回退到上一级模式重新初始化;设备固件应容忍”切换后主机不再通信”的情况(以超时/复位兜底)。

7.4 调谐(Tuning)

  • 目的:HS200/HS400 在 200 MHz 下,CMD/DAT 的建立保持时间余量极小,主机必须找到最佳采样延迟。
  • 机制:主机反复发送 CMD21(SEND_TUNING_BLOCK_HS200),设备每次返回固定 64 字节调谐块;主机扫描采样延迟窗口,找出 CRC/位错全部消失的中心点并锁定。
  • 设备固件要求:调谐块内容固定(厂商可自定义但须稳定);调谐期间不执行 FTL 操作、不回忙。
  • 主机侧注意:调谐须在每次模式进入时执行;运行中温度漂移可触发重调谐(re-tuning,由主机定时或按错误触发)。

7.5 初始化失败处理(主机侧清单)

现象 排查
CMD0 无响应 检查供电、时钟(≤400 kHz)、CMD 线上拉、CRC
CMD1 一直忙 电压不匹配;等待时间不足
CMD2 响应 CRC 错 时钟过快;信号质量(建议逻辑分析仪抓 CMD 线)
CMD7 后 CMD13 状态异常 RCA 不匹配;设备未进入 tran
CMD8 数据 CRC 错 位宽/电压配置不一致;DAT 线问题
切 HS200/HS400 后通信全断 未调谐;电压未先切 1.8/1.2 V;跳级切换

8. 数据传输协议

8.1 块与寻址

  • 逻辑块大小固定 512 B(DATA_SECTOR_SIZE=1 时为 4096 B,但主流设备仍为 512 B 逻辑扇区)。
  • 高容量设备(CCS=1)使用 LBA 块寻址:命令参数直接是块号。
  • 低容量设备(CCS=0)使用字节地址(遗留,仅旧设备)。

8.2 单块读/写

1
2
读:CMD17(LBA) → R1 → [DAT: 512B + CRC16](读方向,设备发)
写:CMD24(LBA) → R1 → [DAT: 512B + CRC16](写方向,主机发)→ DAT0 忙(编程)
  • 读数据首块开始时间受 TAAC/NSAC(Nac)限制,主机须设超时。
  • 写完成后设备在 DAT0 上拉低表示编程忙;主机必须等待忙释放(或轮询 CMD13)才能发下一条命令。

8.3 多块读/写

两种方式:

  1. 预定义多块(推荐)

    1
    CMD23(块数 N) → R1 → CMD18/CMD25(LBA) → R1 → 连续传输 N 块

    CMD23 的 SET_BLOCK_COUNT 在 CMD18/CMD25 之前发出;设备按计数自动结束,无需 CMD12。

  2. 开放多块(遗留)

    1
    CMD18/CMD25(LBA) → R1 → 连续传输 → CMD12(STOP_TRANSMISSION) → R1/R1b

    读中止:R1;写中止:R1b(等编程结束)。设备固件在收到 CMD12 后须立即停止数据流。

  • 多块传输中块间无间隙(back-to-back),块与块之间依次为 数据+CRC16+End bit。
  • 对主机:推荐 CMD23 方式(省一次 CMD12 往返,且可靠写/CMDQ 依赖它)。
  • 对设备固件:CMD23 的块数必须在 CMD18/25 前锁定;若 CMD23 后收到非传输命令,块数状态应复位。

8.4 擦除 / TRIM / Discard(回顾 §4.4)

操作 命令序列 用途
Erase CMD35 + CMD36 + CMD38(0x0) 物理擦除(组对齐)
TRIM CMD35 + CMD36 + CMD38(0x1) 逻辑无效化(建议主机日常用)
Discard CMD35 + CMD36 + CMD38(0x3) 数据不再需要,立即回收
Secure Erase CMD35 + CMD36 + CMD38(0x80000000) 安全擦除(需 SEC_FEATURE_SUPPORT)
Secure TRIM CMD35 + CMD36 + CMD38(0x80000001→0x80008000) 两阶段安全 TRIM

设备固件注意:

  • TRIM/Discard 范围可任意块;Erase/Secure 需组对齐,否则返回 ERASE_PARAM/ADDRESS_OUT_OF_RANGE。
  • Discard 后读回值不定(可能 0x00/0xFF/旧数据),主机不得依赖;TRIM 后读回为擦除态。
  • 擦除/TRIM 与 CMDQ、Cache 的交互:挂起/排队策略需固件内部处理(见 §14)。

8.5 命令队列(CMDQ,eMMC 5.1)

背景:HS400 下单次命令往返开销占比高;CMDQ 允许主机一次提交最多 32 个任务(读/写混合),设备内部排序执行,显著提升随机 IO 性能。

使能条件

  • EXT_CSD[308] CMDQ_SUPPORT=1,且深度 EXT_CSD[307] CMDQ_DEPTH ∈ [3,32]。
  • 主机 CMD6 写 EXT_CSD[15] CMDQ_MODE_EN=1。
  • 启用后只能使用队列命令(CMD44–48)传输数据;CMD17/18/24/25 与 Packed 命令不可用。

使用流程

1
2
3
4
5
6
1. 使能:CMD6(CMDQ_MODE_EN=1)
2. 入队:CMD44(任务参数:操作码/任务号/优先级/方向/可靠写/FUA/块数)
CMD45(起始 LBA)
3. 执行:CMD46(读)/ CMD47(写)→ 触发该任务的数据传输
4. 完成:任务完成后设备更新完成队列;主机用 CMD13 轮询 QSR 或
CMD48(TASK_MGMT) 等待/取消任务

关键语义

  • 任务号 0–31 由主机分配,设备按任务号跟踪。
  • 设备固件可按优先级、方向(写优先)自行调度;规范要求设备必须支持乱序完成。
  • 可靠写(Reliable Write)任务保证落盘(配合 REL_WR_SEC_C);FUA 任务保证刷 cache。
  • RPMB、Sanitize 等操作前必须禁用 CMDQ(Linux 中表现为临时的 cmdq 关闭再使能)。

8.6 错误处理与重试(主机侧)

错误 检测 处理
命令 CRC 错 R1.COM_CRC_ERROR 重发命令(CRC 由主机控制器校验,一般不会发生)
命令非法 R1.ILLEGAL_COMMAND 降级特性(如不支持 TRIM 则用 Erase)
地址越界 R1.OUT_OF_RANGE 修正范围
读数据 CRC 错 DAT CRC16 校验失败 发 CMD12 中止;若已用 CMD23 则等计数结束;重读该区域
写数据 CRC 错 设备回 R1.ERROR 或忙后失败 重写;若反复失败考虑坏块
ECC 无法纠正 R1.CARD_ECC_FAILED 数据损坏,报上层;设备侧触发坏块/刷新流程
写超时/忙超时 DAT0 长时间忙 复位(CMD0 或硬件复位),必要时重新初始化
擦除超时 超过 300ms×MULT 用 CMD13 确认状态,必要时复位

设备固件侧对应职责:CRC 校验失败时不得提交数据;编程失败(NAND 写失败/ECC 超限)必须报告(R1.ERROR/CARD_ECC_FAILED 或卡在 busy 后回错)并触发内部坏块重映射。

8.7 写保护

  • 分组写保护:CMD28/CMD29 按写保护组(WP 组 = HC_WP_GRP_SIZE × 擦除组)设置/清除;CMD30 读回 256 位保护位图。
  • 永久写保护:User 区用 EXT_CSD[171] USR_WP(bit0=保护使能,bit1=永久,bit2=动态);Boot 区用 EXT_CSD[173] BOOT_WP;写保护后对应分区不可再写(Boot 区保护后仅硬件复位可解除动态保护,永久保护不可逆)。
  • 设备固件必须对写保护区域拒绝写/擦除命令并返回 WP_VIOLATION。

9. Boot 操作

9.1 概念

eMMC 可作为系统启动介质:上电后无需完整协议初始化,设备即可在 Boot 分区 中连续输出启动代码,供 SoC ROM 直接加载。Boot 分区为 Boot1/Boot2 两个只读分区(写需特殊配置),大小相等,由 EXT_CSD[226] BOOT_MULT × 128 KB 决定。

9.2 使能配置(生产时由工厂/主机写入)

配置 字段 说明
启动使能 EXT_CSD[179] BOOT_PARTITION_ENABLE[6:5] 01=Boot1,10=Boot2
Boot ACK EXT_CSD[179] BOOT_ACK_ENABLE[7] 1=设备在 Boot 开始时回 R1
Boot 总线 EXT_CSD[177] BOOT_BUS_WIDTH x1/x4/x8,SDR/DDR;bit5=启动后复位为 x1 SDR
保护 EXT_CSD[173] BOOT_WP 防止 Boot 区被意外改写

9.3 Boot 操作序列

1
2
3
4
5
6
7
1. 上电,主机拉高电平,CLK 以 ≤400 kHz 或已协商的 Boot 频率运行
2. 主机发 CMD0(arg=0xFFFFFFFA)
3. 若 BOOT_ACK_ENABLE=1:设备回 R1(ACK)
4. 设备从 Boot1(或 Boot2)起始地址连续输出 Boot 数据(DAT0–7,按
BOOT_BUS_WIDTH 配置),直到 Boot 分区结束或主机终止
5. 主机发 CMD1(SEND_OP_COND)——设备退出 Boot 模式,停止输出数据,
进入正常初始化流程(§7.1)

要点:

  • Boot 数据是”流”,无块边界/无 CRC,由主机按长度裁剪;数据连续输出,主机靠时钟控制接收。
  • 主机也可通过停止时钟暂停/终止 Boot(规范允许终止方式之一)。
  • 若 BOOT_PARTITION_ENABLE=00,设备不进入 Boot 模式,直接响应普通 CMD0(arg=0)初始化。
  • 固件注意:设备端 Boot 数据源通常是”Boot 分区内固定偏移的原始 NAND 内容”,不经 FTL 映射,因此 Boot 分区写入必须保证连续物理页布局(厂商固件内部处理)。

10. 分区管理

10.1 分区类型总览

eMMC 设备存储空间划分为以下分区:

分区 数量 大小公式 可访问性 用途
Boot1 / Boot2 2 BOOT_MULT[226] × 128 KB(两区等大) PART_CONFIG acc=01/10 系统启动代码,只读保护
RPMB 1 RPMB_MULT[168] × 128 KB acc=03,专用协议 安全数据(密钥、计数器等)
GPP1–GPP4 0–4 GP_SIZE_MULT[143–154](每区 3 字节,单位=HC_ERASE_GRP_SIZE × HC_WP_GRP_SIZE × 512 B) acc=04–07 通用分区(可自定义用途)
User Area 1 SEC_CNT[212–215] − 其他分区总和 acc=00 主数据区

10.2 分区大小计算

Boot 分区

  • 大小 = EXT_CSD[226] × 128 KB(若值=0 则无 Boot 分区)。
  • 两区对称,各独立可写。

RPMB 分区

  • 大小 = EXT_CSD[168] × 128 KB。
  • 若 RPMB_MULT=0,则无 RPMB 分区。

GPP(通用目的分区)

  • 每个 GPP 大小 = GP_SIZE_MULT[i] × HC_ERASE_GRP_SIZE × HC_WP_GRP_SIZE × 512 B。
  • HC_ERASE_GRP_SIZE = EXT_CSD[224](单位 512 KB);HC_WP_GRP_SIZE = EXT_CSD[221](单位擦除组)。
  • 若 GP_SIZE_MULT=0(3 字节全 0),该 GPP 不存在。

增强区(Enhanced Area)

  • 部分 User 区或 GPP 可配置为增强区(性能更高,通常是 SLC 模式或可靠写区域)。
  • 起始地址:ENH_START_ADDR[136–139];大小:ENH_SIZE_MULT[140–142] × HC_ERASE_GRP_SIZE × HC_WP_GRP_SIZE × 512 B。
  • 分区属性 PARTITION_ATTRIBUTE[156] bit0=1 表示 User 区有增强属性。
  • 注意:分区配置一旦完成(PARTITION_SETTING_COMPLETED[155]=1),分区大小和增强区设置不可再修改(掉电不可恢复!)。

10.3 分区切换与访问

  1. 主机发送 CMD6 写 EXT_CSD[179] PART_CONFIG,将 PARTITION_ACCESS[2:0] 设为目标分区编码。
  2. 等待 PART_SWITCH_TIME(≥300 ms,由 EXT_CSD[199] 或 GENERIC_CMD6_TIME 决定)。
  3. 发 CMD13 确认设备处于 tran 且无错误。
  4. 之后的数据传输命令访问目标分区。

切换期间的限制:

  • 正在编程/擦除时不可切换(设备回 SWITCH_ERROR 或 R1b 延长)。
  • RPMB 切换时必须同时禁用 CMDQ(若已启用)。
  • Boot 区切换后写保护可能生效(视 BOOT_WP 配置)。

10.4 分区配置的安全性

  • 一次性配置:PARTITION_SETTING_COMPLETED=1 后,分区表锁定。设备固件应拒绝再修改 GP_SIZE_MULT、ENH_SIZE_MULT 等字段(回 SWITCH_ERROR)。
  • 保护 Boot 区:BOOT_WP 配置(bit0=上电保护,bit2=永久保护)在分区配置完成后应设置;永久保护不可逆,须谨慎。
  • RPMB 保护:RPMB 区域的读写必须经 HMAC 认证(见 §11),主机无法绕过认证直接读写。

11. RPMB(重放保护内存块)

11.1 概念

RPMB 是一个硬件级防篡改分区,专为存储安全敏感数据(密钥、设备标识、计数器、DRM 凭据等)设计。特性:

  • 认证写入:每笔写操作必须附带 HMAC-SHA256 签名(256-bit 密钥),签名不匹配则拒绝。
  • 抗重放:内置单调递增写计数器(Write Counter,32 bit),每次成功写入自动 +1;主机侧保存计数器值,若低于预期则拒绝(防回滚)。
  • 防物理读:未认证的读操作返回数据但不保证完整性(建议主机总是认证读)。

11.2 RPMB 帧格式(512 字节)

RPMB 通信使用固定 512 字节帧,写入用 CMD25(目标=RPMB 分区),读取用 CMD17/CMD18。

请求帧(写方向,CMD25 发送)

字节偏移 字段 大小 说明
0–3 保留 4 B 填 0
4–5 请求类型 2 B 见下方
6–261 数据 256 B 写数据(READ/WRITE)或保留
262–263 保留 2 B
264–267 写计数器 4 B 主机填入预期值(WRITE/SECURE_WRITE)
268–279 地址 12 B [271:268] 保留,[275:272] LBA,[279:276] 保留
280–283 保留 4 B
284–287 Nonce 4 B 随机数(READ 用,WRITE 可选)
288–319 HMAC 32 B HMAC-SHA256 签名
320–511 保留 192 B 填 0

响应帧(读方向,CMD17/CMD18 返回):结构类似,但数据区包含读出数据。

请求/响应类型

请求类型 说明
PROGRAM_KEY 0x0001 写入认证密钥(一次性,不可更改)
RESULT_READ 0x0002 读取上一次操作结果(状态)
WRITE 0x0003 认证写入
READ 0x0004 认证读取
GET_WRITE_COUNTER 0x0005 查询写计数器

响应类型:请求类型 | 0x0100(如 WRITE 响应 = 0x0103)。

结果码

结果码 含义
0x0000 操作成功
0x0001 通用失败
0x0002 认证失败(HMAC 错误)
0x0003 计数器失败(值不匹配)
0x0004 地址失败(地址越界)
0x0005 写失败
0x0006 读失败
0x0007 密钥未编程(首帧未写密钥)

11.3 RPMB 交互流程

密钥编程(一次性,生产阶段)

1
2
3
4
5
1. 主机构造请求帧(type=PROGRAM_KEY,数据区放 256-bit 密钥)
2. CMD6 PART_CONFIG acc=RPMB
3. CMD23(1) + CMD25(RPMB 地址) 发送请求帧
4. CMD23(1) + CMD17/RPMB 读取响应帧
5. 校验 result=0x0000;此后密钥不可更改

认证写

1
2
3
4
5
1. 读取当前计数器(GET_WRITE_COUNTER)
2. 构造请求帧(type=WRITE,数据,counter=预期值+1,HMAC)
3. CMD23(1) + CMD25 发送
4. CMD23(1) + CMD17 读响应;校验 result 和计数器
5. 主机更新本地 counter

认证读

1
2
3
4
1. 构造请求帧(type=READ,nonce 随机数)
2. CMD23(1) + CMD25 发送请求
3. CMD23(1) + CMD18(数据块数) 读取数据帧
4. 用 nonce + 数据计算 HMAC 并校验

11.4 设备固件实现要点

  • 密钥存储:密钥编程后写入 NAND 安全区域(或 OTP 区),不经过 FTL 映射;掉电后不可丢失。
  • 写计数器:存于 RPMB 专属 NAND 区域(日志结构),每次成功写入原子递增;掉电时可能已完成递增但数据未完全写入——固件须保证计数器原子更新与数据写入的一致性。
  • HMAC 计算:SHA-256 的 HMAC,密钥 256 bit。覆盖帧内 [4–319](不含帧头保留域,不含 HMAC 域本身)。
  • 并发:RPMB 操作期间应挂起普通分区的 CMDQ/Cache 操作。
  • RPMB 与可靠写:WR_REL_PARAM[166] bit4=EN_RPMB_REL_WR 时支持可靠写。

12. 安全、可靠性与维护特性

12.1 安全擦除(Secure Erase / Secure TRIM)

见 §4.4 CMD38 参数。Secure Erase(0x80000000)物理擦除所有范围内 NAND 块并确保旧数据不可恢复;Secure TRIM 用两阶段机制(CMD38 0x80000001 → 0x80008000)防止掉电导致数据残留。需 SEC_FEATURE_SUPPORT[231] bit0(Secure Erase)和 bit4(Secure GC/Trim)支持。

12.2 Sanitize

用途:TRIM/Discard 后数据可能物理残留(FTL 未回收前仍存在于 NAND);Sanitize 强制清除这些”逻辑无效但物理残留”的数据。

流程

1
2
3
1. 主机先对目标范围执行 TRIM/Discard(CMD38 0x1/0x3)
2. CMD6 写 EXT_CSD[165] SANITIZE_START=1(R1b,长时间忙)
3. 等待 Sanitize 完成(忙释放)——过程可能持续数分钟到数小时

  • Sanitize 不可中断,不可与其他数据命令并发。
  • 支持条件:EXT_CSD[231] SEC_FEATURE_SUPPORT bit6=1。
  • 若设备在 Sanitize 中断电,数据状态不确定(规范未保证原子性)。

12.3 现场固件升级(FFU,eMMC 5.0+)

用途:在线更新设备内部固件,无需物理更换。

前提:EXT_CSD[493] SUPPORTED_MODE bit0=1 且 EXT_CSD[169] FW_CONFIG bit0=0。

流程

1
2
3
4
5
6
1. 读取 FIRMWARE_VERSION[254–261](8 字节)确认当前版本
2. 读取 FFU_FEATURES[27] 确认支持的写入模式
3. 写 FFU_ARG[25–28](4 字节)设置升级参数
4. 发送 CMD23(块数) + CMD25(起始地址) 将固件镜像写入(镜像以 512B 块计)
5. 轮询 FFU_STATUS[26]:0x00=成功,0x10=错误,0x11=设备忙,0x12=版本不匹配
6. 成功后掉电/硬件复位,新固件生效

  • 固件镜像格式厂商特定,通常包含头信息(版本、校验和、分区布局)。
  • 升级期间设备不响应普通数据命令。
  • 升级失败(断电/校验错)设备应回退到旧固件(厂商实现,规范不强制)。
  • eMMC 5.1 增强了 FFU 的多块写模式和 CMD23 支持(FFU_FEATURES[27] 各位指示)。

12.4 高优先级中断(HPI)

用途:主机中断长时间操作(擦除、TRIM、Sanitize),立即读取状态/执行其他命令。

机制

  • HPI_FEATURES[503]:bit0=支持用 CMD13 中断,bit1=支持用 CMD12 中断。
  • HPI_MGMT[161]:写 1 使能 HPI。
  • 主机发 HPI 命令(CMD13 或 CMD12)后,设备中止当前操作并回 R1。
  • OUT_OF_INTERRUPT_TIME[198]:中断后设备保证在该时间内恢复正常状态(×10 ms)。

设备固件要求:HPI 收到时若正在 FTL/GC,需安全中止(保存中间状态);返回的 Card Status 中 READY_FOR_DATA 和 CURRENT_STATE 必须反映实际状态。

12.5 后台操作(BKOPS)

用途:设备内部的维护任务(磨损均衡、垃圾回收、坏块扫描等)。

控制

  • BKOPS_SUPPORT[502]:设备是否支持。
  • BKOPS_EN[163]:bit0=手动使能,bit1=自动使能。
  • BKOPS_START[164]:写 1 触发手动 BKOPS。
  • BKOPS_STATUS[246]:当前 BKOPS 等级(≥2=紧急,需主机让出总线时间)。
  • EXP_EVENTS_STATUS[54] bit0:URGENT_BKOPS(异常事件,设备主动通知主机)。

主机行为:在 I/O 空闲期让设备执行 BKOPS(通过 CMD6 写 BKOPS_EN=1 或发送 BKOPS_START),避免设备在繁忙时突发 GC 导致性能抖动。

12.6 Cache 与掉电

Cache 机制

  • CACHE_CTRL[33]:写 1 使能写缓存。
  • 写命令数据先进入 cache(快),后台再写入 NAND(慢)。
  • FLUSH_CACHE[32]:写 1 触发强制刷写(R1b,超时可长达 30 s)。

掉电流程(主机侧,见 Linux mmc_poweroff_notify):

  1. 刷写 cache(FLUSH_CACHE)。
  2. 发 POWER_OFF_NOTIFICATION[34]:短通知(快速关机)或长通知(完整刷写后关机)。
  3. 掉电。
  • 设备收到长通知后保证 cache 落盘(POWER_OFF_LONG_TIME[247] 超时)。
  • 未通知直接断电可能导致 cache 数据丢失(规范未保证)。
  • 设备固件须在 掉电检测中断 中紧急刷写 cache(若有备电/大电容)。

12.7 寿命监控

字段 偏移 含义
PRE_EOL_INFO 267 0x01=正常(>90% 寿命),0x02=警告(80%消耗),0x03=严重(建议更换)
DEVICE_LIFE_TIME_EST_TYP_A 268 MLC 区估计寿命(0x01–0x0B,0x01=<10%消耗,0x02=10–20%,…,0x0B=100%消耗,0x00=未定义)
DEVICE_LIFE_TIME_EST_TYP_B 269 SLC cache 区估计寿命(同上编码)

主机应定期读取这些字段,上报健康状态;PRE_EOL_INFO=0x03 时应触发告警/更换流程。


13. 时序模式与性能

13.1 时序模式总览

模式 时钟频率 位宽 信号方式 最大带宽(×8) 引入版本 信号电压
Legacy 25 MHz x1/x4/x8 SDR 25 MB/s(×8) 4.0 3.3 V
High Speed(HS) 52 MHz x1/x4/x8 SDR 52 MB/s(×8) 4.0 3.3 V 或 1.8 V
DDR52 52 MHz x4/x8 DDR 104 MB/s(×8) 4.4 1.8 V 或 1.2 V
HS200 200 MHz x4/x8 SDR 200 MB/s(×8) 4.5 1.8 V 或 1.2 V
HS400 200 MHz x8 DDR 400 MB/s(×8) 5.0 1.8 V 或 1.2 V
HS400ES 200 MHz x8 DDR + 增强选通 400 MB/s 5.1 1.8 V 或 1.2 V
  • SDR:数据在 CLK 上升沿采样。
  • DDR:数据在 CLK 双沿采样(主机必须支持 DDR 控制器)。
  • DS(Data Strobe):HS400 模式下设备输出 DS 信号(200 MHz,与数据同相),主机用 DS 而非 CLK 采样数据——大幅降低时序偏移容忍要求。HS400ES 进一步使用 DS 调谐机制(主机按 DS 边沿调整采样点)。

13.2 驱动强度

EXT_CSD[197] DRIVER_STRENGTH 上报支持的驱动强度类型:

类型 说明
Type 0 0x1 50 Ω(默认)
Type 1 0x2 33 Ω(更强驱动,适合长走线)
Type 2 0x4 66 Ω
Type 3 0x8 100 Ω
Type 4 0x10 40 Ω
  • HS200/HS400 切换前可选 CMD6 写 HS_TIMING 时附带驱动强度(bit[7:4])。
  • 设备固件在 HS_TIMING 写入时同步更新输出驱动强度。

13.3 性能影响因素

  • SLC Cache:多数现代 eMMC 使用 TLC/QLC 颗粒,配备 SLC Cache(将部分 TLC 区当 SLC 用),写入时先进 SLC Cache(快),Cache 满后直接写 TLC(慢,持续带宽骤降)。Cache 大小由厂商决定,不可通过 EXT_CSD 配置。
  • 后台操作:BKOPS/GC 期间写延迟增加。
  • CMDQ:多任务并行可掩盖命令往返开销;深度 16–32 时随机 4K IOPS 显著提升。
  • 写放大:FTL 的 GC 产生额外写入;TRIM/Discard 帮助 GC 预判无效块,减少写放大。

14. eMMC 设备内部架构与 FTL

本章从设备固件开发视角描述 eMMC 内部结构——这些内容在协议规范中不可见,但对固件工程师至关重要。

14.1 内部架构总览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
┌──────────────────────────────────────────────────────────┐
│ eMMC 封装内 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Host Interface │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │CMD 解码/ │ │DAT FIFO/ │ │ 响应生成/│ │ │
│ │ │CRC 校验 │ │位宽控制 │ │状态维护 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ 命令/数据 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ FTL / 控制器固件(CPU + SRAM + 固件代码) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │地址映射 │ │磨损均衡 │ │坏块管理 │ │ │
│ │ │(L2P表) │ │(WL) │ │(BBM) │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │垃圾回收 │ │写缓存/ │ │掉电保护 │ │ │
│ │ │(GC) │ │SLC Cache │ │(journal) │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │ECC 管理 │ │Boot/RPMB │ │ │
│ │ │(BCH/LDPC)│ │安全管理 │ │ │
│ │ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ NAND 操作 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ NAND 阵列控制器 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │页面缓冲 │ │多Plane │ │CE/RB管理 │ │ │
│ │ │(page buf)│ │交织控制 │ │ │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ NAND Flash 颗粒(SLC/MLC/TLC/QLC) │ │
│ │ · 页(4 KB / 8 KB / 16 KB)+ OOB │ │
│ │ · 块(128–512 页/块) │ │
│ │ · Die / Plane / LUN 层次 │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘

14.2 NAND 颗粒特性(固件须知)

特性 说明 固件影响
页大小 4 KB / 8 KB / 16 KB(+ OOB) 决定 LBA→物理页映射粒度
块大小 128–512 页(0.5–8 MB) 决定擦除单位、GC 粒度
页类型 SLC(1 bit/cell)/ MLC(2)/ TLC(3)/ QLC(4) SLC 写快但容量低;TLC/QLC 写慢但容量高
读干扰 同一块内相邻页读次数过多导致数据错误 读计数管理、定期刷新
编程干扰 编程相邻页时可能影响已编程页 严格顺序编程(sequential write)
数据保持 TLC 通常 1 年(@ 室温),写入后 1 年内读出正确 定期刷新(read reclaim)
坏块 出厂及使用中新产生(写/擦除计数超过阈值) BBT 管理、坏块替换
擦除计数 SLC: 10万次;MLC: 3千–1万;TLC: 1千–3千 磨损均衡必须覆盖全盘

14.3 FTL 核心模块

14.3.1 地址映射(L2P Table)

  • 逻辑块地址(LBA)→ 物理 NAND 页地址的映射表。
  • 映射粒度:通常按”逻辑页”(512 B 或 4 KB,视实现)。
  • 映射表存储:SRAM(热页)+ NAND 映射区(冷页),启动时从 NAND 加载。
  • 混合映射:eMMC 通常采用页级映射(page-level mapping)以支持随机写,代价是 L2P 表较大(16 GB eMMC 约需 4 MB SRAM 存映射,分层管理)。

14.3.2 垃圾回收(GC)

  • 写入新数据时旧页标记为无效;无效页累积后块变”脏”。
  • GC 选择脏块,将其中有效页搬移到新块,然后擦除脏块。
  • GC 类型:
    • 前台 GC(Foreground GC):主机写入时触发,阻塞主机——导致写延迟抖动。
    • 后台 GC(Background GC):在 I/O 空闲期提前执行,减少前台抖动(BKOPS 的一部分)。
  • GC 策略:选择无效页比例最高的块优先回收(贪心),或按磨损均衡选择。

14.3.3 磨损均衡(Wear Leveling)

  • 动态均衡:仅对热数据块轮换使用新擦除块。
  • 静态均衡:也搬移冷数据块(低擦除计数块放热数据,高计数块放冷数据),使全盘擦除计数趋同。
  • eMMC 设备通常内置静态+动态均衡;固件需维护擦除计数表(NAND 或 SRAM)。

14.3.4 坏块管理(BBM)

  • 出厂坏块标记:NAND 块的 spare area 第一个字节 ≠ 0xFF。
  • 使用中坏块:写/擦除失败(ECC 超限、编程超时)标记为坏块。
  • 替换策略:保留”预留块”(spare blocks,出厂时预留若干块),坏块发生时用预留块替换。
  • BBT(Bad Block Table):存在 NAND 固定区域,启动时加载到 SRAM。

14.3.5 掉电保护

  • 日志结构:FTL 的 L2P 表更新、GC 操作、擦除等写入操作用日志结构(journal)记录,掉电后通过日志恢复一致性。
  • 原子写:关键操作(如 L2P 表更新)使用”先写新→再标记旧→最后提交”的方式,保证掉电后不丢失一致性。
  • 备电电容:部分高端 eMMC 内置电容,掉电时可将 SRAM 中的脏数据刷入 NAND。
  • POWER_OFF_NOTIFICATION(见 §12.7):设备收到通知后提前刷写缓存、完成 GC。

14.3.6 ECC 纠错

  • NAND 页的 OOB 区域存储 ECC 校验码。
  • 纠错能力:BCH(50–80 bit/1KB)或 LDPC(更强,适合 TLC/QLC)。
  • ECC 不可纠正时返回 CARD_ECC_FAILED(R1 位 21);固件应触发坏块标记+数据恢复(从镜像/冗余页)。
  • 读刷新(Read Reclaim):读取 ECC 错误接近阈值时,将页数据重写到新位置(防止进一步恶化)。

14.4 性能调优(固件侧)

  • SLC Cache:写入先进 SLC 区,空闲时迁移到 TLC 区——Cache 策略(大小、迁移时机)直接影响持续写入性能。
  • 多 Plane 并行:利用 NAND 多 Plane(2–4 Plane)同时读/写多个页,倍增吞吐。
  • CE 交织:多 CE(Chip Enable)交错操作,隐藏 NAND 忙时间。
  • 写合并:小块写入先在 SRAM 缓冲合并为整页再写入,减少 NAND 写次数。
  • CMDQ 调度:接收多个任务后按最优顺序执行(如把写合并、读局部化),减少 GC 干扰。

15. 固件开发要点

15.1 设备固件模块划分(参考架构)

模块 职责
命令解析器(CMD Parser) 解码 CMD 线命令,校验 CRC,更新状态机,生成响应
数据引擎(Data Engine) 管理 DAT 线传输(块读/写/CMDQ)、CRC16 校验
寄存器管理(REG Manager) 维护 OCR/CID/CSD/EXT_CSD,处理 CMD6 写入并同步内部配置
FTL 映射 L2P 表维护、地址翻译
GC / WL / BBM 垃圾回收、磨损均衡、坏块管理(§14.3)
Cache 管理 写缓存、SLC Cache、刷写控制(FLUSH_CACHE)
RPMB 管理 HMAC 计数器、密钥管理、帧解析(§11.4)
安全引擎 AES-XTS(加密)、HMAC-SHA256(RPMB)、安全擦除
NAND 驱动 页面读/写/擦除、ECC、坏块标记、多 Plane 控制
电源管理 掉电中断处理、POWER_OFF_NOTIFICATION、睡眠/唤醒(CMD5)
Boot 加载器 上电启动代码加载、Boot 分区数据流输出(§9)
诊断/监控 寿命监控(PRE_EOL_INFO/LIFE_TIME)、BKOPS 状态、日志

15.2 关键设计决策(固件工程师须知)

  1. L2P 表粒度:页级映射(灵活但表大)vs 块级映射(表小但写放大高)→ eMMC 通常用页级。
  2. GC 触发策略
    • 空闲块低于阈值 → 触发前台 GC。
    • BKOPS_EN=1 → 空闲时后台 GC。
    • URGENT_BKOPS → 强制前台 GC。
  3. SLC Cache 大小:TLC 容量的 1/30–1/10;写满后降速(”稳态”性能)。
  4. ECC 选择:BCH vs LDPC——LDPC 纠错更强(适合 TLC/QLC),但计算量大、延迟高。
  5. 映射表持久化:掉电前必须刷入 NAND;启动时加载(支持从 NAND 映射区多点恢复)。
  6. 分区固定 vs 动态:boot/RPMB/GPP 大小出厂固定,不可动态调整——生产测试时一次性配置。

15.3 常见故障与排查

故障现象 可能原因 排查方向
CMD1 初始化超时 电压不匹配、时钟过快、信号完整性差 示波器看 CMD 线、检查 VCC/VCCQ
HS200/HS400 切换后 CRC 错误 未调谐、信号质量差、驱动强度不匹配 逻辑分析仪抓 CMD21 调谐块、检查电源纹波
写性能周期性骤降 SLC Cache 耗尽触发 TLC 直写 监测写带宽曲线;增加 SLC Cache 或减少 Cache 触发阈值
随机读写卡顿 前台 GC 阻塞 检查 BKOPS 设置;优化 GC 策略(增加后台 GC 投入)
RPMB 认证失败 HMAC 计算错误、密钥不匹配、帧格式错误 逐字段 dump 对比;检查 HMAC 输入范围
偶发数据错误(ECC 失败) NAND 坏块/读干扰、ECC 强度不足 增加 ECC 强度;增加读刷新频率
掉电后数据丢失 未刷 cache、日志不完整 确认 POWER_OFF_NOTIFICATION 流程;检查备电电容
FFU 升级失败 镜像格式错误、版本不匹配、超时 检查 FFU_STATUS;确认镜像格式与 FFU_FEATURES

15.4 测试与验证

测试项 方法
协议合规 JEDEC CTS(Compliance Test Suite);协议分析仪(LeCroy/Keysight)抓取总线验证每条命令/响应
功能测试 全命令遍历(CMD0–48,含异常参数);状态机全路径覆盖;分区切换压力测试
性能测试 fio(顺序读/写、随机 4K);持续写 10 分钟观察 SLC Cache 降速;CMDQ 深度扫描
可靠性测试 掉电 1000+ 次(随机时刻),数据一致性检查;写/擦除耐久(至 PRE_EOL=0x03);温度循环(-40°C–85°C)
安全测试 RPMB HMAC 篡改检测;Secure Erase 后数据残留检查(读 NAND dump);FFU 异常中断恢复
兼容性测试 多 SoC 平台验证(不同 Host Controller IP);多 NAND 颗粒型号适配

16. 附录:速查表、术语与参考资料

16.1 常用命令速查

命令 功能 响应 典型场景
CMD0 复位/进 Boot 无/R1 初始化、Boot
CMD1 电压协商 R3 初始化
CMD2 读 CID R2 初始化
CMD3 分配 RCA R6 初始化
CMD5 睡眠/唤醒 R1b 低功耗
CMD6 写 EXT_CSD R1b 模式切换、配置
CMD7 选中设备 R1b 初始化、分区切换
CMD8 读 EXT_CSD R1+Data 初始化
CMD9 读 CSD R2 初始化
CMD12 停止传输 R1/R1b 中止多块读写
CMD13 读状态 R1 状态轮询
CMD17/18 单/多块读 R1+Data 数据读
CMD23 设块数 R1 预定义多块、RPMB
CMD24/25 单/多块写 R1 数据写
CMD35/36 擦除范围 R1 擦除/TRIM
CMD38 执行擦除 R1b 擦除/TRIM/Discard
CMD42 锁/解锁 R1b 卡加锁
CMD44–48 CMDQ R1/R1b 命令队列

16.2 EXT_CSD 关键字节速查

偏移 名称 读写 说明
15 CMDQ_MODE_EN R/W CMDQ 使能
32 FLUSH_CACHE W 刷写 cache
33 CACHE_CTRL R/W Cache 使能
34 POWER_OFF_NOTIFICATION R/W 关机通知
61 DATA_SECTOR_SIZE R 逻辑扇区大小
155 PARTITION_SETTING_COMPLETED R/W 分区配置完成
162 RST_N_FUNCTION R/W RST_n 功能
163 BKOPS_EN R/W BKOPS 使能
165 SANITIZE_START W Sanitize 启动
168 RPMB_MULT R RPMB 大小
173 BOOT_WP R/W Boot 写保护
175 ERASE_GROUP_DEF R/W 擦除组定义
177 BOOT_BUS_WIDTH R/W Boot 总线
179 PART_CONFIG R/W 分区配置
183 BUS_WIDTH R/W 总线宽度
185 HS_TIMING R/W 时序模式
192 REV R EXT_CSD 版本
196 CARD_TYPE R 支持的模式
212–215 SEC_CNT R 用户区扇区数
217 S_A_TIMEOUT R 睡眠超时
224 HC_ERASE_GRP_SIZE R 擦除组大小
226 BOOT_MULT R Boot 分区大小
231 SEC_FEATURE_SUPPORT R 安全特性
248 GENERIC_CMD6_TIME R CMD6 超时
249–252 CACHE_SIZE R Cache 大小
254–261 FIRMWARE_VERSION R 固件版本
267 PRE_EOL_INFO R 预寿命终结
268/269 LIFE_TIME EST A/B R 寿命估计
307 CMDQ_DEPTH R 队列深度
308 CMDQ_SUPPORT R CMDQ 支持
493 SUPPORTED_MODE R 支持的模式(FFU)
503 HPI_FEATURES R HPI 特性
504 S_CMD_SET R/W 命令集

16.3 R1 状态位速查

名称 类型 说明
31 OUT_OF_RANGE er,c 地址越界
30 ADDRESS_ERROR erx,c 地址错误
29 BLOCK_LEN_ERROR er,c 块长错误
28 ERASE_SEQ_ERROR er,c 擦除序列错误
27 ERASE_PARAM ex,c 擦除参数错误
26 WP_VIOLATION erx,c 写保护违规
25 CARD_IS_LOCKED sx,a 卡已锁定
24 LOCK_UNLOCK_FAILED erx,c 加锁失败
23 COM_CRC_ERROR er,b 命令 CRC 错
22 ILLEGAL_COMMAND er,b 非法命令
21 CARD_ECC_FAILED ex,c ECC 不可纠正
20 CC_ERROR erx,c 控制器错误
19 ERROR erx,c 通用错误
18 UNDERRUN ex,c 读欠载
17 OVERRUN ex,c 写过载
16 CID_CSD_OVERWRITE erx,c CID/CSD 覆盖
15 WP_ERASE_SKIP sx,c 跳过写保护擦除
14 CARD_ECC_DISABLED sx,a ECC 已禁用
13 ERASE_RESET sr,c 擦除已复位
12:9 CURRENT_STATE (4 bit) sx,b 当前状态
8 READY_FOR_DATA sx,a 数据就绪
7 SWITCH_ERROR sx,c CMD6 切换失败
6 EXCEPTION_EVENT sr,a 异常事件(5.0+)
5 APP_CMD sr,c APP 命令标志

类型说明:e=错误,s=状态,r=响应,x=执行中;a=按状态清,b=按前一命令清,c=读清。

16.4 术语表

术语 全称 说明
BGA Ball Grid Array 焊球阵列封装
BBT Bad Block Table 坏块表
BKOPS Background Operations 后台操作
CMDQ Command Queue 命令队列
CSD Card Specific Data 卡特定数据
DS Data Strobe 数据选通
DDR Double Data Rate 双倍数据速率
ECC Error Correction Code 纠错码
EXT_CSD Extended CSD 扩展 CSD
FFU Field Firmware Update 现场固件更新
FTL Flash Translation Layer 闪存转换层
GC Garbage Collection 垃圾回收
GPP General Purpose Partition 通用目的分区
HMAC Hash-based Message Authentication Code 基于哈希的消息认证码
HPI High Priority Interrupt 高优先级中断
LBA Logical Block Address 逻辑块地址
L2P Logical-to-Physical 逻辑到物理映射
OCR Operation Conditions Register 工作条件寄存器
OID OEM/Application ID OEM/应用标识
PNM Product Name 产品名
RCA Relative Card Address 相对卡地址
RPMB Replay Protected Memory Block 重放保护内存块
SDR Single Data Rate 单倍数据速率
SLC Single-Level Cell 单层单元
TLC Triple-Level Cell 三层单元
TRIM 逻辑块无效化(比 Erase 快)
WL Wear Leveling 磨损均衡

16.5 参考资料

  1. JEDEC JESD84-B51:Embedded MultiMedia Card (e•MMC) Electrical Standard (5.1)
  2. JEDEC JESD84-B50:e•MMC 5.0 Electrical Standard
  3. JEDEC JESD84-B45:e•MMC 4.5 Electrical Standard
  4. Linux 内核源码(权威实现参考):
    • include/linux/mmc/mmc.h:命令定义、R1 状态位、EXT_CSD 偏移、擦除参数
    • drivers/mmc/core/mmc.c:初始化流程、CID/CSD 解码、时序切换、CMDQ/BKOPS 使能
    • drivers/mmc/core/mmc_ops.c:CMD6/CMD8/CMD13 实现
  5. SD 规范(对比参考):SD Physical Layer Simplified Specification v9.00

文档完成。如有勘误或补充,请参考 JEDEC 规范原文及 Linux 内核最新实现。