eMMC(embedded MultiMediaCard,嵌入式多媒体卡)是焊接在设备主板上的嵌入式闪存存储器,它把 NAND Flash、闪存控制器 和 MMC 协议接口封装在一个芯片包里,对主控暴露为接近“块设备”的存储介质。
一句话说,eMMC 不是裸 NAND,也不是可插拔 SD 卡;它更像一颗板载的、带控制器的小型闪存盘,常用来存放 Bootloader、Linux kernel、RootFS、应用数据和设备配置。
核心问题
嵌入式设备需要一种可启动、成本低、体积小、软件复杂度可控的非易失存储。裸 NAND 容量大、便宜,但有几个麻烦:
- NAND 按 page 读写、按 block 擦除,不能像 SRAM 或 NOR Flash 那样任意字节覆盖。
- NAND 出厂就可能有坏块,运行中也会产生新坏块。
- NAND 单元写擦寿命有限,反复写同一区域会提前磨损。
- NAND 读出的 bit 可能出错,需要 ECC(错误纠正码)。
- 操作系统更希望看到连续 LBA 扇区,而不是管理 page、block、erase count 和 bad block。
eMMC 的核心价值是把这些 NAND 管理问题放进芯片内部的控制器,让 SoC 和操作系统通过标准 MMC/eMMC 命令读写逻辑块。
核心对象
| 对象 | 作用 | 工程关注点 |
|---|---|---|
| NAND array | 真正存储数据的闪存颗粒 | page、block、擦除次数、坏块、bit error |
| eMMC controller | 芯片内部控制器 | FTL(闪存转换层)、磨损均衡、坏块管理、ECC |
| host controller | SoC 侧 MMC 控制器 | 时钟、电压、总线宽度、时序模式、驱动 |
| boot0 / boot1 | eMMC 专用启动分区 | 早期启动镜像、只读/写保护、启动配置 |
| user area | 普通大容量数据区 | GPT/MBR、kernel、RootFS、数据分区 |
| RPMB | Replay Protected Memory Block | 防回放安全存储、密钥烧录、计数器 |
| EXT_CSD | eMMC 扩展寄存器信息 | 容量、寿命估计、分区配置、boot 配置 |
| LBA | 逻辑块地址 | 操作系统看到的扇区编号,不等于物理 NAND 地址 |
核心机制
eMMC 把“主机请求逻辑块”转换成“内部 NAND 读写和维护”。
典型读写路径如下:
- 主机发命令:Linux block layer 或 Bootloader 通过 SoC 的 MMC host controller 发出读写命令。
- eMMC 接收 LBA:命令中包含逻辑块地址和长度,例如从第
L个 512B 扇区开始写n个扇区。 - FTL 查映射:eMMC 内部 FTL(闪存转换层) 把逻辑地址映射到某些物理 NAND page。
- 写入新物理页:NAND 不能原地覆盖,控制器通常写到新的空闲 page。
- 更新映射表:逻辑地址改指向新 page,旧 page 变成无效数据。
- 后台回收:控制器把仍有效的数据搬走,擦除整块 block,释放可写空间。
- 纠错和坏块处理:读写时使用 ECC(错误纠正码),发现异常时触发重映射或 坏块管理。
逻辑地址映射可以用一个简化公式表示:
physical_page = mapping_table[LBA]LBA是主机看到的逻辑块地址。mapping_table是 eMMC 控制器维护的映射表,不直接暴露给主机。physical_page是 NAND 内部真实 page 位置。- 这个映射不是固定不变的;控制器会为了磨损均衡、垃圾回收和坏块替换而移动数据。
这也是为什么 eMMC 看起来像块设备,但内部行为并不等同于机械硬盘或普通 RAM。顺序写、随机写、掉电、擦除块大小和控制器后台回收都会影响性能与寿命。
分区与启动
Linux 中常见设备节点包括:
/dev/mmcblk0 # user area
/dev/mmcblk0p1 # user area 上的第 1 个分区
/dev/mmcblk0boot0 # boot0 分区
/dev/mmcblk0boot1 # boot1 分区
/dev/mmcblk0rpmb # RPMB 区域嵌入式启动链通常是:
- SoC Boot ROM 根据 strap、efuse 或启动配置选择 eMMC。
- Boot ROM 从 boot0、boot1 或 user area 的固定位置加载早期 Bootloader。
- Bootloader 初始化 DDR、时钟、MMC 控制器和 设备树。
- Bootloader 从 eMMC 读取 kernel、dtb、initramfs 或 RootFS。
- Linux 启动后把 eMMC 作为块设备挂载系统和数据分区。
不同芯片和板卡的启动源选择、boot 分区启用方式、写保护方式和镜像偏移可能不同,量产脚本必须按具体平台确认。
工程用途
- 作为嵌入式 Linux / Android 的主系统盘。
- 存放 bootloader、kernel、dtb、RootFS、recovery、A/B OTA 分区和用户数据。
- 在量产中通过 USB 烧录、fastboot、U-Boot、工装或厂商工具写入镜像。
- 用 EXT_CSD 寿命估计、错误日志和读写性能判断存储健康状况。
- 用 RPMB 存放防回放的小型安全状态,例如安全启动计数器或密钥派生材料的绑定状态。
常见诊断命令包括 lsblk、dmesg | grep -i mmc、mmc extcsd read /dev/mmcblk0、cat /sys/block/mmcblk0/device/life_time 以及检查分区表和挂载参数。
eMMC 与 UFS 的区别
| 维度 | eMMC | UFS |
|---|---|---|
| 设备定位 | 低成本、成熟、板载托管式 NAND | 高性能移动/嵌入式托管式 NAND |
| 主机接口 | MMC/eMMC 总线,常见为并行数据线 | MIPI M-PHY + UniPro 高速串行链路 |
| 通信方向 | 更接近半双工访问模型 | 支持[[全双工通信 |
| 并发能力 | 队列和并发能力有限,常见系统瓶颈更早出现 | 基于 SCSI 模型和任务/命令管理,适合更高并发 |
| 软件关注点 | EXT_CSD、boot0/boot1、RPMB、MMC host 驱动 | UFSHCI、link startup、gear/lane、LUN、UPIU、SCSI midlayer |
| 选型倾向 | 成本、供货、启动链成熟度优先 | 吞吐、随机 I/O、启动速度、多任务体验优先 |
两者都不是裸 NAND Flash。它们都把 FTL(闪存转换层)、磨损均衡、坏块管理 和 ECC(错误纠正码) 放在芯片内部;真正差异主要在主机接口、并发模型、功耗状态、性能上限和平台 bring-up 复杂度。
边界与常见坑
- eMMC 不是裸 NAND:裸 NAND 的坏块、ECC、磨损均衡通常由外部软件或控制器管理;eMMC 把这些封装进芯片内部。
- eMMC 不是 SD 卡:协议亲缘接近,但 eMMC 焊在板上,启动分区、RPMB、生命周期和量产流程更偏嵌入式。
- eMMC 不等于 UFS:UFS 通常有更高吞吐、更好的并发和更现代的协议,但成本、平台支持和启动链要求不同。
- 块设备外观会掩盖内部擦写成本:频繁小随机写、日志刷盘和数据库写放大会明显影响寿命和延迟。
- 掉电不是普通异常:控制器有缓存和映射表,掉电可能造成最近写入丢失、文件系统损坏或极端情况下设备异常。
- boot 分区写保护要谨慎:量产时写错 boot0/boot1 或永久写保护配置,可能导致设备难以恢复。
- RPMB 密钥通常不可重置:一旦烧录错误密钥,后续认证访问可能永久不可用。
- 性能问题不能只看标称速率:文件系统、discard、后台垃圾回收、空闲块比例、热限制和应用写入模式都会影响实际延迟。