只读分享解决方案文档原理方案设计📅 2026-10-14🔖 Rev 1.0⏳ 还有3日到期
🔧解决方案&应用市场分析 -> 原理方案设计 -> 电子设计&技术探讨 -> eMMC内部架构与分区模型_技术探讨

eMMC内部架构与分区模型_技术探讨

同系列 · 原理方案设计
扫码打开本页
微信扫码

eMMC 内部架构与分区模型

从 Host 控制器到 NAND 阵列的完整拆解 —— 分区模型、命令队列、缓存与可靠性机制的一份系统性参考 | 编制日期 2026-10-14 | 版本号 Rev 1.0

3 大块
器件内部的功能划分
Host 接口 / 内部控制器 / NAND 阵列
6 类区域
硬件分区模型的固定划分
Boot1 / Boot2 / RPMB / User / Backup
14 张图
全部为内联 SVG 架构图
剖面 / 流程 / 映射 / 时序 / 矩阵
12 章正文
从架构到分区再到可靠性
附录 A~D 为速查与排查手册
报告总结

eMMC 在原理图上是一颗 BGA 封装、在软件上是一个块设备名,但在器件内部它是一套完整的存储子系统:有自己的命令解析器、命令队列、缓存、FTL 映射、ECC 引擎、坏块管理与磨损均衡。主控发出一条读命令到数据回来,中间经过多少层转换、哪些层会缓存、哪些层会重试、哪些层会静默地换地址——这些决定了很多在现场被当成「驱动 bug」的现象的真实成因。

这份文档只讲器件内部这一层:长什么样、数据怎么流动、分区怎么切出来、命令队列与缓存怎么工作、可靠性机制怎么落地。不写电气连接与信号完整性、不写驱动移植与命令流程的代码细节、不写 Linux 驱动栈的分层实现。三份文档是并列的互补关系,本文是它们缺失的那一块地基。

结论: eMMC 不是「一块会走总线的大容量 Flash」,而是一颗自带存储子系统的器件—— 它把「LBA 到物理位置的映射、ECC 纠正、坏块替换、磨损均衡、写缓存与合并」全部封在硅片里, 所以主控侧看到的只是一次普通的块读写,而实际的写入次数、物理位置、耗时与掉电行为, 全都被器件内部的策略改写了一遍。所有架构层的现场问题,几乎都能追到这七件事中的一件。 本文所有数值均为量级性描述,具体参数一律以正式 datasheet / JESD84 为准。

读者路径

  • 分区切错了、镜像放错区:直接看第 3 章(六类硬件区域与能力对照)与附录 B(区域能力速查)。
  • 写入丢了、乱序了:看第 6 章(缓存与非对齐写入)与第 4 章(RPMB 的原子性语义),这两章覆盖了绝大多数「数据丢了」的真实成因。
  • 性能不如预期:看第 5 章(CMD 队列的收益条件)与 5.8 节(无 CMDQ 时的替代路径),先分清是「没并发」还是「写放大」。
  • 启动失败、启动源搞不清:看第 9 章(Boot 分区与内部 ROM)与 9.6 节(分层定位)。
  • 要评估寿命与健康度:看第 7 章(ECC、坏块、磨损均衡与寿命预算分摊)。
  • 做选型与能力评估:看第 10 章(版本演进与能力矩阵)+ 11.2 节(能力协商字段清单)+ 附录 C(排查手册)。

1. 为什么需要理解 eMMC 的内部架构

这一章不介绍具体机制,只先把一件事说清楚:eMMC 的「外部接口」与「内部实现」之间存在巨大的抽象落差,而这个落差正是绝大多数架构层困惑的来源。

1.1 外行看到的一颗「SD 卡」,里面到底有什么

在软件视角里,eMMC 就是块设备上的一个设备节点:打开它,读一个扇区,写一个扇区,出错就返回错误码。这个视角是有意简化的,它成立的前提是「你不需要知道数据实际落在哪」。一旦出了问题——写入丢失、性能不达标、寿命掉得比预期快——这个前提就塌了,你必须能看到器件里面去。

器件内部实际发生的事情,与「读一个扇区」这六个字之间隔着至少六层转换:

  • 接口层把命令和数据在引脚上串行化,Host 与器件之间跑的是一套有严格时序的协议;
  • 命令解析器把命令字翻译成内部事务,并判断当前状态下这条命令是否合法;
  • 队列调度器决定这条事务排在缓存前面还是 NAND 前面,排在读队列还是写队列;
  • 缓存层可能直接命中并返回,也可能先收下再择机合并后写入;
  • FTL 映射层把逻辑块号翻译成物理页号,这是磨损均衡与坏块替换的落地点;
  • NAND 阵列真正完成页的编程或读取,期间可能触发内部 ECC 纠错、坏块重映射、页迁移。

这六层里任何一层都可以「悄悄改变」外部观察到的行为:缓存让写入延迟变得不确定,FTL 让同一个 LBA 前后落到不同物理块,ECC 让数据在被读出之前就已经被改写过一次。

外部观察到的现象器件内部真正发生的事如果只看外部会怎么误判
写完立刻掉电,重启后数据丢了写入可能还压在写缓存里,没落 NAND;也可能已经落 NAND 但映射表没落误判为驱动没调用写,或误判为文件系统问题
同样的写操作,时快时慢写缓存是否命中、是否触发回写读改写、是否需要等内部擦除,路径不同误判为总线不稳定或主控性能不够
连续写同一个 LBA,寿命掉得飞快磨损均衡会把长期热写的 LBA 逐步挪到不同物理块;均衡未介入的窗口内,同一 LBA 的反复写入集中在少数物理块上,或写放大把 512 字节变成整页甚至整块误判为「只是多写了点数据」
换了一块料,行为就不一样不同厂商的缓存大小、调度策略、ECC 强度、磨损均衡粒度都不同误判为板级问题或软件版本问题
写到某个固定地址开始大面积报错那个地址可能落在 Host 保护区、Backup 区,或对应物理块已经耗尽误判为容量算错或地址对齐问题
裸读能读出内容,但重启后内容变了ECC 纠正会改写出错的比特,主机拿到的是「正确后的数据」,与阵列里原始存的不完全一致误判为器件不稳定

1.2 三层视角:焊盘与引脚 / 数字接口与协议 / 内部的 Flash 阵列

理解 eMMC 最有效的办法,是把它拆成三个抽象层级。这三个层级的关注点完全不同:最外层是物理的,中间层是协议的,最里层是介质的。绝大多数架构层误解,都发生在跨层推理——拿最外层的直觉去推断最里层的行为。

视角关心什么典型问题本文章节
① 焊盘与引脚电源域有几路、时钟从哪来、数据线几根、上电顺序要求这颗料能不能在我这块板上跑起来?VDDIO 与 VDD 有先后要求吗?第 8 章(内部电源管理与低功耗)
② 数字接口与协议命令怎么发、数据怎么切、状态怎么读、队列怎么管CMD18 之后为什么必须按时发 CMD12?CMDQ 到底解决了什么?第 4、5、11 章
③ 内部的 Flash 阵列LBA 怎么映射到物理位置、ECC 怎么纠、坏块怎么换、寿命怎么摊为什么同容量不同料的寿命差这么多?RPMB 为什么比 User 区更可靠?第 3、6、7 章
三层视角的实用价值

排查问题时先定位你在哪一层,能省掉大量无效尝试:上不了电、识别不到器件在第 ① 层,查电源时序、电平、时钟与初始化命令序列;能识别但命令报错、数据不对在第 ② 层,查协议时序、命令前缀、块长度设置与队列状态;偶尔出错、性能波动、寿命异常在第 ③ 层,查写放大、缓存策略、磨损均衡与 ECC 行为。

最容易浪费时间的做法就是拿第 ③ 层的直觉去解释第 ② 层的现象——例如用「NAND 页要整页写」去解释「为什么块设备一定要按 512 字节对齐读」,这两件事其实处在完全不同的层。

1.3 架构知识在哪些具体问题上值钱

下面这张表是本文的价值清单:每一行都是一个真实会被问到的问题,以及它对应的架构层与本文位置。

现场问题真正该问的是什么对应架构层本文位置
镜像烧不进 Boot 分区Boot 分区的容量是出厂固定的,容量算错就是烧不进;它不是普通分区,Host 侧只能按规范规定的窗口访问③ 介质 / ② 协议第 3.2、3.5、3.9 节
密钥存在 User 区,被读走了User 区没有任何访问控制,谁拿到卡谁就能读到全部 LBA;认证数据必须放 RPMB③ 介质第 3.3、4 章
掉电后数据出现错乱或丢失写缓存里的数据在掉电时是否已经落 NAND、映射表是否先于数据落盘,是两个独立的原子性问题③ 介质第 6.5 节
顺序写很慢但 CPU 占用很高单任务串行模式下 Host 在空转等 NAND,CMDQ 才能把等待时间填满② 协议 / ③ 调度第 5 章
启用 CMDQ 后反而更慢队列太浅、或任务粒度太细,任务切换开销超过收益② 协议第 5.6、5.7 节
日志区寿命远快于预期写放大把随机小写变成整块改写,Boot 区被高频写会拖累整片寿命预算③ 介质第 6.3、7.5 节
整机静态功耗偏高器件停在低功耗状态的条件没满足,或者内部电荷泵在高频访问后没能及时关闭① 物理 / ③ 介质第 8 章
设备上电后偶尔起不来启动源指向了一个空 Boot 分区,或 Boot 分区切换状态与实际镜像位置不匹配② 协议 / ③ 介质第 9 章

1.4 全局架构总览图

把上面三个层级画进一张图,就是本文的总纲。后面每一章都只是在这张图的某一块上放大。

eMMC 全局架构总览:从 Host 焊盘一路走到 NAND 阵列① 焊盘与引脚层 —— 器件在 PCB 上的物理存在电源与地两路独立电源域供内核与接口时钟与命令CLK / CMD / RST命令串行传输数据总线DAT[3:0]高速模式靠边沿采样状态与侦测上电状态反馈热插拔与卡检测这一层只回答一件事:这颗器件能不能被正确唤醒并建立通信。所有电气与时序问题都落在这里。② 数字接口与协议层 —— Host 与器件之间的全部约定命令通道命令字与参数决定做什么数据通道负载按块传输单通道或复用响应与状态响应码与状态寄存器决定成功与否命令队列任务化与排队支持并发提交这一层回答:一条命令从下达到完成经历了哪些阶段,在哪些点允许插入下一个任务。③ 器件内部层 —— 自带的存储子系统接口引擎串并转换、时钟采样块长度与超时管理命令解析与队列调度合法性判定、任务排队读写与刷写时机缓存与刷写控制器读缓存、写缓存合并、回写、丢弃读路径自上而下、写路径自下而上:读命令从上进来直接向下穿透,写命令从下面上来要经过调度与缓存。器件对外只承诺「逻辑块读写语义」,上面六个子模块的具体行为才是不同厂商实现差异的真正来源。读图提示:三层之间不是简单的「层层传递」,而是存在跨层优化——缓存可以绕过部分层,CMDQ 可以把多条命令的等待重叠起来。真正决定外部可观察行为的,是第 ③ 层里的缓存、FTL 与 ECC 这三块;第 5 章、第 6 章、第 7 章分别讲它们。本图为结构性示意,不含任何具体器件的容量、速度与工艺参数;实际能力以正式 datasheet / JESD84 为准。
图 1 · eMMC 全局架构总览:焊盘与引脚、数字接口与协议、内部 Flash 阵列三层结构

1.5 本文的主线:数据在器件内部怎么流动

全文围绕一个问题展开:一条命令从 Host 发出,到数据被交还,中间的每一层都做了什么决定。为了把这条链条讲完整,本文按下面这个顺序推进:

  • 第 2 章先把器件内部剖开,看三大功能块与控制器的八类子模块,再走一遍一次读写的完整旅程。
  • 第 3、4 章讲分区模型:六类硬件区域的边界、容量与能力差异,以及 RPMB 如何用认证语义实现防回滚。
  • 第 5、6 章讲性能的两大引擎:命令队列负责「让等待重叠」,缓存与非对齐写入负责「让写入变少」。
  • 第 7、8 章讲可靠性与功耗:ECC、坏块、磨损均衡如何在硅片里落地,以及器件如何进入低功耗状态。
  • 第 9 章到第 12 章把前面所有机制收到工程侧:启动流程怎么用 Boot 分区、版本演进带来了哪些新能力、系统侧该怎么配、以及一份可直接照做的检查清单。
本文的三个「不写」

为了与同系列另外三份文档划清边界,本文明确不写电气连接与信号完整性、焊接与老化(属电路设计指南);不写驱动移植步骤、命令序列代码与 SDK 调用方式(属软件设计规范);不写块设备层、MMC 子系统、GPT 与文件系统挂载顺序(属 Linux 驱动开发指南)。

本文只写器件内部这一层。读完你应该能回答的是:「这个现象是器件内部哪一层干的、它为什么有权这么干、我能通过系统侧配置改变它吗」。

2. 硬件架构:Host、控制器与 NAND 阵列

这一章把器件从外面切开。先给出三大功能块的划分,再逐个拆解内部控制器的子模块,然后跟着一条命令走完从 Host 到 NAND 再回到 Host 的完整旅程。

2.1 eMMC 器件的三大功能块

eMMC 之所以能被当成一颗「存储芯片」而不是「一颗 Flash」,根本原因在于它内部有一整套把 NAND Flash 变得像块设备的东西。这套东西可以清晰地拆成三大功能块。

功能块职责如果它不存在会怎样本文相关章节
Host 接口物理引脚、串并转换、协议时序、命令与数据的收发、状态与响应编码NAND 的裸接口无法被标准主机控制器驱动,只能靠专用时序发生器访问第 8 章、第 11 章
内部控制器命令解析、队列调度、缓存管理、ECC、FTL 映射、坏块与磨损均衡Host 只能看到裸 NAND 的物理特性,容量、寿命与可靠性都无法管理第 5、6、7 章
NAND 阵列真正存放数据的介质,按 die / block / page 组织,支持多道并行容量为零,且任何写磨损与坏块都需要 Host 自己处理第 2、7 章

2.2 内部控制器由哪些子模块构成

内部控制器不是一个黑盒,它由八类子模块拼成。理解这八块的职责边界,比记住任何一条命令流程都有用——因为工程上遇到的现象,几乎总能落到其中一块。

子模块核心职责它做的关键决定典型影响
接口引擎串并转换、采样与时序、块长度与超时管理用多少时间片完成一次事务、超时后如何恢复总线占用率、超时行为
命令解析器识别命令字、校验前置状态、拆解参数这条命令当前是否合法、是否需要重试非法命令的响应码、超时行为
队列调度器把命令转成任务、分配队列、决定执行顺序哪条任务先跑、读与写怎么交错并发度、尾延迟、顺序保证
缓存控制器管理读缓存与写缓存的分配、合并与回写数据是留在缓存里还是落 NAND、怎么合并写入延迟抖动、写放大、掉电风险
ECC 引擎页级校验、纠错、错误分类与上报哪些错能纠、哪些要标记坏块读出数据的正确性、坏块增长速度
FTL 映射维护逻辑块到物理位置的映射表这个 LBA 现在对应哪个物理块寿命分布、并发写入的表现
坏块管理器出厂坏块登记、增长坏块替换、坏块表持久化遇到不可用物理块时替换到哪一块长期可用容量、是否需要重分区
磨损均衡模块按块级或页级分散擦写次数下一次写落到哪一块整片寿命分摊、单点磨损速度
为什么把这八块拆开讲

因为同一个外部现象,落到不同子模块上,规避动作完全相反。「写入偶发丢失」若落在缓存控制器,应显式刷写缓存、缩短驻留时间;若落在 FTL 映射,应保证映射持久化顺序;两者都不解决才去怀疑 Host 侧。「性能不如预期」若落在队列调度器,要增加并发;若落在磨损均衡,要减少随机写、增大批量;若落在 ECC 引擎,说明读错误过多导致额外重读。

不做这个拆分,就会出现「明明换了料却没变化」「明明加了并发却更慢」这类无法收敛的排查过程。

2.3 NAND 阵列与数据通路:从 LBA 到页、块、物理位置

NAND 阵列的组织是分层的,从大到小依次是 die(裸片)→ block(块)→ page(页)。这三个层次各自对应一个操作粒度,且操作粒度与数据粒度并不一致——这是写放大与所有非对齐写入问题的物理根源。

  • page:读操作的最小单位。读一个 page 会把整页的数据一次性搬到片上缓存,Host 侧只能取其中一段。
  • block:擦除的最小单位。擦除一个 block 会把其中所有 page 全部恢复为初始态。
  • die:独立的数据分区。同一时刻可以对不同 die 并行发起操作,这也是吞吐的主要来源。

关键的不对称在于:读以 page 为单位、写在 page 为单位、擦除以 block 为单位,而 Host 的访问单位是逻辑块。当一个逻辑块不能整除地映射到一个 page,或者需要改写的部分不足一个 page,主控就必须把动作放大到整页甚至整块。

层次 / 概念定义允许的操作不允许的操作工程含义
LBA(逻辑块)Host 侧看到的地址空间,以固定逻辑块大小为单位按块读、按块写不能按字节或任意长度写块大小由能力协商确定,是所有对齐计算的基础
page(页)读与写的基本单位,固定大小读整页、写整页不能只改页内的一部分而不重写整页非对齐写必然触发回写读改写,见第 6.3 节
block(块)擦除的基本单位,包含固定数量的 page整块擦除不能擦除块内单个 page写放大与寿命消耗以块为单位计量
die(裸片)独立的数据分区,多 die 可并行跨 die 并行命令同一 die 内的操作存在时序约束并行度决定顺序吞吐的上限
FTL 映射项一个 LBA 当前指向的物理位置改指向(不改数据即完成覆盖写)不能跨越坏块策略约束覆盖写不等于原地写,这是寿命分散的关键
把「块大小」和「页大小」混为一谈是最常见的一类现场错误

Host 侧协商出来的逻辑块大小(例如 512 字节或 4 KB)和器件内部的 NAND 页大小是两个完全独立的量,它们之间没有必须整除的关系。实践后果是:「按块访问」不等于「按块写入 NAND」——小块频繁写入会在器件内部被聚合成整页甚至整块写,「我一个月才写几十 MB,怎么寿命掉这么快」这类问题多半出在这里。

2.4 内部架构剖面图

把第 2.1 与 2.2 节的内容叠成一张剖面图,就是器件内部的真实形态。注意右侧的职责标注——这是排查问题时最常回查的一张图。

内部架构剖面:从封装焊盘一路切到 NAND 阵列外部接口层焊盘 / 串并转换 / 协议时序命令解析器合法性判定与参数拆解队列调度器任务化、排队、读写交错缓存控制器读缓存 / 写缓存 / 合并与回写ECC 引擎页级校验、纠错、错误分类FTL 映射 + 可靠性管理坏块表、磨损均衡、映射持久化NAND 阵列多 die 并行,页 / 块 两级组织每一层在做什么(排查时的回查表)接口层总线占用率、超时→ 上不了电、识别不到命令解析非法命令响应→ 命令报错误队列调度并发度与尾延迟→ 慢,但 CPU 空闲缓存控制写入延迟与写放大→ 写入抖动、寿命偏快ECC读出正确性、坏块增速→ 偶发读错、重读变多FTL逻辑到物理的映射→ 同容量寿命差很多可靠性坏块替换与均衡→ 容量缓慢变小NAND 阵列介质本身的极限→ 达到寿命或出现增长坏块读路径:从上往下穿透,写路径:从下往上排队。前者延迟低但可能撞上坏块,后者吞吐高但需要调度与合并。这张分层不是物理版图,实际芯片里这些模块与 NAND 阵列是交织布局的;图只表达职责归属。各子模块的名称为功能性描述,不同厂商的实现命名与集成方式不同;不要用本图去推断某颗料的数据手册结构。
图 2 · eMMC 内部架构剖面:从接口层到 NAND 阵列的八级职责分层

2.5 数据一次读写的完整旅程

现在把前面的概念串成一条完整链路。下面是一次读操作和一次写操作的完整路径,每一步都标注了它属于哪一层,这样以后看到现象就能立刻定位。

步骤读操作(CMD17 / CMD18)写操作(CMD24 / CMD25)所属层
1Host 把命令字与参数放到命令通道上,器件按位采样同左,命令指向目标块地址接口层
2命令解析器识别命令、检查前置状态(是否已选中、块长度是否设定)同左,另外检查写保护与目标区域是否合法命令解析
3任务进入读队列,等待调度器分配总线与时序片任务进入写队列,可能先被写缓存吸收队列调度
4FTL 查表得到物理页号FTL 查表得到目标物理页号;若命中已分配页则直接改写,若需新页则从空闲池取FTL
5NAND 页读出,数据进入器件内部读缓存写缓存暂存数据;若缓存不足则触发回写或合并缓存
6ECC 引擎对整页做校验并纠正ECC 引擎在落盘时生成并写入校验信息ECC
7如有不可纠错错误,标记坏块并由磨损均衡改映射如有坏块,改由备用块承接可靠性
8数据经数据通道返回 Host,状态寄存器置位数据落 NAND 后更新映射与状态接口层
9Host 轮询到完成,读取状态确认无错Host 轮询到完成;掉电风险点在第 5 到第 8 步之间接口层
读操作里最容易被忽略的一步

第 6 步 ECC 纠错会改写数据——Host 拿到的数据与 NAND 阵列里物理存放的位流并不完全相同,器件在读出路径上做了修正。两个后果:用裸读手段「验证数据是否与写入时一致」时,出现过软错误之后可能发现不一致,但这是正常的纠正结果而非器件缺陷;ECC 强度是设计取舍,纠错能力越强所需额外存储位越多、容量开销越大,读错误率超过纠错能力时才表现为「读不出来」而不是「读错了」。

2.6 器件内部的数据流总览

把一次读写拆成「谁在什么时候把活干完」,就能看清哪些阶段可以被重叠、哪些阶段必须串行。这张图也是第 5 章与第 6 章的铺垫。

内部数据流:六个阶段与它们各自的代价来源1命令与参数落地Host 发出命令字,器件完成采样与合法性判定2任务排队与调度任务进入队列,调度器决定何时占用内部资源3映射与地址翻译FTL 查表得到物理页,必要时触发分配或替换4缓存决策命中则直接返回,否则收下或回写读改写5NAND 阵列操作页级编程或读取,必要时先擦除目标块6ECC 校验与响应纠错、错误分类、写回映射与状态每一段的代价来自哪里协议时序跟 PCB 走线与主控时序有关调度策略跟队列深度与并发数有关映射开销跟逻辑到物理的表项有关缓存行为跟缓存容量与刷写策略有关介质特性跟页块划分与并行度有关纠错能力跟 ECC 强度与错误率有关读命令走到第 4 步如果命中缓存就可以直接回数据;写命令走到第 4 步往往还要等回写窗口才会真正落到 NAND。这六步的串行性决定了单任务模式下吞吐的上限,也决定了命令队列能带来多少重叠空间(见第 5 章)。阶段划分为功能性描述;不同厂商在具体实现上的合并与拆分方式不同,缓存与映射的边界各家也不一样。
图 3 · 器件内部数据流总览:六个阶段、每一段的代价来源与可优化边界

2.7 厂商实现差异

标准定义的是外部可观察的行为,不定义内部怎么做。因此同容量、同版本的两颗 eMMC,在缓存大小、调度策略、ECC 强度、映射粒度上都可以差很多。这解释了为什么「换料就出问题」经常发生。

实现维度差异的可能范围对系统侧的表现验证方式
内部缓存大小从很小到较大,可能只读缓存与读写缓存分开突发写入的抖动幅度不同,写放大倍率不同顺序写与小随机写混合压测,对比延迟分布
写缓存策略是否启用、合并窗口多大、什么条件下回写掉电时可能丢多少数据窗口不同写入过程中随机断电,检查最后一次提交的数据是否存活
ECC 强度与算法纠正能力与容量开销的取舍不同读错误率不同、重读次数不同、可选终止时机不同长时间读压测,统计可纠正错误上升趋势
FTL 映射粒度按逻辑块映射或按更细粒度映射同容量下寿命分布差异明显随机写压测后读取健康度信息对照
磨损均衡粒度静态、动态或二者结合,块级或页级频繁改写的小区域是否成为磨损热点高频改写同一逻辑块,观察整体寿命
坏块策略备用块数量、增长坏块替换阈值长期使用后可用容量是否下降老化测试中定期读取坏块相关信息
队列与并发实现支持的队列数、队列深度、任务完成顺序规则并发收益曲线不同、顺序保证不同多队列并发压测并校验数据一致性
换料时的正确做法

因为上述差异,换料不是「同容量可直接替换」。方案层面要把架构相关的行为做成可探测而不是可假设——启动时把能力协商字段完整取出来并记录存档,不要在代码里硬编码任何来自某颗料的经验值。验证层面要对每颗新料至少跑三类测试:混合读写压测(看延迟分布与写放大)、随机断电测试(看缓存与映射的原子性)、高频小写老化(看寿命分摊是否合理)。

更详细的可观测性字段见第 7.7 节,能力协商字段清单见第 11.2 节。

3. 分区模型:六类硬件区域

eMMC 的分区不是操作系统画的,而是器件出厂时就在硅片里切好的。这一章把六类硬件区域的边界、容量来源与能力差异讲清楚,并说明它们与 GPT 的分工关系。

3.1 为什么要有分区:掉电安全与多用途共享

如果 eMMC 只是一个大容量可写块设备,那么所有内容——启动镜像、密钥、日志、用户数据——就会混在同一片地址空间里,任何一次误写或掉电都可能同时毁掉它们。硬件分区模型的本质是用物理隔离换取语义隔离:让某些区域天生具备不同的能力,让另一些区域从物理上就不可能被普通写入碰到。

三条设计动机:掉电安全(启动镜像必须在掉电后仍完整可执行,需要一块写入策略更保守的区域)、认证性(密钥不能被任何人读到,需要一块伪造会被拒绝的区域)、多用途共享(同一颗器件要同时服务启动、认证、用户数据、备用,地址空间上必须分开)。

需要特别澄清的一点:硬件分区与操作系统的分区表是两套机制。硬件分区在器件出厂时就固定了;操作系统分区表(如 GPT)是写在某个区域里的数据结构,必须依附于硬件分区才能生效。这个分层关系是理解第 3.8 节的前提。

3.2 Boot1 / Boot2:上电即执行区

Boot1 与 Boot2 是器件内部预留的启动区,容量在出厂时固定。它们存在的理由很直接:系统上电后,主控还没有跑起来,此时唯一可用的存储就是这两块区域。主控的启动 ROM 只需要按固定规则从这里取数据,就能把第一段代码搬到 SRAM 或内部运行区执行。

Boot 分区有三个常被忽略但很重要的架构属性:

  • 容量固定且很小:这是它作为「上电即用」区域的前提,也是最常见的现场错误来源(详见第 3.9 节)。
  • 访问方式受限:Host 侧不是通过普通 LBA 访问它,而是按规范规定的分区号与固定偏移访问。
  • 切换是双份的:Boot1 与 Boot2 成对存在,用于「一份在写、另一份保持有效」的更新模式;启动源指向哪一份由配置决定,不是 Host 临时决定。
维度Boot1 / Boot2 的架构属性对设计的含义
容量出厂固定,与具体型号绑定,不占用 User 区容量镜像必须按容量裁剪,不能按 User 区容量规划
寻址方式Host 侧通过分区号加固定偏移访问,不是普通 LBA 空间烧写工具要按分区号下发,而不是按地址
双份结构成对存在,用于更新时一份在写一份保持有效更新流程必须处理「更新中掉电」的中间态
启动源选择由器件内配置决定指向哪一份或 User 区切换要显式下发命令,不能靠写入位置隐式决定
内部 ROM 支持规范定义了从 Boot 区启动的固定流程,ROM 负责搬运第一级引导不必由主控代码实现
可靠性语义写入量小、可校验,主要承担可引导责任不适合放日志、参数或任何高频写数据
是否放文件系统不放镜像必须是裸的、位置固定的连续数据

3.3 RPMB:一写入一读取的认证区

RPMB(Replay Protected Memory Block,防重放保护存储区)是本文里最需要被正确理解的一块。它的核心不是「一块特殊存储」,而是一套带密钥认证的原子读写语义:写入必须携带正确的认证标签,读取返回的数据同样带标签,因此任何一方都能验证数据没有被仿造或重放。

三句话说清它的定位:

  • 认证性:帧内携带由密钥派生的认证标签,主机与器件各自持有一份密钥,只有知道密钥的一方才能产生合法帧。
  • 原子性:一次写入要么完整生效、要么完全不生效,不会出现「数据写了一半」的中间态。
  • 防重放:每个成功写入都会递增一个写计数器;写入请求必须携带与器件当前值相等的写计数器,不等(无论大小)即拒绝,从而防重放。
维度RPMB 的架构属性典型用途误用后果
访问控制无认证的读写一律被拒绝,只有合法帧才生效密钥材料、授权票据、一次性凭证把密钥放 User 区,等于公开存储
原子性帧级原子,写入要么全成功要么不生效需要保证「要么更新要么不变」的状态把关键状态放在无原子保证的普通区
防重放写计数器单调递增,落后或重复的计数被拒绝固件版本、授权次数、事件序号版本可被回滚,安全机制形同虚设
容量出厂固定,版本不同大小不同,通常远小于 User 区只放小体积、高价值的状态数据拿它当大容量数据区用,根本装不下
性能每次访问都要计算认证标签,开销大于普通读低频关键数据拿它存高频日志,性能无法接受
密钥位置密钥本身存放在器件内的一次性可编程区由一次性可编程机制锁定,不可改写密钥存到外部 Flash,认证模型立刻失去意义

3.4 User 区:容量主体与 GP 分区

User 区是容量主体,标称容量基本都指它。它在架构上有一个关键特点:被切成若干通用分区(GP 分区),每个 GP 分区在主机侧表现为一个独立的逻辑块设备。GP 分区本身不带任何特殊能力,它的存在只是为了在一块物理器件上划出多个互相独立的空间。

需要注意的是,GP 分区与操作系统分区表是两回事:GP 分区是硬件层的切分(由器件配置决定,主机通过分区号选择),而 GPT / MBR 是软件层的切分(写在某个区域里,操作系统读它来挂载文件系统)。同一个 GP 分区内部可以再放一整张 GPT。

3.5 硬件分区地址映射与容量关系

下面这张图与接下来的对照表是本章最重要的一张图。关于容量只有一条必须记住的规则:Boot 与 RPMB 的容量来自器件出厂配置,不从 User 区里扣;而标称容量指的是 User 区的容量。把两者混在一起算,是分区规划阶段最常见也最难在早期发现的错误。

六类硬件区域在地址空间中的位置与容量关系Boot1Boot2RPMBGPUser 区Backup示意图,段宽非按真实容量比例绘制:Boot 与 RPMB 的容量是出厂固定的,User 区占据其余全部可用空间。Backup 区不属于可直接寻址的数据空间,它承载坏块表、映射信息等内部元数据。区域寻址方式容量从哪来掉电后的一致性语义Boot1 / Boot2固定窗口出厂固定,与型号绑定可引导启动,依赖写入完整性校验RPMB固定窗口出厂固定,版本不同大小不同认证写入,帧级原子性与防回滚GP 分区普通 LBA 空间从 User 区切出,可自由规划无特殊保证,等同普通数据区User 区普通 LBA 空间扣除保留区后的剩余部分仅受写缓存与掉电检测影响Backup 区不可直接寻址随器件配置而定内部保证一致性,不对外承诺保留区不可访问厂商内部预留不可用,也不计入容量标称关键结论:Boot 与 RPMB 的容量来自器件出厂配置,不是从 User 区里切出来的,写分区表时千万不要把它们算进可用容量。各区域的容量、地址窗口与访问权限以正式 datasheet / JESD84 为准,本图不用于任何容量计算。
图 4 · 六类硬件区域的地址映射方式、容量来源与一致性语义对照

3.6 Backup 区与保留区

Backup 区不是给用户放数据的地方,它是器件给自己的:坏块表、映射信息、磨损均衡的统计状态等内部元数据存放于此,Host 侧不能把它当普通 LBA 访问。保留区则是厂商内部预留,既不可访问也不计入标称容量。

Backup 区的存在解释了一个常见现象:eMMC 的标称容量并不等于地址空间末端。地址空间的最高若干块往往落在保留区,越界访问得到的是错误而不是数据。如果系统侧按「容量 × 块大小」直接算地址上界,尾部可能撞进保留区。

3.7 三种区域的能力对照表

把 Boot 区、RPMB、User 区(含 GP 分区)放在一起对照,五个维度上的差异一目了然。这张表建议直接抄进设计文档作为分区选型的判据。

能力维度Boot 区(Boot1 / Boot2)RPMBUser 区(含 GP 分区)
可读性可读,内容通常是裸镜像可读,但只有合法认证帧能被接受完全可读,无任何保护
可写入性可写,但 Host 侧写入受限可写,必须携带合法认证标签与正确计数完全可写,无限制
认证性无认证语义,靠位置约定有,帧级认证,防仿冒无,任何持有卡的人都能读到全部内容
原子性取决于写入策略,可校验帧级原子,保证要么全成功要么不生效仅受写缓存与掉电检测影响,无强保证
防回滚无有,写计数器单调递增无
容量出厂固定,很小出厂固定,很小标称容量的全部,不含 Boot 与 RPMB
寻址方式分区号加固定偏移分区号加固定偏移普通 LBA 地址空间
典型用途启动镜像引导代码密钥、授权状态、版本计数系统镜像、用户数据、日志、参数
是否适合放文件系统否否是,这是它唯一适合做的事
写入频率预期极低,只在升级时写低,只在状态变化时写高,可能持续高频写入
五个维度里最容易被忽略的是「认证性」和「防回滚」

可读性与可写入性几乎所有人都懂,但下面两条经常在评审时被跳过:认证性是分区属性而非软件属性——用户区的任何 LBA 都能被任何持有卡的人读出来,加密只能靠数据本身,不能靠分区来加密;防回滚必须由器件保证——如果版本号或计数存放在用户区,攻击者或误操作可以写回一个更旧的合法镜像,防回滚立刻失效,其载体必须在 RPMB 这类带计数的区域里。

3.8 硬件分区与 GPT 的分工

硬件分区与软件分区表是上下两层,各管一件事。搞混这一层的常见后果是「分区表写对了但系统起不来」,或者反过来。

  • 硬件分区:由器件出厂配置决定,划出 Boot、RPMB、GP 分区等区域。Host 侧通过分区号选择,写入这个动作发生在烧录阶段。
  • GPT:是一张写在某个区域里的分区表数据结构,描述这块区域内部怎么再分。它是一个普通文件,位于 GP 分区或 User 区的开头,操作系统读取它来建立分区映射。

关键结论:Boot 分区里不放 GPT。原因很直接——GPT 的作用是描述「一个可被操作系统读取的块设备内部怎么分」,而 Boot 分区不是操作系统块设备,它是主控 ROM 直接读取的裸镜像区;把 GPT 写进去只会让 ROM 无法解析。

对比项硬件分区GPT(软件分区表)
由谁决定器件出厂配置你自己写进去的
什么时候确定烧录阶段就固定烧录之后可随时重建
作用范围划出 Boot / RPMB / GP 等物理隔离区域在某个块设备内部再划分逻辑分区
谁解析主控的启动 ROM 与 Host 驱动按规范解析操作系统分区解析层解析
能不能放文件系统Boot 与 RPMB 不能;GP 与 User 可以GPT 本身不是文件系统,它描述文件系统所在分区
写错的后果启动失败或认证失败,现象明显分区丢失或挂载错位,可能被误判为文件系统问题
是否需要备份一般不备份(出厂固定)需要备份,重要设备建议留存原始分区表镜像
两者的关系GPT 必须依附在某个可被操作系统识别的区域里通常写在第一个 GP 分区或 User 区开头

3.9 分区选择的常见错误

下面五条是分区规划阶段的高频错误,每一条都会在后期以很难排查的形式暴露出来。提前对照检查一遍,比事后追查便宜得多。

错误做法为什么错现场表现正确做法
把启动镜像放在 User 区主控 ROM 的启动源默认指向 Boot 分区;User 区里的东西不会被 ROM 自动取走上电后卡在启动 ROM 阶段,日志里看不到任何应用层输出启动镜像放 Boot 区;User 区只放主控 ROM 能定位到的第二级引导
把密钥材料放在 User 区User 区完全可读,无任何认证或保护物理接触卡即可读出密钥,密钥体系形同虚设密钥材料放 RPMB;User 区只放不可逆派生出的结果或引用句柄
Boot 分区容量算错Boot 容量出厂固定,且两份都要放镜像烧录工具报空间不足,或者烧进去了但 ROM 校验不过先从数据手册确认 Boot 容量与启动源配置,再裁剪镜像
两份 Boot 区被同时擦写Boot1 与 Boot2 的设计前提是一份在写、另一份保持有效更新中掉电后两份都不可引导,设备变砖严格按「先写空闲份、校验通过后再切换启动源」的顺序更新
把 Backup 区当可用容量Backup 区是器件内部元数据空间,不对外承诺尾部读写返回错误,文件系统末尾出现不可用空间可用容量一律按数据手册给出的用户可用容量计算,不自行推断

4. RPMB 的认证模型与防回滚

这一章把 RPMB 拆到机制层面。核心命题只有一句:RPMB 的价值不在存储,在于它用器件内部的一次性密钥和单调递增的计数器,把「数据完整性」与「不可回滚」两件事从软件层的自觉变成了硬件层的强制。

4.1 RPMB 要解决的问题:回滚与仿冒

先说清它防的是什么。没有 RPMB 时,主机的安全状态存在普通区域里,会面临两类攻击:

  • 回滚(replay):攻击者或误操作把状态数据恢复成一个更早的合法版本。例如把「已授权次数」改回未使用的状态,或把固件版本号改回旧版本,从而绕过「必须升级才能使用」的限制。
  • 仿冒(forgery):直接构造一份看起来合法的状态数据并写入。在没有认证的区域里,这在技术上就是把几个字节写进去而已。

RPMB 用两个机制分别对付这两类问题:帧级认证标签对付仿冒,单调递增的写计数器对付回滚。缺了任何一个,模型就不完整——只有认证没有计数,就是防住了仿冒但防不住回滚;只有计数没有认证,攻击者可以自己构造一个计数更大的合法帧。

4.2 密钥的派生与存储位置

RPMB 的认证标签能防仿冒,前提是只有可信一方知道密钥。密钥的派生与存放本身就是一个架构问题,而不是一个密码学细节。

  • 存储位置:密钥存放在器件内部的一次性可编程区域。这块区域在出厂后可以被写入一次,之后不可更改——这是模型的信任根。如果密钥存在外部 Flash 里,攻击者读到 Flash 就能生成合法帧,整个认证模型立刻失去意义。
  • 派生方向:一般由主控在生产阶段生成一次性密钥,写入器件的一次性区;运行期器件与主控各自持有同一份密钥,任何一侧泄露都会让认证失效。
  • 一次性可编程的含义:不可更改意味着无法轮换密钥,也无法擦除重来。因此密钥的烧写本身必须被当作一次性不可逆操作来管理,写错就没有补救路径。

工程上最容易被忽略的一点:密钥的烧写要在产线流程里明确留痕。一旦批量烧写后没有记录哪颗器件用了哪把密钥,售后换料时就无法复现,RCP 认证相关的功能会集体失效。

4.3 认证写入与认证读取的流程差异

认证写与认证读都带认证标签,但字段构成与副作用不同。下表列出关键差异,这些差异直接决定了驱动层的实现必须区别对待读写两条路径。

对比项认证写入认证读取对驱动层的含义
是否携带认证标签携带携带两条路径都要实现标签计算,不能只做写
是否需要写计数器需要,且必须等于当前值不需要写前必须先读回当前计数,计数要由驱动维护
是否修改器件状态修改:写入数据并递增计数不修改读操作不能被当作幂等无副作用的探测
失败后的状态完全不变,计数不变不变写失败后可直接重试,不需要回滚动作
副作用的可观察性计数器会前进无副作用掉电后计数是否前进决定了重试是否安全
性能特征更慢:写入 NAND 且要算标签较慢:全量数据都要算标签不适合放在高频路径上
典型用途更新状态、递增序号、写入凭证读取状态、校验数据未被篡改关键状态读取要走认证读而不是普通读
重试是 RPMB 最危险的操作

因为写计数器单调递增,一次成功的写入会让下次重试的计数失效。实际项目中并不罕见这个序列:写入请求发出 → 器件已完成写入并递增计数 → 但响应在总线上丢失或被主控判为超时 → 驱动认为失败,用同一个计数再次发起写入 → 器件以「计数已在更早处用过」拒绝。

此时把驱动当成普通错误继续重试会陷入永久失败;强行改用更大的计数去「试出来」则可能覆盖掉状态。正确做法是:任何写失败之后,必须先做一次认证读取取回当前计数器,再决定下一步。这条「失败后先读回」的纪律,是 RPMB 实现里最重要的一条。

4.4 计数与回滚保护:单调递增语义

写计数器是 RPMB 模型的支柱。它的语义非常朴素但非常严格:任何一次成功的认证写入,都必须让计数单调增加;写入请求必须携带与器件当前值相等的写计数器,不等(无论大小)即拒绝,从而防重放。

这条规则带来三个直接后果:

  • 状态不可回退:攻击者无法把「已用 99 次」改回「已用 0 次」,因为他构造不出计数更大且通过认证的合法帧。
  • 顺序即保护:计数值本身隐含了顺序信息,主机不需要额外的序号字段就能判断状态是否被倒退。
  • 掉电后不会自愈:如果掉电发生在写入过程中,要么整帧生效且计数前进,要么完全不生效且计数不变——不会出现「数据写了一半、计数却已前进」的错位。

反过来也要理解它的成本:计数器空间是有限的,计数每次写入都前进,因此 RPMB 的总写入次数有上限。把高频事件持续写进 RPMB 是设计错误——它既会撞上计数空间,也会带来不可接受的开销。RPMB 应该只存「低频但高价值」的状态。

4.5 RPMB 帧结构与响应码流程

下面这张图把认证写入的帧字段与六个步骤画在一起,同时给出三类典型错误响应的成因与对策。它是实现与排查 RPMB 时最常回查的一张图。

RPMB 帧结构与一次认证写入的完整流程认证写入帧的字段构成帧类型与帧号区分请求与响应,成对出现认证标签由密钥与帧内容派生的校验值写命令与地址目标 RPMB 内的块地址与写入模式数据长度与数据区本次写入的数据内容写计数器单调递增的防回滚计数写计数器与认证标签是 RPMB 的两个核心:前者防回滚,后者防仿冒。一次认证写入的六个步骤1主控取出密钥并派生认证标签2按当前写计数器构造写入帧3发送写入请求,器件校验标签与计数4校验通过后写入数据并递增计数器5器件返回写计数器,供主控同步6主控比对计数器,确认写入生效任一步校验失败,器件都会返回错误码而不修改数据。认证或计数错误密钥不匹配、计数落后先核对密钥来源与计数同步对策计数已在更早处用过同一次掉电后重发导致计数重复必须先读回当前计数再重试对策空间或帧长不足单次数据超过帧容量或区域写满分帧写入并检查剩余容量对策读图提示:认证读取与认证写入的字段不同,但都带认证标签;读取不递增计数器,写入一定递增。帧格式与响应码的具体定义以正式 JESD84 与器件数据手册为准,本文只描述字段职责与流程顺序。
图 5 · RPMB 认证帧的字段构成、写入流程与三类典型错误响应

4.6 常见失败模式与排查路径

RPMB 的失败往往表现为一句含糊的错误码。排查的关键是先判断失败发生在哪一层:是认证没过、计数不对、还是空间与帧长问题。这三类失败的处理方式完全不同,混在一起试会浪费时间。

失败模式根因典型触发场景排查路径规避动作
认证始终不通过密钥不匹配或派生不一致换料后密钥未同步写入;密钥烧写流程缺记录确认器件内密钥来源与主控侧是否同一份派生结果在产线记录每颗器件的密钥烧写结果
计数不同步主控维护的计数落后于器件写失败后未读回计数就重试;掉电后状态未恢复写失败后强制读回当前计数并比对实现「失败先读回」纪律,不盲目重试
响应超时总线上有噪声或信号完整性不足布线过长、缺少串联电阻、时钟质量差先在电气层面排查,不要在协议层面硬改先解决电气问题,必要时降低总线速率验证
空间不足单帧数据超过帧容量或区域写满想拿 RPMB 存大对象核对帧容量上限与区域剩余量只存小体积高价值数据,大对象放别处
返回计数始终为初始值写入从未成功过认证就没通过;或写入到了别的分区号确认分区号选择与启动源配置把分区号与用途做成显式配置项
换料后功能集体失效密钥缺失或不一致维修换料时未重新烧密钥核对换料流程是否包含密钥烧写步骤把密钥烧写写进换料作业标准
RPMB 排查的通用起手式

遇到任何 RPMB 相关问题,按这个顺序做三件事基本能覆盖九成场景:先做一次认证读取——能读出来说明认证链路与密钥没问题,问题在写入路径或计数,读不出来说明是认证或分区的问题;再比对读回的计数与本地计数——不一致说明有过「成功但主控不知道」的写入,计数必须以读回为准;最后才看电气与时序——响应超时类问题优先查布线与信号质量,而不是反复改协议参数。

相关报告 · 交叉引用 1 器件全部展开收起 ▾
点开类目即可展开:具体文档 / 章节(点章直接跳转到该章)
eMMC
电路设计指南
软件设计规范
Linux 驱动开发
样机问题排查
量产问题排查