说明:
1.和下面论相关的帖子:
2.下面讨论所涉及的概念和问题,具有一定普遍性:不止一个人遇到类似的疑惑,对类似的概念不熟悉,
所以专门在此处,一并解释清楚。
3.此讨论,如果后续有更新,会一并添加进来的。
4.抽空会额外整理出更详尽的内容。最终,应该会加到,相关的教程中。
1."旧的mmc检测出sd卡的容量不对·,那现在的mmc里面是含有sd卡的驱动吗?"
参见前面的解释。
再多说几句:
现在的uboot里面,本身已经包含了,很多关于sd/mmc方面的代码。
主要可以分几部分:
(1)sd/mmc等协议方面的,通用的代码
这部分代码,是别人,别的开发者,uboot的开发者,帮你实现好了的
你无需再写,只是(当实现你自己的sd卡驱动的时候,)借用,利用到
即:你的代码,内部在执行sd卡方面的操作,比如读写数据等动作时,内部会调用此部分的,通用代码
(2)不同平台(即不同的开发板)中,实现了自己的sd卡驱动
每个平台(可以理解为开发板)都可能有不同的sd卡(主控芯片),对应的,(如果不同开发板的sk卡主控芯片不同的话)都需要自己实现自己对应的sd卡(主控芯片)的驱动
这部分的代码,对于你来说,对于你想要实现你自己的开发板的sd卡驱动来说,
你是无法直接使用的。
但是,别人实现的sd卡驱动的代码,多多少少,肯定还是有一些,或者说很大程度上的参考价值的。
对于你要实现你自己的sd卡驱动,就是:
搞清楚你的(开发板所用的)sd卡(主控)芯片是啥
找到该芯片对应的数据手册
其中有对应的芯片的寄存器等方面的解释
以及关于如何设置,设置哪些寄存器
才能实现你要的:
初始化sd卡
sd卡的数据读写
高级点的功能,可能还会包括:如何利用DMA实现SD卡的(加速)数据传输(速度),等等
这些内容,都是需要你自己:
先搞懂SD卡的协议本身:
协议中规定的,如何去初始化,如何去实现数据读写
然后再去看上面的硬件(sd卡主控芯片)的数据手册,看看如何操作,实现协议中规定的内容。
对于uboot(包含其他架构,比如Linux下的驱动框架)来说,
让一个设备能功能起来,此处即你想要的,实现sd卡驱动,让sd卡正常工作
本质上,就是实现对应的数据读写
但是在正常工作(数据读写)之前
又肯定会涉及硬件(此处为sd卡芯片)的初始化
所以,让一个设备,正常工作的核心逻辑,都可以归为一句话:
先初始化硬件
然后实现数据的读写
对应此处的sd卡来说就是:
正确初始化sd卡芯片
让sd卡正常数据读写
正确初始化sd卡芯片,意思是:
搞懂sd卡协议中,如何初始化的逻辑和过程,
看懂sd卡芯片的数据手册,如何设置,设置哪些寄存器,实现sd卡的初始化
让sd卡正常数据读写,意思是:
搞懂sd卡协议中,如何规定的,数据如何读写的过程
看懂sd卡芯片的数据手册,搞懂如何操作,需要操作哪些寄存器,才能实现sd卡的数据的收发,即数据读写
而对于,具体的,如何去写对应的代码,此处不详细说明了,这个是写sd卡驱动的人,需要慢慢学习软硬件之后,才能搞懂的。
但是,其总体的逻辑,都和:
读操作的硬件到软件的映射
类似。
去参考参考,然后针对sd卡,去搞懂软硬件,再去一点点写对应驱动,即可。
2.“而且我看了最新版的uboot-2013.07,有sdhci.c、sdhci.h、sdhc_boot.c、sdhc_boot.h,有sd卡驱动的话”
如上所述,此处,所谓的,有sd卡驱动,主要指的是:
对于sd卡,协议级别的,和你单个的(各个板子不同的,sd卡主控芯片,可以说是无关的,那些通用代码,用于实现sd协议的代码
的确是有的,也的确是Uboot就帮你做好的。
但是,要注意的是:
这些,sd卡协议方面的通用的(上层)代码,
不是你原以为的,你的(开发板上的)sd卡(主控)芯片的驱动。
你的(开发板上的)sd卡(主控)芯片的驱动,是要你自己实现的
再说了,Uboot开发者,即使什么芯片驱动,都会写,但是又不知道你是什么芯片,不知道你是哪款芯片
(背景是:市面上,sd卡芯片,作为普通硬件模块之一,也可以说有千千万万的,别人又不知道你用的哪款芯片,具体是什么硬件参数和配置)
所以当然无法实现帮你也都一一实现了。
但是,还是如前所述:
uboot中,已有的,别的开发板的,sd卡芯片的驱动
那还是有很大参考价值的:
看看别人代码是怎么写的
自己搞懂sd卡的协议和你的sd卡芯片的硬件后,可以照葫芦画瓢去写你自己的sd卡驱动
另外,万一别人某个开发板的sd卡芯片和你的一样或类似,那么别人的代码
你基本上可以拿过来(稍作修改,甚至无需大的改动)或许就直接可以用了呢,也未可知。
总之:
需要你自己搞懂:
硬件方面:你自己用的什么sd卡芯片
软件方面:sd协议的细节,尤其是初始化和数据读写
再去看对应芯片的数据手册,再去写你的(uboot中的)sd卡驱动
3.“在uboot下面也需要像在内核中一样对设备和驱动进行注册和匹配吗?”
简答:
不需要。
详解:
先澄清一个概念:
Linux内核中的sd卡芯片驱动,和uboot中的芯片驱动,可以说,完全是两回事
换句话说:
对于同一款sd卡芯片,如果说从uboot到Linux内核,都已经支持
意味着:
(1)uboot中,实现了对应的,该芯片的sd卡驱动
uboot中,如前所述,虽然也是有共同代码
但是整体上来说,对于设备的操作,都是相对比较直接的,甚至说粗暴的
没有太多的,软件层面的多个层次的架构
(2)内核中,实现了对应的,该芯片的sd卡驱动
对应的,linux内核中,为了实现支持更多类型的设备
都是做了更多的,更好的,更复杂的,
各种层面的,层次的,架构
且针对不同类型的设备,有对应的不同的架构
比如我知道的一个,MTD类型的设备,就是一个很大的软件层
其他,又分很多种具体类型的硬件设备的支持
比如nor flash,nand flash等等。
而对应的sd卡的话,是属于另外的,和硬盘等设备,等价的,块设备类型中
这类块设备,也有对应的自己的层次划分
而对于你要实现sd卡驱动,意味着:
除了对于sd卡协议的初始化,数据读写的逻辑清楚了之外
还要去搞懂,对于这些逻辑过程中
尤其是通用的过程,Linux内核的(此处的块设备的)框架,架构中,
已经帮你实现了哪些
剩下的,还需要你:
实现哪些具体的,和你的sd卡硬件相关的,初始化部分,数据读写部分
但是需要注意的是:
虽然,从逻辑上,
uboot,和linux内核,都是有点类似:
都算是可以分为:
系统(uboot或linux)都定义了自己的一套框架,帮你实现了,一般都是协议级别的,通用的代码
而和硬件相关的,特定的代码需要你实现
但是:
Uboot和Linux内核的:
(1)框架
(2)实现的通用的代码
都是完全不同的,根本不是一个数量级的,不是一个复杂度的。
如果说uboot的,算是大事化了型的,简化型的,已经把框架弄得足够简单了,
但是对于普通开发者来说,其复杂度,估计也算得上3~6之间了,即也需要花点精力,才能搞懂的
对此,Linux所定义,所规划,出来的框架,那绝对算得上10(甚至更高)了。
有些子系统(比如我之前接触过的声卡方面的alsa子系统),其复杂度更高,
即,单独对于这些子系统,你想要花精力搞懂,都不是个容易的事情
不近需要大量的相关知识背景,相关的软硬件基础知识,还需要针对Linux中的该框架本身,需要花很多精力,慢慢看代码,
最好是动手去实践,最后才能算是一点点,搞透彻的,算是搞懂了的
简言之:
(1)uboot中,框架相对简单,实现了基本的通用的协议级别的代码=》剩下只需要你,看懂该框架,搞懂框架帮你做了哪些事情,自己去实现剩下的功能,即和硬件相关的操作,即可实现,所谓的,某某硬件驱动实现完成了,支持某某硬件了;
(2)而对于Linux来说,框架本身就很复杂,当然也实现了,或许更多,或者说是和uboot相比,相同级别的,协议方面的通用代码=》你所要做的,往往是在真正写这些代码之外,需要真正搞懂linux的复制的各种软件架构,各种层次,各种框架,各种设计,搞懂后,才能"下笔",才能去写,和uboot中类似的工作,即写写和硬件相关的操作,但是也要注意的是,由于框架不同,接口不同,环境不同,代码方面,出了要操作的寄存器的和要写入的值,没太大变化之外,写出来的代码,也算是差距很大,完全是两套不同体系下的代码了。
回到此处的sd卡驱动: "在uboot下面也需要像在内核中一样对设备和驱动进行注册和匹配吗?”" 答案就是: 根本不需要。 因为,uboot和linux的架构完全不同,框架完全不同。 uboot中的,更加简单,更加直接。 搞懂如何操作寄存器,基本上,任务算是完成了一半了。 剩下就是搞懂如何加对应的代码,加到哪个文件中,加到哪些(uboot中的sd卡相关的api)函数中去,就差不多了。