Linux MMC子系统1(基于Linux6.6)---概述
一、概述
MMC(MultiMediaCard) 子系统是 Linux 内核中负责支持和管理 MMC 和 SD(Secure Digital)卡的组件。MMC 和 SD 卡通常用于嵌入式设备中,用作存储介质,广泛应用于智能手机、平板、相机、嵌入式系统等设备。
MMC 子系统通过提供统一的接口,支持多种不同类型的存储设备,并管理设备的初始化、数据读写、错误处理等功能。Linux 内核的 MMC 子系统也支持 SDIO(SD Input Output)设备,这些设备不仅可以用于存储,还可以用于其他功能,如无线网卡、蓝牙模块等。
1.1、MMC 子系统结构
MMC 子系统主要由以下几个部分组成:
1.MMC 驱动程序
- MMC 驱动程序负责与硬件进行通信。每个 MMC 设备的驱动程序会实现特定的硬件操作,如数据读写、卡初始化等。
- 驱动程序通常会绑定到特定的 MMC 卡控制器(如 SDHCI 控制器)上。
2.MMC 控制器(Host Controller)
- MMC 控制器是与存储卡直接交互的硬件部件,通常是一个芯片或硬件模块,负责发起与卡之间的数据传输。控制器与卡之间的通信是基于专门的协议标准,如 MMC 或 SD 协议。
- 控制器通常通过总线接口(如 SPI、SDIO)连接到系统中。
3.MMC 卡
- MMC 卡是用于存储数据的介质,可以是 SD 卡、eMMC 卡、SDIO 卡等。它们遵循相应的协议标准进行数据交互。
- MMC 卡根据不同的标准(如 SDHC、SDXC、eMMC)有不同的存储容量、速度和接口规范。
4.MMC 子系统中的核心模块
- Block Layer:MMC 子系统使用内核的块设备层(Block Layer)来处理存储设备的读写操作。块设备驱动负责将数据按块(通常是 512 字节或更大的块)读写到 MMC 卡中。
- File System:文件系统(如 ext4、FAT32、exFAT)提供了在 MMC 卡上存储和管理数据的高级接口。
1.2、CPU、MMC之间的硬件关联图
CPU、MMC controller、存储设备之间的关联如下图所示,主要包括了MMC controller、总线、存储卡等内容的连接,针对控制器与设备的总线连接,主要包括时钟、数据、命令三种类型的引脚,而这些引脚中的cd引脚主要用于卡的在位检测,当mmc controller检测到该位的变化后,则会进行mmc card的注册或注销操作。
在MMC子系统中,主要包含MMC总线、SDIO总线两个部分,其中MMC部分则主要用于适配MMC卡、SD卡、TF卡等存储设备,而SDIO部分则主要用于实现针对SDIO接口连接的设备(wifi、bluetooth、uart、gps、esata等)
二、MMC驱动模型概述
MMC驱动模型也是基于实际的硬件连接进行抽象的,其实该mmc驱动模型的抽象和iic、spi模型类似,如下具体的抽象说明:
- 针对mmc controller,该子系统抽象为mmc_host,用于描述一个mmc controller;
- 针对mmc、sd、tf卡,该子系统抽象为mmc_card,用于描述卡信息;
- 针对通信总线,抽象出mmc_bus;
- 针对mmc、sd、tf,mmc子系统完成了统一的mmc driver,针对mmc总线规范以及SD规范,其已经详细的定义了一个存储卡的通信方式、通信命令,因此LINUXmmc子系统定义了mmc driver,用于和mmc、sd、tf等卡的通信,而不需要驱动开发人员来开发卡驱动。
而针对这四者之间的关系,以及这四者是如何借助LINUX设备-总线-驱动模型实现关联的,可从如下图中找到对应的关联。
该模型的实现和spi模型是类似的,其中mmc host不添加至mmc bus中,另外和iic、spi不同的是:
- mmc总线模型中只注册一个驱动类型,即mmc driver(该驱动适配所有的mmc card);
- 一个mmc host与一个mmc card绑定;
- Mmc card属于热插拔的设备,而mmc card的创建主要由mmc host负责探测与创建,mmc host根据卡在位检测引脚,当检测到mmc card的存在后,即创建mmc card,同时注册至mmc bus上,并完成与mmc driver的绑定操作。
三、SDIO驱动模型概述
sdio总线驱动模型和mmc类型,结构体上的区别为其driver类型为sdio_driver,并增加了sdio_func结构体变量(该结构体包含了该sdio设备相关的厂商id、设备id,同时包含了mmc_card),与mmc总线驱动模型的区别为:
方面 | MMC总线驱动模型 | SDIO总线驱动模型 |
---|---|---|
主要用途 | 存储卡设备,如SD卡、eMMC等 | 非存储设备,如Wi-Fi、蓝牙、GPS模块等 |
协议与功能 | 仅支持存储功能,主要用于数据存储操作 | 除了支持存储功能外,还支持I/O功能,如无线通信等 |
驱动框架 | 通过mmc 子系统进行设备管理与存储操作 | 基于sdio 子系统,处理与SDIO设备的通信与管理 |
常见设备 | 存储卡、SD卡、eMMC等存储设备 | Wi-Fi模块、蓝牙模块、GPS模块等 |
硬件控制器 | 使用MMC控制器驱动(如sdhci ) | 共享MMC控制器驱动,但增加SDIO特定的支持 |
四、MMC块设备
因mmc_card一般均是存储设备,因此针对该设备的访问即需要借助LINUX内核的块设备模型,因此mmc子系统也必须要实现块设备驱动,借助该块设备驱动模型,将mmc card与vfs完成了关联,即可通过系统调用借助VFS模型实现对块设备的读写访问操作。
1. MMC块设备模型
在Linux中,MMC设备被视为块设备(Block Device)。块设备的操作模型通常涉及以下几个方面:
- 块设备驱动:它通过块设备接口提供对存储设备的读写操作。
- MMC子系统:这是Linux内核中处理MMC卡的核心子系统,提供了对卡的管理、命令执行、数据传输等功能。MMC子系统通过接口管理块设备的生命周期(如插入、拔出、初始化等)。
2. MMC块设备的组成
MMC子系统
MMC子系统由多个子模块组成,其中最重要的模块是:
- mmc_core:管理MMC设备的核心功能,包括卡的生命周期(插入、拔出)、卡的初始化、协议处理等。
- mmc_blk:处理MMC卡的块设备接口,负责将MMC存储设备作为标准块设备暴露给用户空间,使用户可以通过常见的文件系统接口访问它。
MMC设备与块设备
-
mmc_blk驱动:MMC卡通过
mmc_blk
子系统注册为块设备,使得Linux能够对其进行常规的读写操作。通过/dev/mmcblk0
等设备节点,用户可以直接对MMC卡进行文件读写操作。 -
块设备操作:MMC设备的读写操作由块设备驱动完成,Linux系统通过缓冲区缓存机制和I/O调度对数据块进行管理,确保读写操作的高效性和可靠性。
MMC卡的读写操作
在Linux中,MMC卡的读写操作依赖于mmc_blk
驱动和MMC协议的交互:
- 读操作:在Linux中,读操作通过
read()
系统调用请求,底层会调用MMC驱动中的相关函数来发送读取命令到MMC卡,并从卡上获取数据。 - 写操作:写操作则通过
write()
系统调用,底层会将数据块写入MMC卡。写操作可能涉及数据的缓存和刷写,具体实现取决于文件系统和内存管理策略。
3. MMC设备的管理
设备插拔与初始化
- 设备插入:当MMC卡插入系统时,
mmc_core
子系统会探测到新设备并进行初始化。初始化过程中,卡的特性(如存储大小、速度等级等)将被识别,并且设备节点(如/dev/mmcblk0
)会被创建,用户可以开始使用该设备。 - 设备拔出:当MMC卡拔出时,Linux会通过
mmc_remove_card()
来卸载卡设备,并更新系统状态。
设备属性
每个MMC卡都有其自身的属性,如:
- 容量:卡的总存储容量(通常以字节为单位)。
- 速度等级:表示卡的数据传输速度等级,如SDHC、SDXC等。
- 文件系统类型:Linux会使用不同的文件系统(如ext4、FAT32等)来格式化MMC卡,使其可以在系统中存储和管理文件。
4. MMC与SD卡的关系
虽然MMC和SD卡在物理接口上有许多相似之处,它们之间的驱动和协议实现有所不同。SD卡是一种更为流行的标准,许多SD卡支持SDIO(输入输出)功能,而MMC卡通常仅支持存储功能。然而,在Linux内核中,SD卡和MMC卡通常是通过类似的总线(如SDHCI)进行管理的。
- MMC设备:主要指存储类设备,通常不具备SD卡的扩展输入/输出功能。
- SD卡设备:也可以作为MMC设备使用,但具有更多的扩展功能,如SDIO卡、UHS-I等高速度标准。
5. MMC块设备的文件系统
MMC块设备在Linux系统中通常会与文件系统结合使用,以便存储和管理文件。常见的文件系统包括:
- FAT(FAT16, FAT32):广泛应用于SD卡、MMC卡等存储设备,兼容性好,适用于嵌入式系统。
- ext4:Linux原生文件系统,提供高效的读写性能和良好的容错能力。
- exFAT:为大容量存储设备设计的文件系统,尤其适用于高容量SD卡和MMC卡。
文件系统挂载
一旦MMC卡通过mmc_blk
驱动注册为块设备,Linux系统可以使用mount
命令将文件系统挂载到某个目录,从而可以进行文件操作。例如:
mount /dev/mmcblk0p1 /mnt
五、MMC子系统的目录说明
针对mmc子系统,在代码实现上主要包括mmc core、mmc block、 mmc host这三个模块,其中mmc host主要是针对mmc controller的驱动;mmc block主要用于实现mmc block驱动以及mmc driver;而mmc core主要包括mmc 总线、sdio总线的实现、mmc device、mmc driver的注册接口、mmc host与mmc card的注册与注销接口等内容。
以下是与MMC子系统相关的主要目录及其说明:
1. /drivers/mmc/
这个目录是Linux内核中MMC相关代码的主要存放位置。所有与MMC设备相关的驱动和子系统模块都位于此目录下。具体的目录结构如下:
core/
:此目录包含了mmc_core
子系统的核心代码,主要负责管理MMC卡的生命周期、插拔、初始化等功能。block/
:包含了mmc_blk
驱动的实现。该驱动将MMC卡作为块设备(Block Device)暴露给系统,使得可以使用常见的块设备接口进行读写操作。host/
:该目录包含了MMC主机控制器驱动程序。MMC卡和系统之间的通信通过主机控制器进行,因此主机驱动程序负责提供对MMC总线的控制和管理。sdhci/
:包含了SDHCI(SD Host Controller Interface)相关的驱动程序。SDHCI是一个常见的接口,支持SD卡和MMC卡的通信,通常与SD卡和MMC卡共享一个物理接口。omap/
、tianocore/
等子目录:这些是特定硬件平台的MMC子系统实现。如果你使用的是某个特定平台(如OMAP、TI平台等),这些目录包含了为该平台定制的MMC控制器驱动代码。
2. /drivers/mmc/core/
这个目录包含了与MMC卡管理和基本操作相关的核心代码。主要文件包括:
core.c
:负责实现MMC卡的管理功能,包括卡的初始化、插拔检测、状态更新等。mmc_ops.c
:定义了MMC卡操作相关的接口函数,处理如读写命令、查询卡信息等功能。sdio.c
:负责与SDIO(SD Input/Output)设备的交互。SDIO是SD卡的一种扩展,支持通过SD卡接口实现其他类型的设备(如Wi-Fi模块)。
3. /drivers/mmc/block/
这个目录包含了与MMC卡作为块设备相关的代码。主要文件包括:
mmc_block.c
:实现了将MMC设备注册为块设备的功能,提供了对MMC卡的读写操作。通过该代码,MMC卡的存储区域可以通过文件系统接口被访问。mmcblk.c
:负责处理MMC卡块设备的请求,涉及I/O调度和请求处理。
4. /drivers/mmc/host/
这个目录包含了与硬件主机控制器相关的驱动程序,负责管理MMC总线和控制器。每个主机控制器驱动(如sdhci
)都需要在此目录中注册其设备,以便进行MMC卡的读写操作。
sdhci.c
:实现了SDHCI协议支持,通过SDHCI标准与MMC卡通信。sdhci-omap.c
:针对OMAP平台的SDHCI主机控制器驱动。sdhci-pci.c
:针对PCI设备的SDHCI驱动。
5. /drivers/mmc/omap/
如果你的设备基于OMAP(如TI平台),那么你会在此目录中找到专门为OMAP平台编写的MMC相关代码。例如:
omap_hsmmc.c
:实现了OMAP平台的硬件控制器驱动,支持MMC和SD卡设备。
6. /drivers/mmc/sdhci/
这个目录专门包含了与SDHCI(SD Host Controller Interface)相关的代码。SDHCI是一个标准接口,许多不同的硬件平台都可以通过SDHCI与MMC卡进行通信。该目录内的驱动程序实现了SDHCI规范,允许SD卡和MMC卡的兼容性。
sdhci.c
:实现SDHCI主机控制器驱动的核心代码,提供与MMC卡的低层通信支持。sdhci-pltfm.c
:SDHCI平台相关代码,支持不同平台的特定配置。
7. /include/linux/mmc/
这个目录包含了与MMC子系统相关的头文件。包括:
mmc/card.h
:定义了MMC卡数据结构和操作接口。mmc/host.h
:包含了MMC主机控制器的接口和数据结构。mmc/mmc.h
:包含了MMCC(MultiMediaCard)的基础结构和操作。
8. /sys/class/mmc_host/
在用户空间中,/sys/class/mmc_host/
目录用于显示系统中所有已注册的MMC主机控制器的信息。每个MMC主机控制器都有一个目录,其中包含了其状态和配置信息。通过这个目录,用户可以动态获取设备信息,如当前MMC主机控制器的工作状态、卡的插入/拔出事件等。
9. /dev/mmcblkX
在用户空间中,MMC设备作为块设备呈现,每个MMC设备会在/dev/
目录下创建相应的设备节点(例如,/dev/mmcblk0
)。用户可以通过这些设备节点直接访问存储设备进行读写操作。
/dev/mmcblk0
:表示第一个MMC卡的块设备节点。/dev/mmcblk0p1
:表示第一个MMC卡的第一个分区。
10. /proc/mounts
和 /etc/fstab
这些文件用于查看和配置文件系统挂载。在这些文件中,MMC设备通常会以/dev/mmcblkX
的形式出现,表示MMC卡或SD卡分区的挂载情况。
/proc/mounts
:显示当前挂载的所有文件系统,包括MMC卡。/etc/fstab
:用于配置系统启动时自动挂载的文件系统。