基于高通平台进行的总线、设备、驱动三者的关系简析

来源:互联网 发布:linux进程组 编辑:程序博客网 时间:2024/06/06 10:52

     在计算机中,总线是计算机中各个部件之间进行数据通信的通道。在Linux内核的设备驱动模型中,总线的概念有所不同,不仅有物理上真实存在的总线,如I2C总线和USB总线等,还有并不存在物理器件的虚拟总线,例如最具代表性的platform总线。操作系统通过设备驱动程序来管理设备(主要包括设备的初始化,设备电源管理,设备与系统其他部分的通信等)。在Linux内核代码中,各个总线(总线本身也是一种设备)用于管理挂载各自总线上的设备以及各个设备对应的驱动,例如USB总线系统驱动管理所有USB设备和USB设备驱动;这里所说的“管理”的主要工作是当有新设备接入系统时,为这个设备找到合适的驱动并绑定,或者当新驱动注册到系统时,为该驱动找到它能管理的所有设备(一个驱动可能对应多个设备)并绑定。现在的许多芯片除了包含CPU之外,还集成了各种功能模块,俗称有SoC(System on Chip)。这类的芯片内部的一些外设与CPU的物理连接并没有经过总线,因而这类设备和驱动并没有总线来管理;为了解决统一管理,出现了platform总线,这个总线在物理上并不存在,是虚拟的,仅仅是为了统一管理那些物理连接没有经过总线的设备和它们的驱动。

        下图为总线、设备和驱动三者的关联在代码上的体现。总线的结构体类型的bus_type,它包含一个subsys_private的结构体成员。通过subsys_private这个结构体成员,总线维护两个链表:一个是klist_devices,记录所有挂载在该总线上的设备,另一个是klist_drivers,记录所有挂载在该总线上的驱动。同时,设备驱动程序自身还维护一个链表klist_devices,记录它所管理的所有设备。


 


         总线驱动为新添加的设备绑定一个匹配的驱动的主要过程大致分为三个步骤:(1)将设备添加到总线维护的klist_devices链表中;(2)遍历总线维护的klist_drivers链表直到找到匹配的驱动;(3)如果找到匹配的驱动则执行probe函数。总线为新注册的驱动寻找对应的设备时,操作过程一致,只是在执行代码上有些许差别,详见下图:

 
 
 
         上文讲了总线驱动会为设备或驱动寻找与他们匹配的“另一半”,那总线驱动又是如何判断设备和驱动是否匹配的呢?这个过程由一个match函数实现,不同的总线驱动定义不同的match函数,因而可以有不同的匹配方式,但在Linux内核的现有代码中基本是以下三种方式:
        (1) 各类设备定义的xxx_device和device_driver结构体个有一个char *name成员来代表设备和驱动的名字,总线定义的match函数比较驱动和设备的名字(字符串比较),当一致时,则认为设备和驱动是匹配的,这是最基本的方法;
        (2) 驱动程序中定义一个id表"id_table"(数组),在这个id表中保存该驱动程序所负责的说有设备的id,总线的match函数用这个id表中的每个元素与来自设备的某种属性做比较(不同总线比较不同属性,例如i2c设备比较client设备的name属性而USB比较设备的idVendor和idProduct),符合要求时则认为设备和驱动匹配;
        (3) 第三种方法是使用设备树的情况,驱动程序会填充device_driver->of_match_table成员,然后match函数of_match_table与设备的of_node进行对比,符合要求的则认为设备与驱动匹配。这种方法是arm平台上目前的主流。

阅读全文
0 0
原创粉丝点击