1、裸机中本身是没有驱动概念的。
狭义上的驱动的概念是操作系统中用来具体操控硬件的那部分代码叫驱动。
广义上讲,只要是操控硬件的都算是驱动。
2、裸机程序中是直接操控硬件的,但是在操作系统中我们必须通过驱动操控硬件。
(1)这两个有什么区别呢?本质区别就是分层的问题
3、uboot的虚拟地址对硬件操作的影响
(1)操作系统(linux)下,MMU肯定是开启的。也就是说Linux驱动中肯定使用的都是虚拟地址,而裸机程序中肯定不会开MMU。
(2)在操作系统下只有虚拟地址可以用,物理地址是不可以用的。所以一提到驱动,肯定是和虚拟地址有关的
(3)以前的uboot是不开启MMU的,但是现在的UBOOT会开启MMU,查uboot的虚拟地址映射表,知道物理地址0X30000000-0X3FFFFFFF映射到了0XC0000000-0XCFFFFFFF这个范围,其他的部分都是原样的。因为驱动是操控硬件的,操控硬件寄存器的,所以驱动就需要考虑虚拟地址到物理地址。但是在我们的S5PV210中SFR都在0XEXXXXXXX地址的空间,所以驱动就不需要考虑虚拟地址了
4、uboot中借用(移植)了Linux驱动。
(1)Linux驱动本身做了模块化的设计,Linux驱动和Linux内核不是强耦合的(两者很黏的在一起),所以这是Linux驱动可以被uboot移植的关键。
10、1、inand/SD驱动解析1
1、从start_armboot开始
(1)驱动的整体是很庞大的,涉及到了很多个文件夹下的很多文件,函数更多,所以要知道从哪里开始入手
2、mmc_initialize
(1)这个函数在uboot/deviers/mmc/mmc.c中
(2)这个函数来初始化开发板的MMC系统的,初始化的部分包括:初始化SoC中MMC控制器(MMC系统时钟的初始化、SFR)、SoC里MMU相关的GPIO的初始化、SD/iNand芯片的初始化。(SD卡本身内部有一个cpu,类似于51单片机,本身就有一些内存的读写,我们主机SOC只需要通过MMC控制器向SD卡发一些时序和指令)
(3)mmc_devices链表,用来记录所有已注册的MMC(SD/INAND)设备。所以当我们系统中多了一个SD/INADN设备时,系统驱动就会想mmc_devices中插入一个节点,代表插入了一个这个设备
3、cpu_mmc_init
(1)setup_hsmmc_clock
初始化SOC中MMC控制器时钟
(2)setup_hsmmc_cfg_gpio
配置SOC里MMC控制器相关GPIO的。
10、2、inand/SD驱动解析2
1、smdk_s3c_hsmmc_init
2、s3c_hsmmc_initialize,这个函数在uboot/drivers/mmc/s3c_hsmmc.c中
(1)struct mmc *mmc;
struct mmc设备驱动,就是表示一个MMC卡的所有信息等等,就是一个类,这个类就是mmc类,sd卡类,具体的每一个SD卡就是这个类的每一个实例
(2)这个函数的作用就是,定义并且实例化一个MMC类的对象。然后填充对象里面的各个成员,最后调用mmc_register来向驱动框架来注册这个mmc设备驱动。就是创建了一个设备(对象)(节点),把这个设备的相关信息添加到这个对象中,完了,用链表插入的方法,插入到这个链表中。这个链表是管理mmc的那个链表数据结构。
(3)我们的x210中,定义了USE_MMC0 和USE_MMC2两个,所以这个s3c_hsmmc_initialize 会被初始化两次,所以会有两个mmc设备被注册到我们的mmc设备驱动上。这两个实例化的对象,会被挂接注册到mmc_devices这个链表管理的mmc设备驱动上。 所以表示当前系统中有两个mmc通道是使用。
(4)find_mmc_device(0);//查找mmc设备驱动中,注册上了0编号的mmc设备没有。
(5)list_for_each(entry, &mmc_devices) //这个宏来遍历这个mmc_devices这个链表,遍历这个链表的所有设备驱动
(6)mmc_init,初始化SD/Inand芯片(通过SOC的MMC控制器向这个mmc设备发时序和指令),通过我们已经注册上的mmc设备(是相对于SOCmmc控制器而言的),发送一些MMC卡相关的CMD命令码,来初始化mmc(SD/INAND)芯片内部的控制器。目的是让sd/inand可以工作
总结:
MMC系统的初始化整个分为两个大部分,一部分是SOC内部的MMC控制器的初始化,这个初始化是在cpu_mmc_init函数中完成的。第二部分是初始化SD/INAND本身芯片内部的控制器,在mmc_init函数中完成的。
第一部分,注册mmc,相对于SOC内部来讲,就是将相应的通道对应的相关配置初始化,让这个通道可以工作了,将这个注册好的挂接到mmc链表管理设备驱动的链表上。
第二部分,通过我们这个mmc链表管理设备驱动的链表上,找到我们相应的工作的mmc驱动。通过soc中的MMC控制器向SD/INAND本身的芯片发送命令码来初始化SD/INAND使得其可以工作。
··代码如这样mmc_send_cmd(host, &cmd, NULL);//用host代表的设备驱动,好使的SOC控制器,向mmc卡发送cmd命令
host就是我们注册上去的那个mmc驱动。
10、3、inand/SD驱动解析3
1、struct mmc
(1)驱动的设计中一个关键的数据结构。这些结构体中包含一些成员和一些函数指针,变量用来记录驱动相关的一些属性,函数指针用来记录驱动相关的操作函数。这些变量和函数指针加起来就构成了驱动。驱动就被抽象为了一个结构体。
(2)一个驱动工作时主要分为这么几个部分:驱动构建(类似用mmc类定义构建一个struct mmc的对象,并且将这个对象进行填充),驱动在运行时调用这些函数指针指向的函数和我们我的这些变量来完成工作。
2、分离思想
(1)分离思想就是说在驱动中将操作方法和数据分离开。在不同的地方存储和管理驱动的操作方法和变量,这样便于移植和维护
(2)数据就一些变量和一些参数,操作方法就是函数。
(3)
3、分层思想
(1)分层思想是指一个整个的驱动分为好个层次。简单理解就是驱动分成很多个源文件,放在和多个文件夹中,如果mmc的驱动设计到drivers/mmc下的两个文件,和cpu/s5pc11x中的还几个文件。