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 1
和Boot 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
)写入。 - 不能用于普通数据存储。
- eMMC通常提供两个Boot分区(
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 1 | boot0 | 1 |
Boot Partition 2 | boot1 | 2 |
User Data Area(主存储区) | userdata 或 mmcblk0 | 0 |
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 mmcblk1179 1 512000 mmcblk1p1179 2 1048576 mmcblk1p2179 3 10240 mmcblk1p3179 24 4096 mmcblk1rpmb179 16 4096 mmcblk1boot1179 8 4096 mmcblk1boot0
从运行结果来看,用户数据区(User Data Area )的设备节点名为mmcblk1
,它被划分成了三个逻辑分区,分别为mmcblk1p1
、mmcblk1p2
、mmcblk1p3
,容量大小情况如下:
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 tableDisk /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 tableDisk /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 tableDisk /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 tableDisk /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 tablefdisk: can't open '/dev/mmcblk1rpmb': Input/output error
上面输出信息中mmcblk1p1
和mmcblk1p2
在Boot项上有个*
代表这两个分区是可引导的,但在ARM 嵌入式系统这个信息不重要,原因是i.MX6ULL 内部的 ROM中的 代码可以直接从 eMMC 的Boot Partition (比如mmcblk1boot1) 中加载 U-Boot,无需从用户数据区去加载引导程序(u-boot)。这里的*
号只是一个标志,表示该分区被设定为可引导,但不一定真正参与系统启动。
eMMC的EXT_CSD[179] BOOT_CONFIG
是什么东西?
名字来源
EXT_CSD
这个名字的来源是Extended CSD
。CSD
是Card-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])的位定义:
位范围 | 名称 | 说明 |
---|---|---|
7 | BOOT_ACK | 是否在 Boot 过程中启用 BOOT_ACK 响应(0: 关闭,1: 使能)。【关于什么叫 BOOT_ACK 响应,请往后面看】 |
6:5 | BOOT_PARTITION_ENABLE | 选择哪个 Boot 分区用于启动: 00b - 用户分区 01b - Boot 分区1 10b - Boot 分区2 11b - 保留 |
4:3 | BOOT_PARTITION_ACCESS | 选择当前访问的 Boot 分区(仅在 BOOT_MODE 访问时生效):00b - 用户分区 01b - Boot 分区1 10b - Boot 分区2 11b - 保留 |
2:0 | BOOT_MODE | Boot 访问模式选择: 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
作用
-
确保 eMMC 进入 Boot 模式
- 在
BOOT_ACK
使能的情况下,主机(比如 BootROM 或 Bootloader)可以通过检测ACK
确保 eMMC 正确进入 Boot 模式。
- 在
-
提高 Boot 稳定性
- 某些平台在上电初始化时,需要确保 eMMC 设备正确响应 Boot 过程,否则可能会进入错误状态。
-
防止误读取数据
BOOT_ACK
使能后,主机不会误将未准备好的数据当作 Boot 数据读取。
eMMC BOOT_ACK
过程
-
主机复位并发送 Boot 启动命令
- 发送
CMD0
(GO_IDLE_STATE)并选择 Boot 模式。【关于CMD0
是怎么回事?请看本篇博文后面内容(搜索“eMMC的命令详解”和“关于 eMMC的CMD0
命令选择Boot 模式的工作流程的详解”)。】
- 发送
-
eMMC 响应
BOOT_ACK
(如果启用)- 设备进入 Boot 状态后,会返回
ACK
,通知主机已准备好发送 Boot 数据。
- 设备进入 Boot 状态后,会返回
-
主机开始接收 Boot 数据
- 设备按照 Boot 配置传输 Boot 分区数据(通常是
BOOT_PARTITION_1
或BOOT_PARTITION_2
)。
- 设备按照 Boot 配置传输 Boot 分区数据(通常是
在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 分区的大小是固定的,但用户可以使用工具或命令进行如下调整:
- 划分用户数据区(User Data Area) → 用
fdisk
、parted
等工具创建文件系统分区,如/dev/mmcblk0p1
(rootfs)、/dev/mmcblk0p2
(data)。 - 创建通用分区(General Purpose Partitions) → 通过修改 eMMC 的
EXT_CSD
寄存器,将一部分用户数据区转换为通用分区。 - 转换部分用户数据区为增强型存储(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 卡也是同样的方式)。访问数据时:
- CPU 通过 CMD 发送读/写命令,指定要访问的 LBA 地址。
- eMMC 内部的 Flash 控制器 解析 LBA 地址,将其映射到 NAND Flash 物理地址。
- 数据通过 DAT 线传输,并由 eMMC 内部管理 ECC、磨损均衡等。
Linux 访问 eMMC 时,通常把它当作块设备 /dev/mmcblk0
,通过 dd
、fdisk
等工具进行分区和访问,而不是像 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 命令编号,如 CMD0 为 000000 |
39:8 | 参数(Argument) | 32-bit 参数,具体值因命令而异 |
7:1 | CRC 校验(CRC7) | 7-bit 循环冗余校验 |
0 | 结束位(End Bit) | 固定为 1 |
注意:
- 该格式适用于 所有 48-bit 命令(最常见)。
CMD2
例外,它使用 136-bit 长响应,返回CID
号(卡片标识)。
2. eMMC 命令类型
(1)基本命令
命令 | 名称 | 描述 |
---|---|---|
CMD0 | GO_IDLE_STATE | 使 eMMC 进入空闲状态 |
CMD1 | SEND_OP_COND | 发送 OCR(操作条件寄存器),检查 eMMC 是否准备好 |
CMD2 | ALL_SEND_CID | 发送 eMMC 的唯一 ID 号 |
CMD3 | SET_RELATIVE_ADDR | 设置 eMMC 的 RCA(相对地址) |
CMD6 | SWITCH | 切换 eMMC 的模式(如改变工作电压) |
CMD7 | SELECT/DESELECT_CARD | 选中或取消选中某张 eMMC 卡 |
(2)读/写命令
命令 | 名称 | 描述 |
---|---|---|
CMD8 | SEND_EXT_CSD | 读取 eMMC EXT_CSD (扩展寄存器) |
CMD9 | SEND_CSD | 读取 eMMC CSD (卡片特性描述符) |
CMD16 | SET_BLOCKLEN | 设置读写块大小 |
CMD17 | READ_SINGLE_BLOCK | 读取单个块 |
CMD18 | READ_MULTIPLE_BLOCK | 读取多个块 |
CMD24 | WRITE_BLOCK | 写入单个块 |
CMD25 | WRITE_MULTIPLE_BLOCK | 写入多个块 |
(3)数据传输命令
命令 | 名称 | 描述 |
---|---|---|
CMD12 | STOP_TRANSMISSION | 停止多块传输 |
CMD13 | SEND_STATUS | 查询 eMMC 的状态 |
CMD23 | SET_BLOCK_COUNT | 预设多块传输的块数 |
3. eMMC 响应格式
eMMC 响应有 6 种类型:
- R1(正常响应):包含 eMMC 状态
- R2(CID/CSD 响应):136-bit 长响应
- R3(OCR 响应):包含操作条件寄存器
- R4(不常用)
- R5(不常用)
- 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 Bit
、Command Index
、Argument
、CRC7
和End 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_1
或BOOT_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
相关文章:

eMMC存储器详解(存储区域结构、EXT_CSD[179]、各分区介绍、主要引脚、命令格式与类型等)
读本篇博文所需要的先行知识 关于芯片内部的ROM的作用、工作原理的介绍,链接如下: https://blog.csdn.net/wenhao_ir/article/details/145969584 eMMC的物理结构、特点、用途 这个标题的相关内容见我的另一篇博文,博文链接如下:…...
洛谷 P11830 省选联考2025 幸运数字 题解
题意 小 X 有 n n n 个正整数二元组 ( a i , b i ) ( 1 ≤ i ≤ n ) (a_i, b_i) (1 \leq i \leq n) (ai,bi)(1≤i≤n)。他将会维护初始为空的可重集 S S S,并对其进行 n n n 轮操作。第 i ( 1 ≤ i ≤ n ) i (1 \leq i \leq n) i(1≤i≤n) 轮操作中&#…...
win11编译pytorchaudio cuda128版本流程
1. 前置条件 本篇续接自 win11编译pytorch cuda128版本流程,阅读前请先参考上一篇配置环境。 访问https://kkgithub.com/pytorch/audio/archive/refs/tags/v2.6.0.tar.gz下载源码,下载后解压; 2. 编译 在visual studio 2022安装目录下查找…...

JAVA面经2
ConcurrentHashMap 并发程序出现问题的根本原因 线程池 线程池的执行原理(核心参数) 线程池的常见阻塞队列 ArrayBlockingQueue插入和删除数据,只采用了一个lock,而LinkedBlockingQueue则是在插入和删除分别采用了putLock和takeL…...

NLP学习记录十一:位置编码
目录 一、位置编码的意义 二、位置编码方法 三、代码实现 一、位置编码的意义 在标准的注意力机制中,每个查询都会关注所有的键-值对并生成一个注意力输出,模型并没有考虑到输入序列每个token的顺序关系。 以["我&qu…...

CF 886A.ACM ICPC(Java实现)
题目分析 输入6个值,判断某三个值的和能够等于另外三个值的和 思路分析 首先判断总和是不是一个偶数,如果不是就“NO”。由于小何同学算法不好,只能使用三层for循环强行判断某三个值是否能等于总和的一半,可以就“YES”。 代码 …...

【音视频】H265解码Nalu后封装rtp包
概述 基于ZLM流媒体框架以及简单RTSP服务器开源项目分析总结,相关源码参考以下链接 H265-rtp提取Nalu逻辑 通过rtsp流地址我们可以获取视频流中的多个rtp包,其中每个RTP包中又会包含一个或者多个Nalu,将其提取处理 总体逻辑分析 核心逻辑在…...

Linux -- I/O接口,文件标识符fd、file结构体、缓冲区、重定向、简单封装C文件接口
一、理解文件 狭隘理解(传统视角) 聚焦物理存储:文件特指存储在磁盘等外存设备上的二进制数据集合输入输出特性: 写入文件:CPU 通过总线将数据输出到磁盘读取文件:磁盘通过 DMA 将数据输入到内存 ÿ…...
系统讨论Qt的并发编程2——介绍一下Qt并发的一些常用的东西
目录 QThreadPool与QRunnable 互斥机制:QMutex, QMutexLocker, QSemaphore, QWaitCondition 跨线程的通信 入门QtConcurrent,Qt集成的一个并发框架 一些参考 QThreadPool与QRunnable QThreadPool自身预备了一些QThread。这样,我们就不需…...

【数据挖掘】Pandas之DataFrame
在 Pandas 中,DataFrame 提供了丰富的数据操作功能,包括 查询、编辑、分类和汇总。 1. 数据查询(Filtering & Querying) 1.1 按索引或列名查询 import pandas as pddata {"ID": [101, 102, 103, 104, 105],"…...
C++:volatile、const、mutable关键字
文章目录 volatile、const、mutable 关键字的作用、联系与区别 1️⃣ **volatile** —— 防止编译器优化,确保变量每次访问都从内存读取**作用****使用场景****示例** 2️⃣ **const** —— 限制变量的修改,保证不可变性**作用****使用场景****示例** 3️…...

linux离线安装miniconda环境
1 下载安装包 可以在官网下载最新版 https://www.anaconda.com/download/success#miniconda 或者在软件目录选择合适的版本 https://repo.anaconda.com/miniconda/ 安装包传入离线服务器 ./Miniconda3-py311_24.9.2-0-Linux-x86_64.sh2 运行安装包 ./Miniconda3-py311_24…...
考研408数据结构线性表核心知识点与易错点详解(附真题示例与避坑指南)
一、线性表基础概念 1.1 定义与分类 定义:线性表是由n(n≥0)个相同类型数据元素构成的有限序列,元素间呈线性关系。 分类: 顺序表:元素按逻辑顺序存储在一段连续的物理空间中(数组实现&…...
selenium用例执行过程采集操作形成测试报告上的回复
在代码执行的过程中不断的进行截图,把截图拼接成gif动态图,放在测试报告上 1、每条用例执行启动一个线程,这个线程会每隔0.3秒进行截图 项目下创建一个临时目录video用来存储所有截图以及gif动态图封装不断截图的方法,每隔0.3秒…...

多元数据直观表示(R语言)
一、实验目的: 通过上机试验,掌握R语言实施数据预处理及简单统计分析中的一些基本运算技巧与分析方法,进一步加深对R语言简单统计分析与图形展示的理解。 数据: 链接: https://pan.baidu.com/s/1kMdUWXuGCfZC06lklO5iXA 提取码: …...

【JavaEE】线程安全
【JavaEE】线程安全 一、引出线程安全二、引发线程安全的原因三、解决线程安全问题3.1 synchronized关键字(解决修改操作不是原子的)3.1.1 synchronized的特性3.1.1 synchronized的使用事例 3.2 volatile 关键字(解决内存可见性) …...

HarmonyOS 5.0应用开发——多线程Worker和@Sendable的使用方法
【高心星出品】 文章目录 多线程Worker和Sendable的使用方法开发步骤运行结果 多线程Worker和Sendable的使用方法 Worker在HarmonyOS中提供了一种多线程的实现方式,它允许开发者在后台线程中执行长耗时任务,从而避免阻塞主线程并提高应用的响应性。 S…...
华为OD-2024年E卷-分批萨[100分]
文章目录 题目描述输入描述输出描述用例1解题思路Python3源码 题目描述 吃货"和"馋嘴"两人到披萨店点了一份铁盘(圆形)披萨,并嘱咐店员将披萨按放射状切成大小相同的偶数个小块。但是粗心的服务员将披萨切成了每块大小都完全不…...

SSH监控
创建/etc/ssh/sshrc文件 写入以命令 echo " 系统状态 " uptime free -h 每次登录会显示 如果在sshrc文件加入以下脚本每次登录就是执行这个脚本 # cat /etc/ssh/sshrc echo " 系统状态 " uptime free -h /usr/local/bin/monit.sh以…...

leetcode日记(74)扰乱字符串
很有难度的一题,一开始真的绕了很多思维上的弯路。 最开始的想法是递归,看到题目的时候想到动态规划但是完全没有思路应该怎么用,结果确实是递归动态规划。 最开始的想法是构建树,每一层包含这一步划分的方法(实际会…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...

若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统
核心速览 研究背景 研究问题:这篇文章要解决的问题是当前大型语言模型(LLMs)在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色,但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成(RA…...