linux设备驱动模型一上层容器之关系

linux的上层容器主要有bus,device,driver,这三者是个什么关系呢:

bus:
  总线作为主机和外设的连接通道,有些总线是比较规范的,形成了很多协议。如PCI,USB,1394,IIC等。任何设备都可以选择合适的总线连接到主机。当然主机也可能就是CPU本身。内存也是通过BUS连接到主机的,可内存使用的总线不是外设总线,因此和内存使用相同类型的总线的设备,谈及BUS比较含糊。
  一块网卡在嵌入式开发中,直接通过内存总线接入到CPU。我们在写网卡驱动时,要给该BUS定义就麻烦了。
driver:
  驱动程序是在CPU运行时,提供操作的软件接口。所有的设备必须有与之配套驱动程序才能正常工作。一个驱动程序可以驱动多个类似或者完全不同的设备。
device:
  设备就是连接在总线上的物理实体。设备是有功能之分的。具有相同功能的设备被归到一个类(CLASS中)。如音频设备(和声音相关的都算),输入设备(鼠标,键盘,游戏杆等)。。。。
  从宏观考虑,任何设备必须要连接到主机才能发挥其作用。一个鼠标离开了电脑主机就不再是鼠标了。提到了连接就必然出现总线BUS。任何设备要正常运行必须有软件支持,所有的设备必须有DRIVER。设备的目的就是完成功能,根据功能的分类,该设备必然属于某个CLASS。
  1.三者的定义在 include/linux/device.h里。
  2.总线中的那两条链表是怎么形成:
  这要求每次出现一个设备就要向总线汇报,或者说注册,每次出现一个驱动,也要向总线汇报,或者说注册。比如系统初始化的时候,会扫描连接了哪些设备,并为每一个设备建立起一个struct device的变量,每一次有一个驱动程序,就要准备一个struct device_driver结构的变量。把这些变量统统加入相应的链表,device 插入devices 链表,driver插入drivers链表。这样通过总线就能找到每一个设备,每一个驱动.然而,假如计算机里只有设备却没有对应的驱动,那么设备无法工作。反过来,倘若只有驱动却没有设备,驱动也起不了任何作用。
  3.总线上的两条链表已经有了,链表里的device和driver又是如何联系
  每一个要用的device在计算机启动之前就已经插好了,插放在它应该在的位置上,然后计算机启动,然后操作系统开始初始化,总线开始扫描设备,每找到一个设备,就为其申请一个struct device结构,并且挂入总线中的devices链表中来;
  然后每一个驱动程序开始初始化,开始注册其struct device_driver结构,然后它去总线的devices链表中去寻找(遍历),去寻找每一个还没有绑定driver的设备,即struct device中的struct device_driver指针仍为空的设备,然后它会去观察这种设备的特征,看是否是他所支持的设备,如果是,那么调用一个叫做 device_bind_driver的函数。换句话说,把struct device中的struct device_driver driver指向这个driver,而struct device_driver driver把struct device加入他的那张struct klist klist_devices链表中来。就这样,bus、device和driver,这三者之间或者说他们中的两两之间,就给联系上了
  4.热插拔:
  device可以在计算机启动以后在插入或者拔出计算机了。因此,很难再说是先有 device还是先有driver了。因为都有可能。device可以在任何时刻出现,而driver 也可以在任何时刻被加载,所以,出现的情况就是,每当一个struct device诞生,它就会去bus的drivers链表中寻找自己的另一半,反之,每当一个一个struct device_driver诞生,它就去bus的devices链表中寻找它的那些设备。如果找到了合适的,那么ok,和之前那种情况一下,调用 device_bind_driver绑定好.

总结如下:

驱动核心可以注册多种类型的总线。
每种总线下面可以挂载许多设备。(通过kset devices)
每种总线下可以用很多设备驱动。(通过包含一个kset drivers)}
每个驱动可以处理一组设备。所有的设备都挂载到总线上,当加载驱动时,驱动就支总线上找到自己对应的设备。或者先把驱动加载上,来了一个设备就去总线找驱动。

下面举个例子,SCSI硬盘和IDE硬盘的对比。
SCSI硬盘是个存储设备(CLASS),使用的是SCSI总线连接到主机,要使用硬盘(DISK)驱动程序。
IDE硬盘也是个存储设备(CLASS),使用IDE总线连接到主机,同样使用硬盘(DISK)驱动程序。
同一个类下面的设备高层驱动通用,同一个总线上的设备,通信协议部分驱动通用。
再举个例子,PCI总线上,可以接很多设备,如两个IDE控制器,两个USB控制器。该PCI总线上将有两个DRIVER,四个DEVICE。如果在IDE控制器上分别接入了一个硬盘和一个光驱。总线上将多两个DRIVER去驱动这两个设备。我们需要在硬盘和光盘上使用文件系统,那么就要多出一个DISK驱动程序,工作于前面的那两个驱动程序之上。为什么一个DISK驱动就够了呢?硬盘和光盘同属于存储设备类(CLASS),因此当抽象到高层后,代码的复用就比较强了。
 
设备DEVICE             驱动程序 DRIVER                     总线 BUS             类CLASS   
IDE控制器              IDE芯片驱动程序                     PCI                       无
USB控制器                USB芯片驱动程序                    PCI                        无
IDE硬盘                     硬盘驱动程序                           IDE                        存储设备
IDE光驱                     光驱驱动程序                           IDE                        存储设备
SCSI控制器               SCSI芯片驱动程序                    无                           无
SCSI硬盘                    硬盘驱动程序                          SCSI                       存储设备
  主机就好比各个城市。  
  BUS好比公路,铁路,航空。
  DEVICE好比汽车,火车,飞机。
  CLASS好比客运,货运。
  DRIVER好比能源,如汽油,电力,天然气等。
 
         从北京到西安的BUS很多,根据需要选取。50年代技术落后多选铁路,现在最好是航空。每种BUS上的设备都是特定的,没有人把火车开到公路上,也就没人把键盘接到SCSI总线上一样。运人就要坐客车,运货就要坐货车,物以类聚,人以群分。人怎么能用货车运呢?汽车也好火车也罢,都可以使用电力作为牵引动力。一个驱动程序道理上可以驱动所有设备,通常还是专设备单独驱动。就象没人把航空煤油放到汽车里用。离开DRIVER,所有的DEVICE都无法正常工作。
       再顺便提一下那些BUS为无的设备。就好比某些人从北京徒步走到了西安,针对这种情况就比较特殊。可以遇到,比较罕见,处理起来就因人而异了。你可以从北京到郑州来到西安,可以沿着铁路走,可以沿着公路走,总之是不好统一了。唯一的一点就是你是用两条腿走的,要么运人要么运货,CLASS还是可以确定的。

你可能感兴趣的:(linux设备驱动模型一上层容器之关系)