Linux MMC子系统5(基于Linux6.6)---MMC driver模块介绍
mmc 子系统为何实现了统一的mmc driver,主要有如下几点:
- Mmc host已提供了访问mmc card的方法(mmc_host->request);
- mmc/emmc/sd等协议规范均已定义mmc card(包括mmc/sd/tf等存储卡)支持的命令格式以及状态流转机制、寄存器定义等信息,因此可使用统一的驱动程序实现对所有厂家的card通信(这是由协议规范规定的,比如针对nandflash驱动模块,也不需要为nandflash设备实现特定驱动,因其协议规范也规定了nandflash需要支持的操作及通信格式等等)
基于以上几点,并不需要针对各厂家的mmc card,实现特殊的mmc driver,因此mmc 子系统实现了统一的mmc driver;
一、相关的数据结构及关联说明
针对mmc driver而言,相关的数据结构包括mmc_driver、device_driver、device、mmc_card、mmc_part、mmc_blk_data、mmc_queue、gendisk、request_queue等;
其中mmc_driver为一个mmc card驱动的抽象;device_driver、device为linux设备驱动模型相关的数据结构(该模块已在前面的文章中介绍,此处不再赘述);gendisk、request_queu、request_fn为块设备模型相关的数据结构(此处不展开);mmc_blk_data、mmc_queue主要用于实现mmc block device的通用块层与mmc host之间进行数据传输;而mmc_card则为mmc_driver所要驱动的外设。
这些数据结构之间的关联如下图所示,它们的关联关系说明如下:
- Mmc_driver与mmc_card,通过借助设备-总线-驱动模型的数据结构(device_driver、device)及接口,实现绑定与解绑操作;
- 针对mmc card,通过mmc_part可定义该mmc card的分区个数及分区大小等内容(mmc card中extended CSD寄存器中存储分区信息,当通过mmc rescan查找到mmc card时,会通过读取该寄存器的值,获取mmc card的分区信息);
- mmc_blk_data用于抽象mmc block device信息,这其中包括mmc_queue、request_queue、gendisk这些数据结构;
在完成mmc_driver与mmc_card的绑定过程中,在调用mmc_driver->probe进行设备探测时,则进行mmc block device的创建,针对每一个分区,均执行如下操作:
- 创建mmc_blk_data类型的变量,即为每一个分区均创建对应的通用块设备(gendisk类型);
- 创建mmc_queue,并为其创建对应的线程及处理接口(主要用于处理来自块I/O子系统的请求);
- 针对对mmc_queue,为其创建request_queue及其请求方法mmc_request_fn,并与gendisk进行关联;
- 将gendisk注册至块I/O子系统中,从而将本分区对应的通用块设备注册至块设备对应的bdev_map中,类似于字符设备的cdev_map;
1. MMC Driver 子系统
MMC 驱动子系统是 Linux 内核中专门负责与 MMC 存储设备进行交互的模块。它主要包括以下几个功能:
- 卡和主机控制器的抽象:处理不同类型的存储设备(如 SD 卡、eMMC 卡、UFS 等)。
- MMC 核心的命令调度:管理卡的初始化、读写请求和命令的调度。
- 设备支持:包括插拔检测、卡的电源管理等。
数据结构:
mmc_driver
:这是 MMC 驱动的核心结构体,定义了 MMC 设备与驱动程序的交互接口。例如,它包含了设备初始化、退出、驱动加载等函数。
struct mmc_driver {
const char *name; // 驱动名称
int (*probe)(struct mmc_card *card, struct mmc_host *host); // 驱动初始化
void (*remove)(struct mmc_card *card); // 驱动卸载
struct device_driver driver; // 与设备模型的集成
};
mmc_card
:表示一个插入的 MMC 卡,保存与卡相关的各种属性信息。
s