【Linux驱动开发】eMMC 技术原理与 Linux 平台应用全解析
·
eMMC 技术原理与 Linux 平台应用全解析
文章目录
1. eMMC 技术原理
eMMC (Embedded MultiMediaCard) 是一种将 NAND Flash 存储器与控制电路封装在一起的嵌入式存储解决方案。它通过标准的 MMC 接口与主机通信,屏蔽了 NAND Flash 复杂的物理特性(如 ECC 校验、坏块管理、损耗均衡),大大简化了嵌入式系统的存储设计。
1.1 物理架构
eMMC 内部由控制器(Controller)和 NAND Flash 晶圆(Die)堆叠封装而成。

- Host Interface: 包含时钟(CLK)、命令(CMD)和数据总线(DAT0-DAT7)。支持 1-bit, 4-bit, 8-bit 模式。
- NAND Controller: eMMC 的核心大脑,屏蔽了 NAND Flash 的物理复杂性。其核心功能模块包括:
- ECC (Error Correction Code) 纠错引擎:
- 原理: NAND Flash 随着工艺制程微缩,位翻转(Bit Flip)概率显著增加。ECC 引擎在写入数据时计算校验码(Parity),读取时验证。
- 能力: 常见的 BCH 或 LDPC 算法,每 1KB 数据可纠正 40-70 bit 错误。如果错误位超过纠错能力,则会报告不可纠正错误(Uncorrectable Error)。
- Wear Leveling (磨损均衡):
- 目的: NAND Flash 的每个物理块(Block)擦写寿命(P/E Cycle)有限(TLC 约 1000-3000 次)。
- 静态均衡: 将长期不修改的“冷数据”(如系统文件)搬运到磨损较多的块,让磨损较少的块去承载“热数据”的频繁擦写,确保全盘寿命一致。
- 动态均衡: 仅在写入新数据时选择磨损最少的空闲块。
- Bad Block Management (坏块管理):
- 出厂坏块 (IBB): 生产过程中产生的坏块,由厂家标记在坏块表(BBT)中,控制器会自动跳过。
- 新增坏块 (GBB): 使用过程中因磨损或应力产生的坏块。当擦除或编程失败时,控制器会将该块标记为坏块,并将数据迁移到**保留区(Reserved Area)**的备用块中。
- FTL (Flash Translation Layer): 维护逻辑地址(LBA)到物理地址(PBA)的映射表,这是实现上述功能的基石。
- ECC (Error Correction Code) 纠错引擎:
1.4 坏块增加的后果:容量减少还是数据丢失?
这是一个常见的误区,实际上 eMMC 设计了多重防线:
-
第一阶段(正常老化):
- eMMC 内部预留了约 5%-10% 的冗余容量(Over-Provisioning, OP)。
- 当出现新增坏块时,控制器会用 OP 区的备用块进行透明替换(Remap)。
- 用户感知:可用容量不变,数据完整性不受影响。用户看到的逻辑空间(如 32GB)始终是完整的。
-
第二阶段(寿命末期):
- 当 OP 区的备用块全部耗尽,再出现新坏块时,控制器将无法进行替换。
- 此时 eMMC 通常会进入 “只读模式” (Write Protect) 以保护现有数据不被破坏。
- 用户感知:系统变卡顿,最终无法写入新数据,甚至无法启动系统。
-
数据丢失风险:
- 如果坏块发生在数据写入的瞬间,且 ECC 无法纠正,那么该笔数据会丢失。
- 但 eMMC 控制器会尽量在读取时发现位翻转率过高的块,并提前进行数据搬运(Read Reclaim),防患于未然。
1.2 协议与总线模式
eMMC 遵循 JEDEC 标准(如 eMMC 5.0/5.1)。
- CMD Line: 双向,用于传输命令和响应。
- DAT Lines: 双向,用于传输数据。
- Bus Speed Modes:
- HS200: 200MHz, SDR, Max 200MB/s (1.8V)
- HS400: 200MHz, DDR, Max 400MB/s (1.8V)
1.3 分区管理 (Partitioning)
eMMC 不同于普通的 SD 卡,它在物理层面上划分了多个独立的逻辑分区。

- Boot Area Partitions (Boot1 / Boot2):
- 通常各 4MB。
- 用于存放 Bootloader(如 SPL/U-Boot)。
- SoC 上电后会自动从这里读取代码(无需软件驱动介入)。
- RPMB (Replay Protected Memory Block):
- 用于存放安全敏感数据(如指纹密钥、DRM 证书)。
- 访问需要鉴权(HMAC SHA-256),防止重放攻击。
- User Data Area (UDA):
- 最大的分区,存放操作系统(Kernel, Rootfs)和用户数据。
- 可以进一步被软件(如 GPT/MBR)划分为逻辑分区。
2. Linux 平台实现
Linux 内核通过 MMC 子系统(MMC Subsystem)来管理 eMMC 设备。
2.1 驱动架构

- MMC Card Driver (
drivers/mmc/core/):- 协议层。实现 eMMC 协议规范(CMD 发送、状态机维护)。
- 负责设备探测、初始化、分区识别。
- 创建块设备节点(如
/dev/mmcblk0)。
- MMC Host Driver (
drivers/mmc/host/):- 平台驱动层。适配具体的 SoC MMC 控制器(如 DesignWare mshc, SDHCI)。
- 操作硬件寄存器,控制 DMA 和中断。
2.2 设备节点命名规则
在 Linux 中,eMMC 设备通常映射为:
/dev/mmcblk0: User Data Area (UDA)/dev/mmcblk0p1: UDA 中的第 1 个逻辑分区/dev/mmcblk0p2: UDA 中的第 2 个逻辑分区
/dev/mmcblk0boot0: Boot Partition 1/dev/mmcblk0boot1: Boot Partition 2/dev/mmcblk0rpmb: RPMB Partition
2.3 初始化流程
- Power On: 驱动设置 VCC/VCCQ 电压。
- CMD0 (GO_IDLE_STATE): 复位设备。
- CMD1 (SEND_OP_COND): 询问 OCR 寄存器(电压支持)。
- CMD2 (ALL_SEND_CID): 获取 CID(Card ID,包含厂家信息)。
- CMD3 (SET_RELATIVE_ADDR): 分配 RCA 地址。
- CMD8 (SEND_EXT_CSD): 读取 Extended CSD 寄存器(获取容量、版本、分区配置)。
- Select Partition: 默认选中 User Data Area。
3. 实战操作与调优
3.1 使用 mmc-utils
mmc-utils 是管理 eMMC 的用户空间神器。
# 查看 EXT_CSD 寄存器信息
mmc extcsd read /dev/mmcblk0
# 查看 eMMC 寿命 (Life Time Estimation)
# 0x01: 0-10% used, 0x02: 10-20% used...
mmc extcsd read /dev/mmcblk0 | grep LIFE_TIME_EST
# 开启 Enhanced User Area (SLC Mode)
# 注意:这是一次性操作,不可逆!
mmc enh_area set -y <start_kbyte> <length_kbyte> /dev/mmcblk0
3.2 切换 Boot 分区
在刷机时,需要启用对应的 Boot 分区让 ROM Code 读取。
# 设置 Boot Partition 1 为启用状态
# boot_partition=1, access_partition=1
mmc bootpart enable 1 1 /dev/mmcblk0
3.3 性能调优
- 开启 HS200/HS400 模式:
- 检查 Device Tree (
.dts) 配置。 - 确保
bus-width = <8>;。 - 确保
cap-mmc-highspeed;或mmc-hs200-1_8v;已设置。
- 检查 Device Tree (
- I/O 调度器:
- 对于 eMMC(Flash 介质),推荐使用
deadline或mq-deadline,甚至noop。 echo deadline > /sys/block/mmcblk0/queue/scheduler
- 对于 eMMC(Flash 介质),推荐使用
- CQE (Command Queueing Engine):
- eMMC 5.1 引入。允许主机发送多个读写命令到队列中,由 eMMC 内部优化执行顺序。
- 需 Host 和 Device 同时支持。内核配置
CONFIG_MMC_CQHCI。
4. 参考文献
- JEDEC Standard No. 84-B51 (eMMC 5.1 Specification).
- Linux Kernel Documentation:
Documentation/mmc/. - mmc-utils Source Code:
https://git.kernel.org/pub/scm/utils/mmc/mmc-utils.git.
更多推荐
所有评论(0)