设备模型之kobject,kset及其关系

Linux2.6以后的设备驱动,都是在设备模型的基础上构建的,因此,要编写linux下的设备驱动程序,不论是usb设备,pci设备等,都需要了解设备模型。

设备模型的基础结构体主要是kobject,kset这两个结构体:

struct kobject {

   char      * k_name;

   char      name[KOBJ_NAME_LEN];

   struct kref    kref;

   struct list_head  entry;

   struct kobject    * parent;

   struct kset    * kset;

   struct kobj_type  * ktype;

   struct dentry     * dentry;

};

 

struct kset {

   struct subsystem  * subsys;

   struct kobj_type  * ktype;

   struct list_head  list;

   struct kobject    kobj;

   struct kset_hotplug_ops  * hotplug_ops;

};

 

还有一个subsys结构体,但subsys结构体跟kset差不多,就多了一个互斥访问信号量,因此,就不需要列出了,另外还有一个结构体

struct kobj_type {

   void (*release)(struct kobject *);

   struct sysfs_ops  * sysfs_ops;

   struct attribute  ** default_attrs;

 };

用来表示kobject,kset的类型。 

一个kobject结构如下图的kobject 类型部分,而一个kset结构如下图的kset 类型部分,一个kobject加入一个kset,主要是kobject结构体中的相关字段记录了对应的kset信息,①记录了kobject所对应kset,其所指向的是kset所包含的kobject的地址,②记录了kobject所对应的kset的kset指针,③记录了kobject的类型,④记录了kset所有的kobject的链子,这个链子是一个双向链表,每当有一个kobject加入到当前的kset,就会调用list_add_tail()函数,把要加入kset的kobject连入链表的结尾,最终形成一个链表。

当有另外一个kobject要加入当前的kset,其中的①②③步跟第一个加入当前kset的kobject是一样的,即把要加入的kobject的成员设置,使之指向当前的kset对应数据,而④需要把kobject添加到kset的list的尾部,下图表示了kobject b加入到kset A的图示:

当有一个kset,需要加入到当前的kset,其方法也跟一个kobject要加入到当前kset一样,即把要加入的kset中所包含的kobject的成员设置,使这些成员指向对应的kset的对应数据。而当前kset要加入另一个kset,其方式也是跟一个kset加入到当前kset一样,都是设备kset中的kobject,使kobject的成员指向要加入的kset的对应数据即可,下图显示了一个kset B加入到kset A中的图示。

一个简单的kset,kobject关系图如下:



设备驱动基础1:设备模型之总线,驱动,设备

Kobject,kset是设备模型的基本结构体,设备模型使用这两个结构体来完成设备的层次关系,但在实际的设备驱动编写中,我们基本上用不到kobject,kset这些结构体,是因为这些结构体又被嵌入到更大的结构体中,原因在于kobject,kset结构体只能表征设备的层次关系,但是一个设备的驱动,并不是简单的一个层次关系而已,因此,必需要把kobject,kset结构体嵌入到更大的结构体中,使用kobject,kset来表征层次关系,用其他的成员表示设备驱动的具体功能。

在设备模型中,我们将看到,设备驱动主要是由总线,驱动程序,设备三个部分构成,通过这三个标准部件,把各种纷繁杂乱的设备归结过来,达到简化设备驱动编写的目的,也即我们编写的设备驱动,其实也只是这三部分中的一个很小的部分的。

 

我们编写的设备驱动程序,一定是先属于一个总线的驱动,比如属于USB总线,或者属于PCI总线,或者属于I2C总线,等等,因为我们编写的设备驱动,在注册,安装到系统时,系统会先检查驱动是属于哪个总线的(设备驱动编写时已经定义好),会把驱动加入到对应的总线的kset中,即把当前设备驱动的kobject加入到对应总线的kset中,形成层次关联。而当系统检测到有设备存在(硬件),也会先判断设备是属于哪个总线的(硬件连接),然后遍历当前总线下的所有设备驱动程序,通过所属总线的探测函数,查找是否有设备驱动程序匹配可以驱动当前的设备(一般是通过获得设备的PID,VID,跟驱动程序的PID,VID比较,看是否匹配而定),如果有驱动程序可以驱动设备,则把当前设备也加入到所属总线的kset中,如果没有可驱动设备的驱动程序,则只能在总线的设备链表中存在,而如果设备都无法通过总线的匹配,则也没有办法存在于总线的设备链表中。由于一条总线要管理总线上的所有驱动,同时要管理总线上的有所设备,则需要再把所有设备和所有驱动都分开,分别设立一个设备kset和一个设备驱动kset,用于管理所有的设备和设备驱动,如此,则总线kset实际上包含了两个kset(设备kset,设备驱动kset),设备kset又包含了所有的当前总线的设备的kobject,设备驱动kset包含了所有的当前总线的设备驱动的kobject;而所有的总线,又形成了bus的kset,归结起来就形成下图的层次关系:

每个设备,都被挂接到不同的总线上,当设备挂接到对应的总线上后,其所对应的总线类型就确定了,而设备在挂接到总线上时,总线先要扫描设备,看看设备是否适合总线的要求,如果适合了,那接着就要扫描整个总线上的设备驱动链表,查找是否有驱动程序可以管理设备,如果找到,则把设备结构体中的相应指针成员指向对应的驱动程序,如果暂时没有找到对应的设备驱动程序,则设备结构体中的指向驱动程序的指针暂时为空,表示还没有设备驱动,还在总线的设备队列中等待;而如果设备不能通过总线的检查,即不会出现在总线的设备列表上,自然不会去扫描设备驱动链表,查找匹配的驱动了。

而每个设备驱动程序,都是被安装到对应的总线上的,不论是手动安装,还是自动安装,所谓安装,就是把驱动程序挂载到对应总线的驱动链表中,而挂载到对应的总线驱动链表,首先要满足总线的匹配要求,只有适合了要求,才能挂载到总线的驱动链表,也只有到达这个步骤,系统才会扫描整个总线的设备链表,来查找是否有设备需要此驱动来管理,如果找到这个设备,则驱动程序中的设备管理链表,会记录这个设备的地址,从而达到管理设备的目的。

经过上述的设备插入,或者驱动安装,系统就会出现只有设备,而没有设备驱动程序的情况,也会出现,只有设备驱动程序,没有对应的设备的情况,此时,设备或者设备驱动程序,就会暂时在各自的队列里等待,一旦有驱动程序安装,或新的设备插入,就都会自动的去扫描对应的链表,来检测是否有配对的可能。

综合上述三者的关系,如图:

 

Linux设备模型 之 总线类型 - bus_typebus_type

相关数据结构:

struct bus_type {
 char   *name;

 structsubsystem subsys;
 structkset  drivers;
 structkset  devices;

 struct bus_attribute *bus_attrs;
 struct device_attribute *dev_attrs;
 struct driver_attribute *drv_attrs;

 int  (*match)(structdevice * dev, struct device_driver * drv);
 int  (*hotplug)(struct device *dev, char **envp,
       int num_envp, char *buffer, int buffer_size);
 int  (*suspend)(structdevice * dev, pm_message_t state);
 int  (*resume)(structdevice * dev);
};


内核所支持的每一种总线类型都由一个bus_type对象表示。
bus_type中内嵌了一个subsystem - subsys。
系统中的bus_subsys子系统将所有的bus_type中的subsys集合在一起。
bus_subsys对应sysfs中的/sys/bus目录.

另外,bus_type中有两个内嵌的kset对象:devices 和drivers。分别表示该bus上的设备和驱动。

                                                          
                            
                                                           
                                                           
                                                           
 /------------------------>      bus_type      <-------------------------\
 |                        +--------------------+                         |
 |                        |                   |                         |
 |                        |   name           |                         |
 |                        +--------------------+                         |
 |                        |           kset   |                         |
 |                        |        +--------+|                         |
 |                        |        | subsys ||                         |
 |                        | drivers +--------+|                         |
 |                        |        | kobj   ||                         |
 |                        |        +--------+|                         |
 |                        |        | list   ||                         |
 |                        |        +--------+|                         |
 |                        |        |       ||                         |
 |                        +--------------------+                         |
 |                        |           kset   |                         |
 |                        |        +--------+|                         |
 |                        |        | subsys ||                         |
 |                        | devices +--------+|                         |
 |                        |        | kobj   ||                         |
 |                        |        +--------+|                         |
  | /------------------------------->|list  |<----------------------\   |
  | |                     |        +--------+|                    |    |
  | |                     |        |       ||                    |    |
  | |                     +--------------------+                    |    |
  | |                     |                   |                    |    |
  | |                     |  subsys          |                    |    |
  | |                     |                   |                    |    |
  | |                     +--------------------+                    |    |
  | |                     |                   |                    |    |
  | |                     |                   |                    |    |
  | |                     |                   |                    |    |
  | |                                                                |    |
  | |                                                                |    |
  | |      device                                     device       |    |
  | |  +-------------+                            +-------------+  |    |
  | |  |   node    |                            |   node    |  |    |
  | |  +-------------+                            +-------------+  |    |
  | \-->| bus_list  |<-------  ...... ---------->| bus_list  |<--/   |
 |     +-------------+                            +-------------+       |
 |     | driver_list|                            | driver_list|       |
 |     +-------------+                            +-------------+       |
 |     |  children  |                            |  children  |       |
 |     +-------------+                            +-------------+       |
 |     |  parent   |                            |  parent   |       |
 |     +-------------+                            +-------------+       |
 |     |  kobj     |                            |  kobj     |       |
 |     +-------------+                            +-------------+       |
  \------|  bus      |                            |  bus      |--------/
        +-------------+                            +-------------+   
        |  driver   |                            |  driver   |   
        +-------------+                            +-------------+   
        |            |                            |            |   
                                                                       

 

 

 

 


                                                                             
                                                                             
                                                                             
                                                                             
                                                                             
  /------------------------>      bus_type      <-------------------------\
  |                        +--------------------+                         |
  |                        |                   |                         |
  |                        |   name           |                         |
  |                        +--------------------+                         |
  |                        |           kset   |                         |
  |                        |        +--------+|                         |
  |                        |        | subsys ||                         |
  |                        | drivers +--------+|                         |
  |                        |        | kobj   ||                         |
  |                        |        +--------+|                         |
   | /------------------------------->|list  |<----------------------\   |
   | |                     |        +--------+|                    |    |
   | |                     |        |       ||                    |    |
   | |                     +--------------------+                    |    |
   | |                     |           kset   |                    |    |
   | |                     |        +--------+|                    |    |
   | |                     |        | subsys ||                    |    |
   | |                     | devices +--------+|                    |    |
   | |                     |        | kobj   ||                    |    |
   | |                     |        +--------+|                    |    |
   | |                     |        | list   ||                    |    |
   | |                     |        +--------+|                    |    |
   | |                     |        |       ||                    |    |
   | |                     +--------------------+                    |    |
   | |                     |                   |                    |    |
   | |                     |  subsys          |                    |    |
   | |                     |                   |                    |    |
   | |                     +--------------------+                    |    |
   | |                     |                   |                    |    |
   | |                     |                   |                    |    |
   | |                     |                   |                    |    |
   | |                                                                |    |
   | |                                                                |    |
   | |                                                                |    |
   | |                                                                |    |
   | |         driver                              driver           |    |
   | |   +------------------+                +------------------+   |    |
   | |   |                 |                |                 |   |    |
   | |   |   name         |                |   name         |   |    |
   | |   |                 |                |                 |   |    |
   | |   +------------------+                +------------------+   |    |
   | |   |         kset   |                |         kset   |   |    |
   | |   |      +--------+|                |      +--------+ |   |    |
   | |   |      | parent ||                |      | parent | |   |    |
   | |    |kobj  +--------+|                | kobj  +--------+|   |    |
   | |   |      | kset   ||                |      | kset   ||   |    |
   | |   |      +--------+|                |      +--------+ |   |    |
   | \----------->| entry |<------------------------->|entry |<-----/   |
  |      |      +--------+|                |      +--------+|        |
  |      |      |       ||                |      |       ||        |
  |      +------------------+                +------------------+        |
  |      |                 |                |                 |        |
  \-------|   bus          |                |   bus          |---------/
          |                 |                |                 |  
          +------------------+                +------------------+  
          |                 |                |                 |  
          |                 |                |                 |  
          |                 |                |                 |  
                                                                      
                          
     
函数bus_for_each_dev() 和bus_for_each_drv()分别用于遍历bus上devices和drivers链表中的所有元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值