前言
关于eMMC的分区编号和名字问题,表面上看是个小问题,事实上在程序开发中,没有小问题,一个变量值设置不对,可能整个程序或系统就跑不起来。eMMC的分区编号和名字问题就是一个事关嵌入式系统烧写和正常启动的关键问题,如果没有搞清楚,你根本用不好烧写工具,也无法将整个嵌入式系统启动起来。
关于这个问题,其实是要分情况的,具体分下面几种情况:
①在eMMC标准中的分区名字和编号问题;
②在u-boot的MMC系统中的分区编号问题;
③#在u-boot的Fastboot模式下各分区的名字和编号问题;
③在Linux中的分区名字和编号问题。
本篇博文具体介绍这此情况。
01-在eMMC标准中的分区名字和编号问题
在eMMC标准中的分区名字和编号问题,需要参考制定eMMC标准的组织提供的文档。
关于标准制定组织的介绍和文档的下载地址,请参考我的另一篇博文:
https://blog.csdn.net/wenhao_ir/article/details/145967306 【搜索“由JEDEC协会制定的”】
eMMC标准中的分区名字
在文档的224页对 EXT_CSD[179]各字段的解释如下:
上面划红线的内容实际上就是eMMC标准中对各分区的命名,根据这些名字,我们可以得出下面这个分区示意图:
+----------------------+ 0x00000000
| Boot Partition 1 | (大小固定,如4MB)
+----------------------+
| Boot Partition 2 | (大小固定,如4MB)
+----------------------+
| RPMB Partition | (大小固定,如512KB)
+----------------------+
| General Purpose 1 | (可选)
+----------------------+
| General Purpose 2 | (可选)
+----------------------+
| General Purpose 3 | (可选)
+----------------------+
| General Purpose 4 | (可选)
+----------------------+
| User Area | (最大存储区域)
+----------------------+ 0xFFFFFFFF
eMMC标准中的分区编号
至于各分区在eMMC标准中的分区编号问题,这要分情况,我们还是看下面两张图:
从上面的文档截图来看:
对于EXT_CSD[179]的BOOT_PARTITION_ENABLE
字段,Boot partition 1
被编号为1,Boot partition 2
被编号为2,User area
被编号为7。
对于EXT_CSD[179]的PARTITION_ACCESS
字段,Boot partition 1
仍被编号为1,Boot partition 2
仍被编号为2,但User area
被编号为0(即默认情况)。
关于BOOT_PARTITION_ENABLE
字段和PARTITION_ACCESS
字段的详情说明,请参看博文 https://blog.csdn.net/wenhao_ir/article/details/145967306 【搜索“字段说明”】
所以在不同情况下,eMMC标准中的编号是不一样的,但是还是有规律的,我们可以看到Boot partition 1
基本都被编号为1,Boot partition 2
也基本都被编号为2。
02-在u-boot的MMC系统中的分区编号问题
首先你要知道在u-boot中没有分区名字的说法,全是编号。
在u-boot中的分区编号的意义其实也要根据具体的命令来定,在博文 https://blog.csdn.net/wenhao_ir/article/details/146016551 中我列举出了u-boot用于管理MMC设备的子系统的常见命令。
在这些命令中,不同命令中的不同编号意义不一样,常用的如下:
命令mmc dev [dev] [part]
中的part参数的意义
命令mmc dev [dev] [part]
中的part参数的意义实际上我在博文https://blog.csdn.net/wenhao_ir/article/details/146016551 中已经说得很清楚了,详情请在博文 https://blog.csdn.net/wenhao_ir/article/details/146016551 中搜索关键词“指定要使用的分区编号”。
总结一下就是在命令mmc dev [dev] [part]
中的part参数的意义来自于EXT_CSD[179]的字段PARTITION_ACCESS
。而关于EXT_CSD[179]的字段PARTITION_ACCESS
的详细介绍见博文 https://blog.csdn.net/wenhao_ir/article/details/145967306 【搜索“即哪个分区作为前活动分区”】
命令mmc part
输出信息中part列编号的意义
命令mmc part
用于列出 MMC 设备上的当前活动分区的逻辑分区信息。
详细的分析我在博文https://blog.csdn.net/wenhao_ir/article/details/146016551 中已经说得很清楚了,详情请在博文 https://blog.csdn.net/wenhao_ir/article/details/146016551 中搜索关键词“列出 MMC 设备上的当前活动分区的逻辑分区信息”。
总结一下就是在命令mmc part
输出信息中part列编号的意义是当前活动分区(通常为User Area
区)的逻辑分区的编号。
加载内核的命令fatload
和ext4load
中part参数的意义
命令fatload
和ext4load
中part参数的意义的详细分析我在博文https://blog.csdn.net/wenhao_ir/article/details/146016551 中已经说得很清楚了,详情请在博文 https://blog.csdn.net/wenhao_ir/article/details/146016551 中搜索关键词“fatload mmc”。
总结一下就是在命令fatload mmc
和 ext4load mmc
命令中part参数的意义为当前活动分区(通常为User Area
区)的逻辑分区的编号。也就是与命令mmc part
输出信息中part列编号的意义一样。所以对于命令fatload
和ext4load
中需要的part参数实际上我们可以从命令mmc part
的输出信息获取。
03-在u-boot的Fastboot模式下各分区的名字和编号问题
Fastboot模式下我们重点说下flash
烧写命令是把文件烧写到eMMC存储设备的哪个位置?
比如下面这条命令:
flash bootloader ../../../files/u-boot-dtb.imx
它到底是把u-boot-dtb.imx烧写到eMMC设备的哪个分区?它写到哪个分区是在哪里设置的?
这个问题其实我在博文 https://blog.csdn.net/wenhao_ir/article/details/145985144 中详细解释了,请在博文 https://blog.csdn.net/wenhao_ir/article/details/145985144 中搜索关键词“Fastboot的flash命令如何确定将镜像烧写到哪里”。
总结一下:对于Fastboot模式下的下flash
烧写命令,各区的名字是由u-boot中与Fastboot有关的代码定义的,各分区也没有编号,而是一种名字与具体烧写地址的映射关系。
04-在Linux中的分区名字和编号问题
在Linux系统中,eMMC的不同区域通常会映射成不同的设备节点,所以在Linux中,各分区的名字就是各设备节点的设备文件名。
假设eMMC存储设备在Linux系统中的编号为1,则示例如下:
eMMC区域 | 设备节点示例 | 说明 |
---|---|---|
Boot Partition 1 | /dev/mmcblk1boot0 | 引导分区 1 |
Boot Partition 2 | /dev/mmcblk1boot1 | 引导分区 2 |
RPMB Partition | /dev/mmcblk1rpmb | 认证存储区(受保护) |
User Area | /dev/mmcblk1 | 整个用户数据区 |
User Area的第1个逻辑分区 | /dev/mmcblk1p1 | 用户数据区的第1个逻辑分区 |
User Area的第2个逻辑分区 | /dev/mmcblk1p2 | 用户数据区的第2个逻辑分区 |
那么我们自然要问,如何查看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 Area )的设备节点名为mmcblk1
,它被划分成了三个逻辑分区,分别为mmcblk1p1
、mmcblk1p2
、mmcblk1p3
,容量大小情况如下:
mmcblk1
:3817472KB = 3728MB ≈ 3.6GB
mmcblk1p1
:512000KB = 500MB ≈ 0.48GB
mmcblk1p2
:1048576KB = 1024MB ≈ 1 GB
mmcblk1p3
:10240KB = 10MB
可见,用户数据区(User Area )的第2逻辑分区是最大的,有1个GB的大小。这也是百问网要把根文件系统、设备树文件、内核镜像放在第2逻辑分区中的原因,因为它最大啊。
命令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)。这里的*
号只是一个标志,表示该分区被设定为可引导,但不一定真正参与系统启动。