当前位置: 首页 > article >正文

eMMC存储器详解(存储区域结构、EXT_CSD[179]、各分区介绍、主要引脚、命令格式与类型等)

读本篇博文所需要的先行知识

关于芯片内部的ROM的作用、工作原理的介绍,链接如下:
https://blog.csdn.net/wenhao_ir/article/details/145969584

eMMC的物理结构、特点、用途

这个标题的相关内容见我的另一篇博文,博文链接如下:
https://blog.csdn.net/wenhao_ir/article/details/145367399

eMMC设备的存储区域结构

eMMC(Embedded MultiMediaCard)是一种嵌入式存储设备,符合JEDEC(Joint Electron Device Engineering Council)标准,广泛用于嵌入式系统,如智能手机、单板计算机和工业设备。eMMC的存储区域结构主要包括以下部分:


1. Boot Partition(引导分区)

  • 作用:用于存储引导加载程序(如U-Boot),系统启动时可以直接从该区域加载引导代码。
  • 特点
    • eMMC通常提供两个Boot分区Boot Partition 1Boot Partition 2)。这两个Boot分区在Fastboot(FB)协议中通常被命令名为boot0和boot1,并分别编号为1和2。关于Fastboot(FB)协议的详细介绍,请见博文 https://blog.csdn.net/wenhao_ir/article/details/145985144
    • 每个Boot分区的大小通常是固定的(如128KB、512KB或4MB,取决于eMMC规格)。
    • 可以通过EXT_CSD[179] BOOT_CONFIG配置哪个Boot分区用于启动。关于EXT_CSD[179] BOOT_CONFIG的详细介绍见本博文后面。
    • 只能通过特殊方式(如u-boot中的eMMC命令mmc bootpart enable或 Linux 系统下的命令dd if=uboot.img of=/dev/mmcblkXboot0)写入。
    • 不能用于普通数据存储。

2. RPMB(Replay Protected Memory Block,防重放保护存储区)

  • 作用
    • 主要用于存储安全相关数据,例如加密密钥、认证信息、防篡改数据等。
    • 具有防重放保护机制,可防止存储数据的回滚攻击。防重放保护通常是指防止攻击者通过回滚存储器内容,恢复到较早的状态,从而绕过安全检查或重现旧的、可能已被撤销的凭据。
  • 特点
    • 只能通过安全认证的方式访问,不能像普通块设备一样读写。
    • 通常容量较小,例如512KB或更大。
    • 不能直接挂载或用于普通存储。

3. General Purpose Partitions(通用分区)

  • 作用
    • 额外的可由用户定义的分区,可用于存储操作系统、应用程序或其他数据。
  • 特点
    • eMMC允许创建最多4个通用分区。
    • 大小可配置,但一旦分配就不能动态调整。
    • 适用于某些特殊用途,例如存放文件系统、日志或者特定数据。

4. User Data Area(用户数据区域)

  • 作用
    • 主要存储操作系统、根文件系统、用户数据等。
  • 特点
    • 这个区域是eMMC中容量最大的部分,相当于普通SD卡的存储空间。
    • 可以划分多个逻辑分区(如ext4、FAT等)。
    • 直接映射为Linux设备,例如 /dev/mmcblkX(裸设备)或 /dev/mmcblkXpY(分区)。
    • 采用可磨损均衡(Wear Leveling)坏块管理机制,以提高eMMC的寿命和稳定性。

5. Enhanced User Data Area(增强型用户数据区)

  • 作用
    • 允许将部分User Data Area转换为SLC模式,以提升写入寿命和可靠性。
  • 特点
    • 通过配置EXT_CSD寄存器来分配。
    • 牺牲存储容量换取更高的耐久性。
    • 适用于高频写入的数据,如日志、数据库等。

6.eMMC分区示意图

下面分区示意图中提到的“FB协议”的详细介绍请参看我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145985144

+----------------------+ 0x00000000
| Boot Partition 1    |  (大小固定,如4MB)【在FB协议中被命令为boot0,编号为1】
+----------------------+
| Boot Partition 2    |  (大小固定,如4MB)【在FB协议中被命令为boot1,编号为2】
+----------------------+
| RPMB Partition      |  (大小固定,如512KB)
+----------------------+
| General Purpose 1   |  (可选)
+----------------------+
| General Purpose 2   |  (可选)
+----------------------+
| General Purpose 3   |  (可选)
+----------------------+
| General Purpose 4   |  (可选)
+----------------------+
| User Data Area      |  (最大存储区域)【在FB协议中被命令为 userdata 或 mmcblk0,编号为0】
+----------------------+ 0xFFFFFFFF

上面这个分区示意图中eMMC的相关分区在FB(Fastboot)协议中的名称和编号再附一张表:

eMMC 分区Fastboot 分区名称编号 (mmc partconf)
Boot Partition 1boot01
Boot Partition 2boot12
User Data Area(主存储区)userdatammcblk00

eMMC通常存储容量有多大?我开发析上的eMMC容易有多大?

从上面的分区示意图可以看出,其寻址空间为0x00000000~0xFFFFFFFF,一共有8个F,即32位,32位刚好对应的是4GB,所以eMMC通常的存储容量是4GB大小。我的开发板也正是4GB大小的eMMC,如下图所示:
在这里插入图片描述
在核心版的原理图中(文件MYC-Y6ULX1211.pdf)中搜索“eMMC”得到如下结果:
在这里插入图片描述
然后查看板子的丝印文件(100ask_imx6ull_PRO_V11_silktop(丝印图).pdf):
在这里插入图片描述
所在eMMC芯片在硬件实物中的位置如下图所示:
在这里插入图片描述


7. Linux系统中将eMMC的各区域分别映射为什么名称的设备文件?

在Linux系统中,eMMC的不同区域通常会映射成不同的设备节点:

eMMC区域设备节点示例说明
Boot Partition 1/dev/mmcblk0boot0引导分区 1
Boot Partition 2/dev/mmcblk0boot1引导分区 2
RPMB Partition/dev/mmcblk0rpmb认证存储区(受保护)
User Data Area/dev/mmcblk0用户数据区(整个eMMC)
分区1(如rootfs)/dev/mmcblk0p1用户数据区的一个分区
分区2(如/data)/dev/mmcblk0p2用户数据区的另一个分区

如何查看Linux系统的eMMC的分区信息(设备节点信息)

可以使用以下命令查看eMMC的分区信息:

lsblk
cat /proc/partitions
ls /dev/mmcblk*
fdisk -l /dev/mmcblk*

我的开发板运行命令lsblk的结果如下:
在这里插入图片描述
我的开发板运行命令cat /proc/partitions的结果如下:
在这里插入图片描述

[root@imx6ull:~]# cat /proc/partitions
major minor  #blocks  name
.....
 179        0    3817472 mmcblk1
 179        1     512000 mmcblk1p1
 179        2    1048576 mmcblk1p2
 179        3      10240 mmcblk1p3
 179       24       4096 mmcblk1rpmb
 179       16       4096 mmcblk1boot1
 179        8       4096 mmcblk1boot0

从运行结果来看,用户数据区(User Data Area )的设备节点名为mmcblk1,它被划分成了三个逻辑分区,分别为mmcblk1p1mmcblk1p2mmcblk1p3,容量大小情况如下:
mmcblk1:3817472KB = 3728MB ≈ 3.6GB
mmcblk1p1:512000KB = 500MB ≈ 0.48GB
mmcblk1p2:1048576KB = 1024MB ≈ 1 GB
mmcblk1p3:10240KB = 10MB
可见,第2分区是最大的,有1个GB的大小。

命令fdisk -l /dev/mmcblk*的运行结果如下:
在这里插入图片描述
从中可以看到eMMC设备节点的详细信息,我整理一下输出信息如下:

[root@imx6ull:~]# fdisk -l /dev/mmcblk*

Disk /dev/mmcblk1boot0: 4 MB, 4194304 bytes, 8192 sectors
128 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1boot0 doesn't contain a valid partition table

Disk /dev/mmcblk1boot1: 4 MB, 4194304 bytes, 8192 sectors
128 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1boot1 doesn't contain a valid partition table

Disk /dev/mmcblk1: 3728 MB, 3909091328 bytes, 7634944 sectors
119296 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device       Boot StartCHS    EndCHS        StartLBA     EndLBA    Sectors  Size Id Type
/dev/mmcblk1p1 *  0,65,4      63,254,1          4098    1028097    1024000  500M 83 Linux
/dev/mmcblk1p2 *  63,254,2    194,137,9      1028098    3125249    2097152 1024M 83 Linux
/dev/mmcblk1p3    194,137,10  195,207,14     3125250    3145729      20480 10.0M  c Win95 FAT32 (LBA)

Disk /dev/mmcblk1p1: 500 MB, 524288000 bytes, 1024000 sectors
16000 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1p1 doesn't contain a valid partition table

Disk /dev/mmcblk1p2: 1024 MB, 1073741824 bytes, 2097152 sectors
32768 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1p2 doesn't contain a valid partition table

Disk /dev/mmcblk1p3: 10 MB, 10485760 bytes, 20480 sectors
320 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1p3 doesn't contain a valid partition table

fdisk: can't open '/dev/mmcblk1rpmb': Input/output error

上面输出信息中mmcblk1p1mmcblk1p2在Boot项上有个*代表这两个分区是可引导的,但在ARM 嵌入式系统这个信息不重要,原因是i.MX6ULL 内部的 ROM中的 代码可以直接从 eMMC 的Boot Partition (比如mmcblk1boot1) 中加载 U-Boot,无需从用户数据区去加载引导程序(u-boot)。这里的* 号只是一个标志,表示该分区被设定为可引导,但不一定真正参与系统启动。


eMMC的EXT_CSD[179] BOOT_CONFIG是什么东西?

名字来源

EXT_CSD这个名字的来源是Extended CSDCSDCard-Specific Data的缩写,直译为“卡指定数据”,即为为设置存储卡指定的数据,实际上就是存储器的寄存器。
所以我们通常说:“eMMC 设备的 EXT_CSD寄存器。”

eMMC 设备的 EXT_CSD寄存器是一个 512 字节大小的寄存器空间,用于存储 eMMC 设备的各种扩展配置参数。EXT_CSD[179] 表示 EXT_CSD 寄存器的第 179 个字节(从 0 开始计算)。在 eMMC 规格中,EXT_CSD[179] 这个字节被定义为 BOOT_CONFIG(引导配置),所以出现了标题中的EXT_CSD[179] BOOT_CONFIG这个名字。

EXT_CSD[179](BOOT_CONFIG)寄存器解析

EXT_CSD[179](BOOT_CONFIG)寄存器解析如下:

EXT_CSD[179] 主要用于设置 eMMC 的引导相关配置,包括:

  • 选择哪个 Boot 分区作为默认启动分区。
  • 是否启用 Boot 访问模式。
  • 是否启用高速度模式(HS_TIMING)。

BOOT_CONFIG(EXT_CSD[179])的位定义:

位范围名称说明
7BOOT_ACK是否在 Boot 过程中启用 BOOT_ACK 响应(0: 关闭,1: 使能)。【关于什么叫 BOOT_ACK 响应,请往后面看】
6:5BOOT_PARTITION_ENABLE选择哪个 Boot 分区用于启动:
00b - 用户分区
01b - Boot 分区1
10b - Boot 分区2
11b - 保留
4:3BOOT_PARTITION_ACCESS选择当前访问的 Boot 分区(仅在 BOOT_MODE 访问时生效):
00b - 用户分区
01b - Boot 分区1
10b - Boot 分区2
11b - 保留
2:0BOOT_MODEBoot 访问模式选择:
000b - 普通数据模式
001b - 强制 Boot
010b - 备用 Boot
011b - 用户区 Boot
100b - 关机后 Boot
其他 - 保留

BOOT_CONFIG 的常见配置:
如果你希望 eMMC 在上电后自动从 Boot 分区 1 启动,并启用 BOOT_ACK,可以设置:

EXT_CSD[179] = 0x48  // 0b01001000

解释:

  • BOOT_ACK = 1(启用 Boot ACK)
  • BOOT_PARTITION_ENABLE = 01(Boot 分区 1)
  • BOOT_PARTITION_ACCESS = 00(无 Boot 访问)
  • BOOT_MODE = 000(普通数据模式)

如何修改 EXT_CSD[179]
在 u-boot中,可以使用 mmc 工具进行查看和修改:

读取 EXT_CSD 信息
mmc extcsd read /dev/mmcblk0

修改 Boot 分区配置(例如设置为 Boot 分区1)
mmc bootpart enable 1 1 /dev/mmcblk0

如果你是用 mmc 设备直接操作,可以通过 mmc cmd6 命令修改 EXT_CSD[179]

什么叫eMMC的 BOOT_ACK 响应?

BOOT_ACK(Boot Acknowledge,启动确认)是 eMMC 在 Boot 过程中提供的一个特殊的确认信号,用于指示 eMMC 设备已进入 Boot 模式,并准备好传输 Boot 数据了。

在 eMMC 设备的 EXT_CSD[179](BOOT_CONFIG)寄存器的 第 7 位(bit7) 控制是否启用 BOOT_ACK 机制:

  • BOOT_ACK = 0(默认) → 设备在 Boot 过程中不会发送 ACK 响应,主机必须自己确定 eMMC 是否进入了 Boot 模式。
  • BOOT_ACK = 1 → eMMC 在 Boot 过程开始时会发送一个 ACK 响应,通知主机 Boot 过程已启动。

BOOT_ACK 作用

  1. 确保 eMMC 进入 Boot 模式

    • BOOT_ACK 使能的情况下,主机(比如 BootROM 或 Bootloader)可以通过检测 ACK 确保 eMMC 正确进入 Boot 模式。
  2. 提高 Boot 稳定性

    • 某些平台在上电初始化时,需要确保 eMMC 设备正确响应 Boot 过程,否则可能会进入错误状态。
  3. 防止误读取数据

    • BOOT_ACK 使能后,主机不会误将未准备好的数据当作 Boot 数据读取。

eMMC BOOT_ACK 过程

  1. 主机复位并发送 Boot 启动命令

    • 发送 CMD0(GO_IDLE_STATE)并选择 Boot 模式。【关于 CMD0是怎么回事?请看本篇博文后面内容(搜索“eMMC的命令详解”和“关于 eMMC的CMD0命令选择Boot 模式的工作流程的详解”)。】
  2. eMMC 响应 BOOT_ACK(如果启用)

    • 设备进入 Boot 状态后,会返回 ACK,通知主机已准备好发送 Boot 数据。
  3. 主机开始接收 Boot 数据

    • 设备按照 Boot 配置传输 Boot 分区数据(通常是 BOOT_PARTITION_1BOOT_PARTITION_2)。

在Linux系统下,如何读取EXT_CSD[179]的配置值?

在 Linux 设备中,可以查看 eMMC 的EXT_CSD[179]的配置值,用下面的命令即可:

mmc extcsd read /dev/mmcblk0 | grep BOOT_CONFIG

你应该会看到 EXT_CSD[179] 配置,例如:

BOOT_CONFIG = 0x48

其中:

  • 0x48 = 0b01001000
    • BOOT_ACK = 1(使能 Boot ACK)
    • BOOT_PARTITION_ENABLE = 01(Boot 分区 1)
    • BOOT_PARTITION_ACCESS = 00(无手动访问)

之前已经确认(搜索“ 如何查看Linux系统的eMMC的分区信息(设备节点信息)”),我的开发板的eMMC的设备节点名为mmcblk1,所以对于我的开发板,需要运行下面的命令:

mmc extcsd read /dev/mmcblk1 | grep BOOT_CONFIG

但运行结果如下:
在这里插入图片描述
这说明在读取/dev/mmcblk1的配置信息中,只搜索到一句话含有BOOT_CONFIG这个关键词,这句话如下:

Boot config protection [BOOT_CONFIG_PROT: 0x00]
  • BOOT_CONFIG_PROT 是 Boot 配置保护的寄存器,用于 保护 eMMC Boot 分区配置,防止意外修改。
  • 0x00 说明 Boot 配置保护未启用,你仍然可以修改 eMMC 的 Boot 分区配置。

也就是说没有出现我们期望的信息,看来如何在Linux系统中获取EXT_CSD[179]的配置值,还需要进一步研究, 但这个问题并不是本篇博文的重点,所以暂且把这个问题放在一边。


eMMC的哪些分区是不可调整的?哪些是可以调整的?

问:eMMC的存储区域是出厂时就划分好的,还是后来根据需要用工具或命令划分的?

答:

1. 出厂默认划分的区域

在 eMMC 出厂时,制造商已经预先划分了以下区域:

eMMC 区域出厂时状态
Boot Partition 1预设大小(如 4MB),无法调整
Boot Partition 2预设大小(如 4MB),无法调整
RPMB Partition预设大小(如 512KB),无法调整
User Data Area整个剩余容量,可以重新分区
General Purpose Partitions(通用分区)默认不存在,需要手动创建

2. 后续可手动调整的部分

虽然 Boot 分区和 RPMB 分区的大小是固定的,但用户可以使用工具或命令进行如下调整:

  1. 划分用户数据区(User Data Area) → 用 fdiskparted 等工具创建文件系统分区,如 /dev/mmcblk0p1(rootfs)、/dev/mmcblk0p2(data)。
  2. 创建通用分区(General Purpose Partitions) → 通过修改 eMMC 的 EXT_CSD 寄存器,将一部分用户数据区转换为通用分区。
  3. 转换部分用户数据区为增强型存储(Enhanced User Data Area, SLC模式) → 提升可靠性,但会减少容量。

eMMC的主要引脚功能介绍

eMMC(嵌入式多媒体卡)采用 BGA 封装,不同版本的 eMMC 可能有不同的引脚定义。一般来说,eMMC 主要使用 11 个信号引脚,支持 1-bit、4-bit 和 8-bit 数据总线模式。


1. eMMC 主要引脚功能

eMMC 采用 BGA-153、BGA-169 或 BGA-100 封装,以下是常见的引脚定义:

引脚名称引脚编号描述
VCC供电引脚核心电源(通常为 3.3V)
VCCQ供电引脚I/O 电源(1.8V 或 3.3V,根据工作模式)
VSS / GND供电引脚地线
CLK(Clock)时钟信号由主机提供时钟(最大 200MHz,HS400 模式下可达 400MHz)
CMD(Command)命令信号双向信号,用于主机和 eMMC 之间传输命令和响应
DAT0-DAT7(Data)数据线支持 1-bit(DAT0)、4-bit(DAT0-DAT3)、8-bit(DAT0~DAT7) 模式
RST_n(Reset)复位信号可选,用于硬件复位
DS(Data Strobe)仅在 HS400 模式下使用提高数据同步精度
NC(Not Connected)-保留未使用的引脚

2. 详细引脚说明

(1)电源相关

  • VCC(核心电源):通常为 3.3V,部分低功耗 eMMC 可能支持 1.8V
  • VCCQ(I/O 电源)
    • 3.3V(常见于旧版 eMMC 4.3 及以下)
    • 1.8V(eMMC 4.5 及以上,低功耗模式)
  • VSS(GND):地线,必须连接到电源地。

(2)控制信号

  • CLK(时钟信号)
    • 由主机提供,用于同步数据传输。
    • 默认频率 0~26MHz,高速模式可达 52MHz,HS200/HS400 模式下可达 200MHz/400MHz
  • CMD(命令信号)
    • 由主机发送 eMMC 命令,eMMC 也可在该引脚上返回响应(双向)。
    • 逻辑上属于 开漏/推挽驱动
  • RST_n(复位信号,可选
    • 低电平复位 eMMC,部分 eMMC 可能不支持该引脚。

(3)数据传输

  • DAT0~DAT7(数据线)
    • DAT0:用于 1-bit 模式。
    • DAT0-DAT3:用于 4-bit 模式。
    • DAT0-DAT7:用于 8-bit 模式(通常用于 eMMC)。
    • 具有 内部上拉,在 空闲状态 下维持高电平。
  • DS(数据选通信号,HS400 模式专用)
    • 仅在 HS400 模式 下使用。
    • 作用:主机用于数据同步。

3. eMMC 数据模式

模式使用的引脚速率
1-bit 模式CLK、CMD、DAT0低速
4-bit 模式CLK、CMD、DAT0-DAT3中速
8-bit 模式CLK、CMD、DAT0-DAT7高速(推荐)

Linux/嵌入式系统中,eMMC 通常采用 8-bit 模式,以提高读写效率。


4. BGA-153 引脚排列示意图

典型的 BGA-153(11x11)封装 引脚示意:

   ____________________________
  |                            |
  |  DAT7  DAT6  DAT5  DAT4    |  ← 数据线
  |  VSS   VCCQ  CMD   CLK     |  ← 控制 & 电源
  |  DAT3  DAT2  DAT1  DAT0    |  ← 数据线
  |____________________________|

不同封装(BGA-100、BGA-153、BGA-169)的引脚排列可能有所不同,但信号功能基本相同。

5.关于eMMC没有地址线的说明(eMMC如何进行寻址)

1. eMMC 为何没有地址线?

在传统的并行存储器(如 NOR Flash、SRAM)中,CPU 需要使用 地址线(Address Bus) 选择存储单元,用 数据线(Data Bus) 进行读写。但 eMMC 采用 MMC(MultiMediaCard)协议,使用 CMD 命令接口 进行数据寻址,并通过 数据线(DAT0-DAT7) 传输数据,因此 不需要单独的地址线


2. eMMC 的寻址方式

eMMC 的寻址是基于 逻辑块地址(LBA, Logical Block Addressing),类似于硬盘(SD 卡也是同样的方式)。访问数据时:

  1. CPU 通过 CMD 发送读/写命令,指定要访问的 LBA 地址
  2. eMMC 内部的 Flash 控制器 解析 LBA 地址,将其映射到 NAND Flash 物理地址。
  3. 数据通过 DAT 线传输,并由 eMMC 内部管理 ECC、磨损均衡等。

Linux 访问 eMMC 时,通常把它当作块设备 /dev/mmcblk0,通过 ddfdisk 等工具进行分区和访问,而不是像 SRAM 那样直接使用地址线访问


eMMC的命令详解

eMMC(嵌入式多媒体卡)遵循 MMC(MultiMediaCard)协议,使用一套标准的 命令格式(Command Format) 来与主机(如处理器或控制器)进行通信。eMMC 的命令分为多种类型,并采用 48-bit 或 136-bit 的格式

1. eMMC 命令格式

eMMC 命令的基本格式如下:

名称说明
47起始位(Start Bit)固定为 0
46传输方向(Transmission Bit)1 表示主机到设备,0 表示设备到主机
45:40命令索引(Command Index)6-bit 命令编号,如 CMD0000000
39:8参数(Argument)32-bit 参数,具体值因命令而异
7:1CRC 校验(CRC7)7-bit 循环冗余校验
0结束位(End Bit)固定为 1

注意

  • 该格式适用于 所有 48-bit 命令(最常见)。
  • CMD2 例外,它使用 136-bit 长响应,返回 CID 号(卡片标识)。

2. eMMC 命令类型

(1)基本命令

命令名称描述
CMD0GO_IDLE_STATE使 eMMC 进入空闲状态
CMD1SEND_OP_COND发送 OCR(操作条件寄存器),检查 eMMC 是否准备好
CMD2ALL_SEND_CID发送 eMMC 的唯一 ID 号
CMD3SET_RELATIVE_ADDR设置 eMMC 的 RCA(相对地址)
CMD6SWITCH切换 eMMC 的模式(如改变工作电压)
CMD7SELECT/DESELECT_CARD选中或取消选中某张 eMMC 卡

(2)读/写命令

命令名称描述
CMD8SEND_EXT_CSD读取 eMMC EXT_CSD(扩展寄存器)
CMD9SEND_CSD读取 eMMC CSD(卡片特性描述符)
CMD16SET_BLOCKLEN设置读写块大小
CMD17READ_SINGLE_BLOCK读取单个块
CMD18READ_MULTIPLE_BLOCK读取多个块
CMD24WRITE_BLOCK写入单个块
CMD25WRITE_MULTIPLE_BLOCK写入多个块

(3)数据传输命令

命令名称描述
CMD12STOP_TRANSMISSION停止多块传输
CMD13SEND_STATUS查询 eMMC 的状态
CMD23SET_BLOCK_COUNT预设多块传输的块数

3. eMMC 响应格式

eMMC 响应有 6 种类型:

  1. R1(正常响应):包含 eMMC 状态
  2. R2(CID/CSD 响应):136-bit 长响应
  3. R3(OCR 响应):包含操作条件寄存器
  4. R4(不常用)
  5. R5(不常用)
  6. R6(RCA 响应)

例如:

  • CMD2 返回 R2 响应(136-bit)
  • CMD1 返回 R3 响应(48-bit)
  • CMD13 返回 R1 响应(48-bit)

4. 数据传输格式

eMMC 读写数据时,数据通过 单线(1-bit)、4-bit 或 8-bit 模式 进行传输,通常格式如下:

  • 起始位
  • 数据块
  • CRC 校验
  • 停止位

eMMC 允许 单块或多块传输,多块传输可以提高读写效率。


5.小结

  • eMMC 采用 48-bit 标准命令格式,有 Start BitCommand IndexArgumentCRC7End Bit
  • 命令分为 初始化命令、数据传输命令、控制命令
  • 不同命令返回 不同格式的响应(R1、R2、R3等)
  • 数据传输支持 单块/多块模式,使用 CMD17/18 进行读取,CMD24/25 进行写入。

关于 eMMC的CMD0命令选择Boot 模式的工作流程的详解

上面一个目录已经详细介绍了eMMC的命令的相关知识,在此基础上,我们再来了解下CMD0命令对Boot模式的选择。

在 eMMC 设备的 Boot 过程 中,主机(Host,例如 CPU 或 BootROM)需要 复位 eMMC 并使其进入 Boot 模式,这个过程通常通过 CMD0(GO_IDLE_STATE)实现。


1. CMD0(GO_IDLE_STATE)命令的作用

CMD0 是 eMMC 规范中的一个标准命令,其作用是:

  • 让 eMMC 进入空闲(Idle)状态,类似于软复位(Software Reset)。
  • 可以附带参数来指定 eMMC 的 启动模式(Boot Mode)

在正常的数据模式下,CMD0 的参数通常是 0x00000000,表示让 eMMC 进入 Idle State(空闲状态)
但在 Boot 过程中CMD0 可以使用特定参数,使 eMMC 进入 Boot 模式 并准备传输 Boot 数据。


2. CMD0 选择 Boot 模式的参数

当系统启动时,BootROM 或 Bootloader 需要告诉 eMMC 进入 Boot 模式。
这通常通过 CMD0 命令 带上特定参数 来完成。

CMD0 参数值含义
0x00000000进入 空闲状态(Idle State),用于普通复位
0xFFFFFFFA进入 Boot 操作模式(Boot Operation Mode)
0xFFFFFFF1进入 备用 Boot 模式(Alternative Boot Mode)

其中,0xFFFFFFFA最常用的,因为它会让 eMMC 从 BOOT_PARTITION_ENABLE 指定的 Boot 分区启动。【 BOOT_PARTITION_ENABLE 是在EXT_CSD[179]中配置的,EXT_CSD[179]在前文已有详细介绍。】


3. 使用CMD0 进入 Boot 模式并启动u-boot的完整流程

步骤 1:上电并初始化 eMMC

  • 处理器上电后,eMMC 仍然处于 Inactive State(未激活状态),不会立即工作。
  • 处理器需要复位 eMMC,并配置 Boot 模式。

步骤 2:发送 CMD0 0xFFFFFFFA 进入 Boot 模式

  • BootROM 发送:
    CMD0 (0xFFFFFFFA)
    
  • eMMC 进入 Boot 模式,准备从 Boot 分区传输数据。

步骤 3:eMMC 发送 BOOT_ACK(可选)
如果 BOOT_ACK(EXT_CSD[179] Bit7)被启用:

  • eMMC 会发送一个 ACK 响应,通知主机已准备好发送 Boot 数据。

步骤 4:eMMC 传输 Boot 数据

  • eMMC 进入 Boot 传输模式,并从 EXT_CSD[179](BOOT_CONFIG)指定的 Boot 分区(BOOT_PARTITION_1BOOT_PARTITION_2发送 Boot 代码(通常是 Bootloader)。
  • 这个传输过程是 单向的,eMMC 只负责发送,主机通过 低速模式(默认 26MHz) 读取 Boot 数据。

步骤 5:主机加载 Boot 代码

  • BootROM 读取 eMMC 传输的 Boot 数据(如 u-boot)。
  • 如果数据有效,BootROM 跳转到 Boot 代码,继续启动操作系统。

常用的eMMC配置修改工具有哪些?

① u-boot可以修改eMMC的配置。
② Linux系统也可以修改eMMC的配置。
③ 注意:百问网基于NXP提供的uuu工具搞出的烧写工具在进行烧写准备前也可能去修改eMMC的配置。百问网提供的烧写工具的详细介绍见 https://blog.csdn.net/wenhao_ir/article/details/145653414 其实这个烧写工具本质上也是使用的u-boot,详情见 https://blog.csdn.net/wenhao_ir/article/details/145985144

Linux系统中如何管理eMMC分区

查看eMMC信息

cat /sys/class/mmc_host/mmc0/mmc0:0001/ext_csd

对于我的开发板而言,mmc的序号值为1,但是下面这个目录:

/sys/class/mmc_host/mmc1/mmc1:0001

中,只有csd文件,没有ext_csd文件,如下图所示:
在这里插入图片描述
可见,如需在Linux下查看我的开发板的eMMC的ext_csd信息,还需要作进一步研究,这并不是本篇博文的重点,所以暂且不作进一步研究。

访问Boot分区

# 读取Boot分区
dd if=/dev/mmcblk0boot0 of=boot.img bs=1M

# 写入Boot分区(需启用写入)
echo 0 > /sys/block/mmcblk0boot0/force_ro
dd if=u-boot.img of=/dev/mmcblk0boot0 bs=1M

格式化User Data分区

mkfs.ext4 /dev/mmcblk0p1

如何查看eMMC的分区信息(设备节点信息)

请在本博文中搜索关键词“以下命令查看eMMC的分区信息”查看相关内容。

在Linux系统下,如何读取EXT_CSD[179]的配置值?

详情请搜索在本篇博文中搜索关键词:“在Linux系统下,如何读取EXT_CSD[179]的配置值”

扩展阅读

Fastboot(FB)协议介绍

https://blog.csdn.net/wenhao_ir/article/details/145985144

百问网在uuu工具的基础上开发出的烧写工具的介绍

https://blog.csdn.net/wenhao_ir/article/details/145653414

Bootloader的三个阶段详解(BootROM、SPL、U-Boot)

https://blog.csdn.net/wenhao_ir/article/details/145999721

SPL和U-Boot合成镜像u-boot-dtb.imx时需要作填充数据处理

https://blog.csdn.net/wenhao_ir/article/details/145999721


http://www.kler.cn/a/570000.html

相关文章:

  • 百度权重有什么用?如何查看百度权重?
  • 在Vscode开发QT,完成QT环境的配置
  • SQLyog 13.1.6 社区免费中文版:高效便捷的MySQL管理工具
  • 从黑暗到光明:FPC让盲人辅助眼镜成为视障者的生活明灯!【新立电子】
  • 【愚公系列】《Python网络爬虫从入门到精通》038-SQLite数据库
  • 8.路由原理专题
  • 命名管道——进程间通信
  • npm 常用命令指南
  • 校园二手交易微信小程序的设计与实现(论文源码调试讲解)
  • CentOS 7 中安装 Docker和Docker Compose
  • 什么是分布式和微服务?
  • NodeJS服务器 + Vue3框架 从搭建服务器 定义接口 到请求数据页面展示
  • Java里的ArrayList和LinkedList有什么区别?
  • 开放鸿蒙OpenHarmony 5.0.0 Release 兼容性测试实战经验分享
  • 爬虫部署:使用docker部署爬虫详解案例
  • 华为:Wireshark的OSPF抓包分析过程
  • 2. Prometheus的Exporter
  • 【STM32H743IIT6】将外部SDRAM作为内部SRAM使用的方法及需要解决的问题
  • 小米和华为的需求管理及产品策划
  • Linux下安装VS Code