u-boot中与eMMC/SD卡相关的功能模块“MMC sub system(MMC子系统)”的详细介绍

前言和先行知识

u-boot中有两个功能块对MMC(eMMC/SD)设备进行管理。
其中一个是fastboot、另一个是 MMC sub system(MMC子系统)。

fastboot主要是实现烧写数据的功能,而MMC子系统则拥有完整的命令集对MMC(eMMC/SD)设备进行管理.

fastboot也会调用MMC sub system的命令来实现其功能。关于这一点,详见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146012950【搜索“Fastboot 的PC端可利用FB”】

本篇博文介绍MMC sub system,而关于fastboot的介绍,请见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145985144

读懂本篇博文需要先对eMMC存储器有个详细的认识,详情见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145967306

U-Boot 的 MMC (MultiMediaCard) 子系统(MMC sub system)是专门用于管理 MMC 设备(包括 eMMC 和 SD 卡)的子系统,它提供了对这些存储设备的初始化、读写和分区管理等功能。


1. MMC 子系统概述

MMC 子系统主要用于支持:

  • SD/MMC/eMMC 存储设备的初始化和访问
  • 分区管理
  • FAT/ext 文件系统支持
  • 设备挂载与引导功能

U-Boot 的 MMC 子系统主要由以下几个部分组成:

  1. 驱动层drivers/mmc/
    负责具体的 MMC/SD 控制器驱动实现,例如 IMX6ULL 平台通常使用 drivers/mmc/fsl_esdhc.c

  2. 核心层drivers/mmc/mmc.c
    负责管理 MMC 设备的初始化、命令发送和数据传输。

  3. 命令层cmd/mmc.c
    提供 U-Boot 命令行接口(CLI)来操作 MMC 设备。


2. MMC子系统的命令集

如何获取当前u-boot的MMC子系统的命令集

在u-boot下运行命令mmc可以输出你当前使用的u-boot的MMC子系统的命令集。

比如我在博文 https://blog.csdn.net/wenhao_ir/article/details/145662136 中最终生成的u-boot运行后,我执行命令:

mmc

运行结果如下:
在这里插入图片描述

mmc - MMC sub system

Usage:
mmc info - display info of the current MMC device
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices
mmc hwpartition [args...] - does hardware partitioning
  arguments (sizes in 512-byte blocks):
    [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes
    [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition
    [check|set|complete] - mode, complete set partitioning completed
  WARNING: Partitioning is a write-once setting once it is set to complete.
  Power cycling is required to initialize partitions after set to complete.
mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode
 - Set the BOOT_BUS_WIDTH field of the specified device
mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>
 - Change sizes of boot and RPMB partitions of specified device
mmc partconf dev [boot_ack boot_partition partition_access]
 - Show or change the bits of the PARTITION_CONFIG field of the specified device
mmc rst-function dev value
 - Change the RST_n_FUNCTION field of the specified device
   WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.
mmc setdsr <value> - set DSR register value

现根据上面的内容说明MMC子系统各条命令的使用。

基本操作命令

1. 查看当前 MMC 设备信息

mmc info

作用

  • 显示当前 MMC 设备的详细信息,包括厂商 ID、设备名称、容量、总块数、总线速度等。

示例输出

Device: FSL_SDHC
Manufacturer ID: 3
OEM: 5344
Name: SL16G
Bus Speed: 50000000
Block Size: 512
Total Blocks: 30474240

实际输出如下:
在这里插入图片描述


2. 读数据

mmc read addr blk# cnt

作用

  • 从 MMC 设备的 blk# 块号开始读取 cnt 个块的数据,并存入 addr 指定的内存地址。

示例

mmc read 0x82000000 0x100 0x10
  • 读取 0x10 (16) 个块的数据,从 0x100 块号开始,存入内存地址 0x82000000

3. 写数据

mmc write addr blk# cnt

作用

  • addr 指定的内存地址的数据写入到 MMC 设备,从 blk# 开始写 cnt 个块。

示例

mmc write 0x82000000 0x100 0x10
  • 从内存地址 0x82000000 取数据,写入到 MMC 设备的 0x100 块,写入 0x10 (16) 个块。

4. 擦除数据

mmc erase blk# cnt

作用

  • 擦除 MMC 设备上从 blk# 开始的 cnt 个块。

示例

mmc erase 0x100 0x10
  • 擦除 MMC 设备的 0x100 块开始的 0x10 (16) 个块。

5. 重新扫描 MMC 设备

mmc rescan

作用

  • 重新初始化 MMC 设备,检测是否有新插入的 SD 卡或 eMMC 设备。

设备和分区管理

6. 列出可用的 MMC 设备及其编号

mmc list

作用

  • 列出系统中所有可用的 MMC 设备。

示例输出

FSL_SDHC: 0
  • 表示系统检测到 FSL_SDHC 控制器管理的设备,编号为 0

实际输出如下:
在这里插入图片描述
这个输出结果表明在当前u-boot下,eMMC存储器在SD/MMC 总线上的 SD/MMC 控制器的编号为1。

输出结果中FSL_SDHC的全称为:Freescale Secure Digital Host Controller,其中:

  • FSL = Freescale(飞思卡尔,现已并入 NXP)
  • SDHC = Secure Digital Host Controller(安全数字主机控制器)

NXP i.MX 处理器(如 i.MX6、i.MX7、i.MX8)中,FSL_SDHC 负责管理 SD/MMC 总线,通常有 2~4 个 SD/MMC 控制器(编号从 0 开始)。 SD/MMC 控制器可以管理 SD 卡、eMMC 存储设备

例如,在 i.MX6ULL 处理器上:

  • FSL_SDHC0 可能连接 SD 卡
  • FSL_SDHC1 可能连接 eMMC
  • FSL_SDHC2 可能是额外的 SD/MMC 控制器

7. 选择或查看当前 MMC 设备

mmc dev [dev] [part]

作用

示例

mmc dev 0
  • 选择设备 0 作为当前操作的 MMC 设备。
mmc dev 0 1
  • 选择设备 0,并使用其第 1 分区,对于eMMC存储器,实际上就是Boot partition 1

我的开发板上u-boot实际输出如下:

mmc dev 1

运行结果如下:
在这里插入图片描述
这个结果表明切换到了编号为1的MMC设备(mmc1),即当前活动的MMC设备为编号为1的mmc1设备,并且这个MMC设备的活动分区编号则是默认的0值,这里的0值在eMMC中代表的是User Area,详情请参考我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146088727 【搜索“被编号为0(即默认情况)”】

8. 列出 MMC 设备上的当前活动分区的逻辑分区信息

mmc part

说明:了解这个命令的作用前,你需要去复习下eMMC存储器启动的两个阶段——即“Boot读取阶段”和“正常数据操作阶段”,详情的介绍请参看博文https://blog.csdn.net/wenhao_ir/article/details/145967306 【搜索“eMMC启动过程的两个阶段”】。

作用

  • 显示当前 MMC 设备上的当前活动分区的逻辑分区信息。关于什么叫当前活动分区?请参考我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145967306 【搜索”即哪个分区作为前活动分区“】
  • 注意:它并不是显示前 MMC 设备上的所有分区信息,它只是显示当前活动分区的逻辑分区信息,举个例子,eMMC进入“正常数据操作阶段”后,默认情况下当前活动分区都是User Area区,此时运行这个命令显示的是User Area区下的逻辑分区信息,这里所谓逻辑分区就是指把User Area分区再进行区域的划分。此时命令mmc part 是看不到Boot partition 1分区和Boot partition 2分区的,你此时查看的分区信息都是User Area分区的逻辑分区信息。

示例输出

Partition Map for MMC device 0  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID
  1     8192           1048576         0x83
  2     1056768        2097152         0x83
  • Part 18192 扇区开始,大小 1048576 扇区。
  • Part 21056768 扇区开始,大小 2097152 扇区。

我的开发板实际运行结果如下:
在这里插入图片描述
分析:
首先用命令mmc dev 1 0将编号为1的eMMC切换到User Area区(命令中末尾的0代表User Area区)。关于为什么0代表User Area区,请参看我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146088727
然后用命令mmc part查看User Area区的分区信息,即User Area区的逻辑分区信息。
从结果中我们可以看到我所使用的eMMC存储器的User Area区被划分为了三个逻辑分区,三个逻辑分区的编号分别为1、2、3。三个逻辑分区的大小可以使用Num Sectors来计算,一个Num Sectors代表512B,即512个字,所以三个分区的大小分别计算如下:
第1个逻辑分区:1024000512/1024/1024 = 500MB
第2个逻辑分区:2097152
512/1024/1024 = 1024MB
第3个逻辑分区:20480*512/1024/1024 = 10MB
这就是为什么百问网的烧写工具要把根文件系统放在第2个逻辑分区的原因了,因为这个逻辑分区最大嘛。关于百问网的烧写工具的详细介绍见博文 https://blog.csdn.net/wenhao_ir/article/details/145653414
从上面可以看出:此时的编号1、2、3其实代表的是User Area区的三个逻辑分区。

备注说明:Boot partition 1Boot partition 2是没有划分逻辑分区的,所以如果你查看这两个逻辑分区,会出现bad MBR sector signature 0x0000的提示,如下图所示:
在这里插入图片描述
注意:命令mmc dev 1 1中的第1个1表示编号为1的MMC设备,第2个1表示Boot partition 1分区,关于为什么第2个1代表示Boot partition 1分区,请参看我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146088727


eMMC 专用管理命令

这些命令主要用于 eMMC 设备,因为 eMMC 具有比 SD 卡更多的高级功能,如硬件分区和引导配置。

9. 硬件分区管理

mmc hwpartition [args...]

作用

  • 对 eMMC 进行硬件分区,例如创建 用户区增强型用户区GP(General Purpose)分区

示例

mmc hwpartition gp1 1024 enh set complete
  • 创建一个 1024 个 512B 扇区的 GP1 分区,启用 enh(增强模式),然后 set complete(完成配置)。

警告

  • set complete 之后,分区配置 不可更改,需要 断电重启 使其生效!

10. 修改 eMMC 引导总线配置

mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode

作用

  • 设置 eMMC 的 BOOT_BUS_WIDTH 字段,以调整启动模式。

示例

mmc bootbus 0 2 0 1
  • 选择设备 0
  • boot_bus_width=2(8-bit DDR)
  • reset_boot_bus_width=0
  • boot_mode=1(单数据率模式)

11. 调整 eMMC 启动分区大小

mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>

作用

  • 修改 eMMC 设备的 引导分区RPMB(Replay Protected Memory Block)分区 的大小。

示例

mmc bootpart-resize 0 4 2
  • 把 eMMC 设备 0 的引导分区设为 4MB,RPMB 分区设为 2MB

12. 修改 eMMC 启动分区访问配置

mmc partconf dev [boot_ack boot_partition partition_access]

作用

  • 设置 eMMC 启动分区的访问模式。

示例

mmc partconf 0 1 1 1
  • 设备 0
    • boot_ack=1(启动确认)
    • boot_partition=1(使用 boot1 分区作为启动分区)
    • partition_access=1(选择 eMMC进入“正常数据操作阶段”后,哪个分区作为活动分区,这里一般都是设置的是0,表示eMMC进入“正常数据操作阶段”后,使User Area区作为当前活动分区。关于这一点详细的介绍请参看我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145967306 【搜索“控制当前访问的 eMMC 分区”】)

13. 修改 eMMC 复位功能

mmc rst-function dev value

作用

  • 设置 eMMC 设备 RST_n_FUNCTION 字段。

示例

mmc rst-function 0 1
  • 设置设备 0RST_n_FUNCTION1(启用 eMMC 复位)。

RST_n_FUNCTION 取值及影响

说明
0RST_n 引脚禁用(无效,外部复位信号不会影响 eMMC)
1RST_n 引脚启用(eMMC 响应外部复位信号)
2RST_n 引脚启用,并且是一次性写入的(OTP,One-Time Programmable)

注意:如果RST_n_FUNCTION的值设为 2,那么RST_n_FUNCTION 的值就不能更改了(OTP-One-Time Programmable,永久设置),请谨慎使用!


14. 修改 DSR(Driver Stage Register)

mmc setdsr <value>

作用

  • 设置 MMC 设备的 DSR 值。在 MMC 设备中,DSR(Driver Stage Register,驱动级寄存器) 是一个 可选 的 16 位寄存器,用于微调 MMC 设备的驱动特性,以优化信号完整性和系统兼容性。它可以控制 MMC 设备的驱动强度,调整其 I/O 特性,以适应不同的 PCB 设计和电气环境。它可以允许主机和设备进行匹配,以减少信号反射、提高稳定性、减少 EMI(电磁干扰)。注意:不是所有 MMC 设备都支持 DSR 功能。

示例

mmc setdsr 0x0404
  • 设置 DSR 为 0x0404

3. 利用MMC子系统的fatload命令和ext4load命令引导加载内核

在 U-Boot 中,fatload mmcext4load mmc 命令用于从 MMC(SD 卡或 eMMC)加载文件到内存。它们的完整格式如下:

1. fatload mmc

用于从 FAT 文件系统的 MMC 设备加载文件到内存:

fatload mmc <dev[:part]> <addr> <filename> [bytes]
  • <dev>:MMC 设备编号(通常是 0 或 1)
  • <part>:准备要加载的文件是存储在eMMC的当前活动分区(通常为User Area区)的哪个逻辑分区中。
  • <addr>:文件加载到的内存地址(通常为 RAM 地址)
  • <filename>:要加载的文件路径
  • [bytes](可选):要加载的字节数,默认加载整个文件

示例

fatload mmc 0:1 0x82000000 boot.img

表示从 mmc 0 的当前活动分区(通常为User Area区)的第 1 逻辑分区加载 boot.img 到内存地址 0x82000000fat代表这个逻辑分区的文件系统是FAT。


2. ext4load mmc

用于从 Ext4 文件系统的 MMC 设备加载文件到内存:

ext4load mmc <dev[:part]> <addr> <filename> [bytes]
  • <dev>:MMC 设备编号
  • <part>:准备要加载的文件是存储在eMMC的当前活动分区(通常为User Area区)的哪个逻辑分区中。
  • <addr>:文件加载到的内存地址
  • <filename>:要加载的文件路径
  • [bytes](可选):要加载的字节数,默认加载整个文件

示例

ext4load mmc 0:2 0x82000000 /boot/uImage

表示从 mmc 0 的当前活动分区(通常为User Area区)的第 2逻辑分区(Ext4 文件系统)加载 /boot/uImage 到内存地址 0x82000000ext4代表这个逻辑分区的文件系统是ext4


两条命令中的part参数的编号来自于哪里

在命令fatload mmcext4load mmc 命令中part参数的意义为当前活动分区(通常为User Area区)的逻辑分区的编号。也就是与命令mmc part 输出信息中part列编号的意义一样。所以对于命令fatloadext4load中需要的part参数实际上我们可以从命令mmc part 的输出信息获取。


4. U-Boot 如何启用 MMC

U-Boot 需要正确配置 CONFIG_MMC 选项来启用 MMC 支持:

CONFIG_MMC=y
CONFIG_GENERIC_MMC=y
CONFIG_FSL_ESDHC=y       /* i.MX6ULL 的 MMC 控制器 */
CONFIG_SYS_MMC_ENV_DEV=0  /* 指定存储环境变量的 MMC 设备号 */

如果 U-Boot 需要在 eMMC/SD 上存储环境变量,通常需要:

CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_MMC_ENV_DEV=0
CONFIG_ENV_OFFSET=0x400000

5.实际使用例子

利用MMC子系统查看和修改eMMC设备的EXT_CSD[179]配置信息

第01步
运行下面的命令即可查看设备的EXT_CSD[179]信息:

先运行命令看下eMMC设备在u-boot中的编号:

mmc list

在这里插入图片描述
这个输出结果表明在当前u-boot下,eMMC存储器在SD/MMC 总线上的 SD/MMC 控制器的编号为1。

输出结果中FSL_SDHC的全称为:Freescale Secure Digital Host Controller,其中:

  • FSL = Freescale(飞思卡尔,现已并入 NXP)
  • SDHC = Secure Digital Host Controller(安全数字主机控制器)

NXP i.MX 处理器(如 i.MX6、i.MX7、i.MX8)中,FSL_SDHC 负责管理 SD/MMC 总线,通常有 2~4 个 SD/MMC 控制器(编号从 0 开始)。 SD/MMC 控制器可以管理 SD 卡、eMMC 存储设备

例如,在 i.MX6ULL 处理器上:

  • FSL_SDHC0 可能连接 SD 卡
  • FSL_SDHC1 可能连接 eMMC
  • FSL_SDHC2 可能是额外的 SD/MMC 控制器

第02步
选择当前的MMC设备,因为我的eMMC设备在u-boot中编号为1,所以命令如下:

mmc dev 1

运行结果如下:
在这里插入图片描述
这个结果表明切换到了编号为1的MMC设备(mmc1),即当前活动的MMC设备为编号为1的mmc1设备,并且这个MMC设备的活动分区编号则是默认的0值,这里的0值在eMMC中代表的是User Area,详情请参考我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146088727 【搜索“被编号为0(即默认情况)”】
第03步

运行下面的命令查看EXT_CSD[179]配置信息:

mmc partconf 1

命令中的参数1代表设备编号为1。
在这里插入图片描述
这个结果表明eMMC 在 启动阶段(Boot Operation) 会发送 Boot Acknowledge(ACK) 信号,从从 Boot 分区 1 启动,当前访问的 eMMC 分区为0分区,即普通用户数据区。

第04步
接下来,说下怎么修改EXT_CSD[179的]配置信息。
本文上面介绍的第12个命令格式就可以实现修改EXT_CSD[179的]配置信息。。

mmc partconf dev [boot_ack boot_partition partition_access]

示例如下:

mmc partconf 1 1 1 0

具体意义如下:
- 第1个参数值为1的意义:选择 编号为1的 eMMC 设备;
- 第2个参数值为1的意义:启用 Boot Acknowledge信号。
- 第3个参数值为1的意义:选择 eMMC Boot 分区 1(即 boot1) 作为启动分区。
- 第4个参数值为1的意义:
- boot_partition = 1 → 选择 eMMC Boot 分区 1(即 boot1) 作为启动分区
- partition_access = 0 → 设置eMMC进入“正常数据操作阶段”后,eMMC的活动分区为普通用户数据区(0值就是代表普通用户数据区),即从普通用户数据区进行数据的读写操作。关于这一点详细的介绍请参看我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145967306 【搜索“控制当前访问的 eMMC 分区”】

利用MMC子系统和Fastboot烧写u-boot、内核、设备树

详情见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146012950

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值