趣谈设备模型下Linux内核修炼

设备模型拍得再玄幻,它也只是个模型,必须得落实在具体的子系统,否则就只能抱着个最佳技术奖空遗恨。既然前面已经以USB子系统的实现分析示例了分析内核源码应该如何入手,那么这里就仍然以USB子系统为例,看看设备模型是如何软着陆的。

内核中USB子系统的结构

我们已经知道了USB子系统的代码都位于drivers/usb目录下面,也认识了一个很重要的目录——core子目录。现在,我们再来看一个很重要的模块——usbcore。你可以使用“lsmod”命令看一下,在显示的结果里能够找到有一个模块叫做usbcore。

localhost:/usr/src/linux-2.6.23/drivers/usb/core#lsmodModuleSizeUsedbyaf_packetrawnfslockdnfsnfs_aclnfssunrpcnfs,lockd,nfs_aclipvbuttonbatteryacapparmoraamatch_pcreapparmorloopusbhiddm_modide_cdhw_randomehci_hcdcdromide_cduhci_hcdshpchpbnxusbcoreusbhid,ehci_hcd,uhci_hcdepci_hotplugshpchpreiserfseddfan??

找到了usbcore那一行吗?core就是核心,基本上你要在你的电脑里用USB设备,那么两个模块是必须的:一个是usbcore,这就是核心模块;另一个是主机控制器的驱动程序,比如这里usbcore那一行我们看到的ehci_hcd和uhci_hcd,你的USB设备要工作,合适的USB主机控制器模块也是必不可少的。

usbcore负责实现一些核心的功能,为别的设备驱动程序提供服务,提供一个用于访问和控制USB硬件的接口,而不用去考虑系统当前存在哪种主机控制器。至于core、主机控制器和USB驱动三者之间的关系,如下图所示。USB驱动和主机控制器就像core的两个保镖,协议里也说了,主机控制器的驱动(HCD)必须位于USB软件的最下一层。HCD提供主机控制器硬件的抽象,隐藏硬件的细节,在主机控制器之下是物理的USB及所有与之连接的USB设备。而HCD只有一个客户,对一个人负责,就是usbcore。usbcore将用户的请求映射到相关的HCD,用户不能直接访问HCD。

core为咱们完成了大部分的工作,因此咱们写USB驱动的时候,只能调用core的接口,core会将咱们的请求发送给相应的HCD。

USB子系统与设备模型

关于设备模型,最主要的问题就是,bus、device、driver是如何建立联系的?换言之,这三个数据结构中的指针是如何被赋值的?绝对不可能发生的事情是,一旦为一条总线申请了一个structbus_type的数据结构之后,它就知道它的devices链表和drivers链表会包含哪些东西,这些东西一定不会是先天就有的,只能是后天填进来的。

具体到USB子系统,完成这个工作的就是USBcore。USBcore的代码会进行整个USB系统的初始化,比如申请structbus_typeusb_bus_type,然后会扫描USB总线,看线上连接了哪些USB设备,或者说RootHub上连了哪些USB设备,比如说连了一个USB键盘,那么就为它准备一个structdevice,根据它的实际情况,为这个structdevice赋值,并插入devices链表中来。

又比如RootHub上连了一个普通的Hub,那么除了要为这个Hub本身准备一个structdevice以外,还得继续扫描看这个Hub上是否又连了别的设备,有的话继续重复之前的事情,这样一直进行下去,直到完成整个扫描,最终就把usb_bus_type中的devices链表给建立了起来。

那么drivers链表呢?这个就不用bus方面主动了,而该由每一个driver本身去bus上面登记,或者说挂牌。具体到USB子系统,每一个USB设备的驱动程序都会对应一个structusb_driver结构,其中有一个structdevice_driverdriver成员,USBcore为每一个设备驱动准备了一个函数,让它把自己的这个structdevice_driverdriver插入到usb_bus_type中的drivers链表中去。而这个函数正是我们此前看到的usb_register。而与之对应的usb_deregister所从事的正是与之相反的工作,把这个结构体从drivers链表中删除。

而structbus_type结构的match函数在USB子系统里就是usb_device_match函数,它充当了一个红娘的角色,在USB总线的USB设备和USB驱动之间牵线搭桥,类似于交大BBS上的鹊桥版,虽然它们上面的条件都琳琅满目的,但明显这里match的条件不是那么的苛刻,要更为实际些。

可以说,USBcore的确是用心良苦,为每一个USB设备驱动做足了功课,正因为如此,作为一个实际的USB设备驱动,它在初始化阶段所要做的事情就很少,很简单了,直接调用usb_register即可。事实上,没有人是理所当然应该为你做什么的,但USBcore这么做了。所以每一个写USB设备驱动的人应该铭记,USB设备驱动绝不是一个人在工作,在他身后,是USBcore所提供的默默无闻又不可或缺的支持。









































长沙白癜风专科医院
白癜风正规医院



转载请注明:http://www.jiaju1314.com/bcxx/bcxx/11390.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了