eMMC驱动分析

本文详细介绍了基于ATMEL-sama5d3芯片与Linux-3.6.9内核的eMMC驱动分析,涵盖SD卡系列简介、MMC/SD通信协议、驱动层次结构以及Linux内核中的面向对象思想。文章通过分析驱动流程,揭示了从控制器初始化到块设备probe的步骤,包括platform_driver_register、driver_register、mmc_add_host等关键函数的调用过程。此外,还探讨了插卡支持、读写操作以及修改传输速度的问题,并记录了在更改过程中遇到的错误和解决方法。
摘要由CSDN通过智能技术生成

作者:Aningsk ,本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。 

 

基于ATMEL-sama5d3芯片与Linux-3.6.9内核。

 

 

SD卡系列简介

这些都是网上找出来的,权当作为开场白了。

 

MMC卡全称Multi Media Card,由西门子公司和SanDisk公司1997年推出的多媒体记忆卡标准。MMC卡尺寸为32mm x24mm x 1.4mm,它将存贮单元和控制器一同做到了卡上,智能的控制器使得MMC保证兼容性和灵活性。MMC卡具有MMC和SPI两种工作模式,MMC模式是默认工作模式,具有MMC的全部特性。而SPI模式则是MMC协议的一个子集,主要用于低速系统。

 

SD卡全称Secure Digital Memory Card,由松下、东芝和SanDisk公司于1999年8月共同开发的新一代记忆卡标准,已完全兼容MMC标准。SD卡比MMC卡多了一个进行数据著作权保护的暗号认证功能,读写速度比MMC卡快4倍。尺寸为32mm x 24mm x2.1mm,长宽和MMC卡一样,只是比MMC卡厚了0.7mm,以容纳更大容量的存贮单元。SD卡与MMC卡保持向上兼容,也就是说,MMC卡可以被新的设有SD卡插槽的设备存取,但是SD卡却不可以被设有MMC插槽的设备存取。

 

SDIO全称Secure Digital Input and Output Card,SDIO是在SD标准上定义了一种外设接口,它使用SD的I/O接口来连接外围设备,并通过SD上的I/O数据接口与这些外围设备传输数据。现在已经有很多手持设备支持SDIO功能,而且许多SDIO外设也被开发出来,目前常见的SDIO外设有:WIFI Card、GPS Card、 Bluetooth Card等等。

 

eMMC全称Embedded Multi MediaCard,是MMC协会所制定的内嵌式存储器标准规格,主要应用于智能手机和移动嵌入式产品等。eMMC是一种嵌入式非易失性存储系统,由闪存和闪存控制器两部分组成,它的一个明显优势是在封装中集成了一个闪存控制器,它采用JEDEC标准BGA封装,并采用统一闪存接口管理闪存。eMMC结构由一个嵌入式存储解决方案组成,带有MMC接口、快闪存储设备及主控制器,所有这些由一个小型BGA封装。由于采用标准封装,eMMC也很容易升级,并不用改变硬件结构。

 

 

 

MMC/SD通信协议

卡的状态与模式:

工作条件检测:

发送CMD0(reset);

发送CMD8,用于取得SD卡支持的工作电压。

在版本2.0中,发送ACMD41,必须先发送CMD8,有应答则是高容量SD卡。

ACMD41是给卡的控制器一个识别卡是否能在给定电压下工作的机制。

 

卡根据CMD8的参数检测控制器的电压,如果电压不可以,卡处于Idle状态;如果电压可以,发送回执(check voltage, check pattern),控制器分析回传的CMD8参数校验是否可以在给定的电压下工作。

 

在ACMD41之后,控制器与卡之间的工作电压将确定。

 

初始化:

开始于收到ACMD41。

响应CMD8的卡为SDHC卡,ACMD41的HCS部分为1;不响应CMD8的则是普通SD卡;

作为ACMD41的回应,SDHC卡会带有CCS=1。

 

控制器发送CMD2,处于Ready状态的卡,发送自己的CID作为响应,然后卡进入Identification状态。

 

控制器发送CMD3,SD卡会发送一个相对地址(RCA)作为响应。卡进入等待状态。

 

数据传输模式:

CMD7:选择某个卡进入Transfer状态。

CMD9:获取卡的CSD(card specific data),包括块长度、卡的容量等。

CMD12:停止命令。

CMD17:块读命令。

CMD18:多块读命令。

ACMD51:发送scr(SD Configuration Register)

CMD24:块写命令。

CMD25:多块写命令。

CMD32:擦除的起始地址。

CMD33:擦除的截止地址。

CMD38:擦除命令。

 

仅仅看SPEC上的通信协议可能略有枯燥,结合代码就比较好理解了。关于SD卡的初始化过程参见:http://www.cnblogs.com/fengeryi/p/3469782.html

这个博客详细描述了SD卡的初始化(mmc_sd_init_card())。MMC卡的初始化是mmc_init_card(),大致过程相似,比SD卡的函数长不少,但实际的代码干的事情貌似比SD的那些简单一些。这里我们用到的是MMC卡,它的初始化后面会涉及到的。

 

 

关于eMMC的原理图部分:

现在的内核使用设备树文件,来描述ARM平台上的相关硬件设备资源。对于设备树(Device Tree)这个东西资料还不是很多,网上有宋宝华写的有关设备树的文章,挺值得参考的。

按我自己的理解,设备树文件就是用一种类似于C语言的东西来描述具体平台相关的硬件资源。这些文件使用特定的编译器编译为.dtb文件,在uboot加载内核的时候,将dtb文件提供给内核,内核便获知了具体的硬件设置;而不再是以前那样,各种各样的硬件信息统统编译进内核。

 

所使用的硬件资源,来自于设备树文件sama5d3.dtsi(arch/arm/boot/dts/sama5d3.dtsi)

与MMC设置有关的寄存器地址:0xf0000000;长度0x600。中断号21,触发模式:4(上升沿触发)。中断优先级为0 。拥有的DMA资源是dma0,寄存器的配置为0x10002200 。

关于设备树文件含义的一些说明,在源码目录中的Document/devicetree/bindings/下有TXT类型的描述文档。

 

 

 

MMC驱动的层次结构

 

CARD层    具体的块设备驱动

CORE层    为card层提供操作接口,为host层注册提供机制

HOST层    MMC/SD/SDIO的控制器驱动层

 

我觉得之所以将整个的驱动分为三层,是为了驱动能够更好的移植到其他的硬件平台上去。CARD层是通用的MMC块设备驱动,这些代码只要是Linux都可以用的;而HOST层里的代码则是与具体平台有关的,进去看文件与函数的名字就可以猜到——我们这里HOST层中的函数常常是"atmci"开头,意思是ATMEL的媒体控制接口,这是因为我们的平台是ATMEL的ARM芯片;而CORE层,则是提供了MMC/SD的核心机制,并且为CARD层屏蔽了HOST层中具体硬件的差异。基于这些有但不完全的原因,MMC/SD的驱动自然而然的分出了三层,也就是drivers/mmc下的三个文件夹。

 

 

Linux内核中的面向对象的思想与实现

在个人学习Linux驱动的过程中,感觉如果只是按照一个一个函数的调用,不断的来回跳,即便是能看懂单个函数的意思,对于整个体系依然是云里雾里,不知内核写了神马东西。若是按照面向对象的思想去理解这些代码,我发现内核的东西就比较容易懂了。

内核虽然是用面向过程的C语言写出来的,但处处体现着面向对象的思想,甚至可以称为一种编程哲学(PS.那些把内核写出来的牛人们,实在太牛了)。Linux不仅仅把设备全部抽象为文件,这种宏观的抽象对象的方法在内核代码里也是比比皆是。个人感觉看代码是在自己脑子里把程序要处理的东西,都抽象为一件件具体的物品,对理解内核代码的来龙去脉,很有帮助。

 

Linux内核中用面向过程的C语言实现了面向对象的程序架构。一种面向对象的语言,拥有三方面的特性:封装、继承、多态。Linux内核用C语言的基本特性实现了这三种面向对

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值