一、硬件结构和协议
eMMC 是一种存储芯片,它将 nand flash 和 eMMC 控制器封装在一块 BGA 芯片上。
【硬件连接图】
gpio_cd ?
协议相关可以参考下方文档。
分区说明:
eMMC 分区管理 · Linux Kernel Internals (codingbelief.com)
二、eMMC 驱动框架
eMMC 驱动代码路径(core,card,host):drivers/mmc/
这个路径下有三个文件 (不同 kernel 版本会有差异,总体结构大致一样),对应三层框架:
1.card/ --> 将 eMMC/SD 实现为块设备。向文件系统层、用户空间提供文件操作的接口,主要文件是 card/ 录下的 block.c,queue.c 向它提供了几个函数来操作队列块设备的驱动程序。
2.core/ --> 核心代码层,这部分完成了MMC/SD命令的封装,不同协议和规范(MMC/SD)的实现,为 host 层的驱动提供接口函数,它也调用主机控制器层的接口完成存储卡的识别、设置、读写等;
3.host/ --> 主机控制器驱动 (通讯接口),对接硬件,需要根据自己的芯片修改。
【框架具体介绍】
【框图】
三、主机控制器驱动分析(drivers/mmc/host/pxamic.c)
linux kernel 使用 struct mmc_host 来描述一个 emmc 主机控制器。从驱动代码中看到它最终会被注册成一个 platform 设备。
代码大致流程如下:
1、调用 mmc_alloc_host,分配一个struct mmc_host 类型的变量,描述某一个具体的 MMC host 控制器。
2、根据 MMC host 控制器的硬件特性,填充 struct mmc_host 变量的各个字段,例如 MMC 类型、电压范围、操作函数集等等。
3、调用 mmc_add_host 接口,将正确填充的 mmc_host 注册到 MMC core 中。
mmc_host 结构体介绍 原型文件:include/linux/mmc/host.h
这个结构体用来描述一个 eMMC 主机控制器,里面包含了硬件相关的一系列的参数,宏还有操
方法。其中比较重要的成员:
1.struct mmc_card,表示连接到 mmc_host 的 mmc device,原型文件 : include/linux/mmc/card.h
2.struct mmc_host_ops *ops,定义本mmc_host的操作接口(包括与mmc card通信的接口 request、卡检测相关的接口等);
struct mmc_host_ops { -----------------非常重要
int (*enable)(struct mmc_host *host); //使能和禁止HOST控制器
int (*disable)(struct mmc_host *host); // 非必要实现void (*request)(struct mmc_host *host, struct mmc_request *req); // 核心函数,用于SD卡命令和数据的传输,比如发送和接收命令,CMD0,CMD8,ACMD41诸如此类的都是在这个函数去实现。
void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); // 配置时钟、总线、电源、片选、时序等
int (*get_ro)(struct mmc_host *host); //用于检测SD卡的写保护是否打开
int (*get_cd)(struct mmc_host *host); //用于SD卡的检测,是否有卡插入和弹出
void (*enable_sdio_irq)(struct mmc_host *host, int enable); //开启sdio中断
...
}-----------------------
struct mmc_request ,封装了一次传输请求, 读写MMC卡的请求包括命令,数据以及请求完成后的回调函数。
原型文件:include/linux/mmc/core.h
struct mmc_request {
struct mmc_command *sbc; /* SET_BLOCK_COUNT for multiblock */
struct mmc_command *cmd; /*读写的命令相关信息,48bit*/
struct mmc_data *data; /*MMC卡读写的数据相关信息如:请求,操作命令,数据以及状态等*/
struct mmc_command *stop;struct completion completion;
void (*done)(struct mmc_request *); /* 完成后的回调,通知请求者*/
struct mmc_host *host;
};-------------------------
mmc_ios 结构体,描述 mmc bus 的配置,set_ios 函数
struct mmc_ios {
}
eMMC 数据和命令的读写,都是通过上面的回调函数
void (*request)(struct mmc_host *host, struct mmc_request *req);
函数的实现会去使用 DMA 直接进行存储器访问,具体方法可参考如下链接
应读者要求讲讲 DMA_布道师Peter的博客-CSDN博客
3
struct delayed_work detect;
int detect_change; /* card detect flag */
四、工作流程
【流程框图】
初始化
读流程
写流程
五、参考连接
sd 卡驱动--基于高通平台_mb61b9894206fca的技术博客_51CTO博客