本文主要是分析Linux系统中mmc子系统的框架和实现。
kernel使用MMC subsystem统一管理MMC、SD、SDIO等设备。
MMC是MultiMediaCard的简称,从本质上看,它是一种用于固态非易失性存储的内存卡(memory card)规范[1],定义了诸如卡的形态、尺寸、容量、电气信号、和主机之间的通信协议等方方面面的内容。
从1997年MMC规范发布至今,基于不同的考量(物理尺寸、电压范围、管脚数量、最大容量、数据位宽、clock频率、安全特性、是否支持SPI mode、是否支持DDR mode、等等),进化出了MMC、SD、microSD、SDIO、eMMC等不同的规范(如下面图片1所示)。虽然乱花迷人,其本质终究还是一样的,丝毫未变,这就是Linux kernel将它们统称为MMC的原因。
MMC、SD、SDIO的技术本质是一样的(使用相同的总线规范,等等),都是从MMC规范演化而来;
MMC强调的是多媒体存储(MM,MultiMedia);
SD强调的是安全和数据保护(S,Secure);
SDIO是从SD演化出来的,强调的是接口(IO,Input/Output),不再关注另一端的具体形态(可以是WIFI设备、Bluetooth设备、GPS等等)。
MMC分别从卡(Card Concept)、总线(Bus Concept)以及控制器(Host Controller)三个方面,定义MMC system的行为。
drivers/mmc/card 存放卡设备相关的驱动,如MMC/SD卡设备等。
drivers/mmc/host 针对不同主机端的SDHC、MMC控制器的驱动。
drivers/mmc/core mmc子系统的核心层,完成了不同协议和规范的实现,为HOST层和设备驱动层提供了接口。
mmc子系统款家图
SD总线通信是基于指令和数据比特流,起始位和停止位结束。SD总线通信有三个元素:
command:由host发送到卡设备,使用cmd线发送
response:从card端发送到host端,是对接收到的cmd的回应,也通过cmd线发送;
data:可以从host到card,也可以从card到host,通过data线传输。
四种用于控制卡设备的指令类型,每个command占48bit
1、broadcast commands(bc),no response 广播类型指令,不需要响应;
2、broadcast commands with response(bcr):需要响应的广播类型指令;
3、addressed(pint-to-point) commands(ac):由HOST发送到指定的卡设备,没有数据的传输;
4、address(point-to-point) data transfercommands(adtc):由HOST发送数据到指定卡设备;
主要的寄存器:OCR、CID、CSD、RCA、SCR:
operation condition register(OCR) 32位的OCR包含卡设备支持的工作电压列表;
card identification number register(CID) 用于卡识别的卡信息,包括制造商ID,产品名等;
relative card address regisger(RCA) 存放在卡识别阶段分配的卡地址,缺省地址为0000h;
SD card configuration register(SCR) 配置寄存器,用于配置SD memory的特殊功能;
所有的response都经过cmd线发送给HOST端,R4和R5响应是SDIO中特有的
1、R1(normal response command) 用来响应常用指令;
2、R2(CID/CSD register) 用来响应CMD2、CMD10、CMD9,并把CID和CSD寄存器作为响应数据;
3、R3(OCR register) 响应ACMD41指令,并把OCR寄存器作为响应数据;
4、R4(CMD5) 响应CMD5,把OCR寄存器作为响应数据
5、R5(CMD52) CMD52是一个读写寄存器的指令,R5用于返回寄存器数据;
6、R6(pulished RCA response) 分配卡地址的响应;
7、R7(card interface condition) 响应CMD8,返回卡支持的电压信息;
此处初始化流程以emmc设备为例。
Linux内核版本:4.9.37
提示:这里对文章进行总结: