• linux device model简述


    参考:

    1)《LINUX设备驱动程序》第十四章 Linux 设备模型

    2)内核源码2.6.38

    内核初始化的时候会对设备模型作初始化,见init/main.c: start_kernel->rest_init->kernel_init->do_basic_setup->driver_init

    设备模型中重要的数据结构

    include/linux/kobject.h:

    struct kobject

    struct kset

    include/linux/device.h:

    struct device

    struct device_driver

    struct bus_type

    struct class

    1. kobject

    Linux设备驱动模型是一个复杂的数据结构,kobject是构成设备驱动模型的基本元素,它总是嵌入到其他结构中,用于把高级对象连接到设备驱动模型上。kobject类似于面向对象中的基类,devicedevice driverbusclass便是它的派生产物。struct devicestruct device_driverstruct bus_typestruct class中都包含一个类型为struct kobject的成员。

    kobject和虚拟文件系统sysfs有着紧密的联系,一个kobject结构对应sysfs下的一个目录。

    Documentation/kobject.txtDocumentation/filesystems/sysfs.txtkobjectsysfs有详细描述。

    struct kobject定义在include/linux/kobject.h中:

     60 struct kobject {     
    61 const char *name; /*对应sysfs中的目录名*/ 62 struct list_head entry; /*同类kobject组成一个双向链表,entry是该链表中的一个节点*/ 63 struct kobject *parent; /*指向父kobject*/ 64 struct kset *kset; /*指向所属的kset*/ 65 struct kobj_type *ktype; /*struct kobj_type中的struct attribute对应sysfs中的文件*/ 66 struct sysfs_dirent *sd; 67 struct kref kref; 68 unsigned int state_initialized:1; 69 unsigned int state_in_sysfs:1; 70 unsigned int state_add_uevent_sent:1; 71 unsigned int state_remove_uevent_sent:1; 72 unsigned int uevent_suppress:1; 73 };

    内核用kobject结构将各个对象连接起来组成一个分层的结构体系,有两种独立的机制用于连接:parent指针和kset

    kobject结构中的parent成员指向另一个kobject结构,这个结构表示了分层结构中的上一层节点。父kobjectkobjectsysfs中表现为目录与子目录的关系。

    kset是同类kobject的集合。

    struct kset定义在include/linux/kobject.h中:

    159 struct kset { 
    160         struct list_head list; /*kset包含的kobject组成一个链表,list指向该链表头*/
    161         spinlock_t list_lock; 
    162         struct kobject kobj; 
    163         const struct kset_uevent_ops *uevent_ops; 
    164 };

    kset通过链表来管理集合中的kobjectstruct kset中的list成员指向该链表头。

    struct kset结构中亦有一个struct kobject类型的成员,故ksetsysfs中同样对应一个目录。

    大部分情况下,kset集合中koject的父kobject都指向该kset中的kobject成员。

    ksetparentkobject的关系如下图:

    kobject的操作函数定义在lib/kobject.c中。

    2. 总线、设备、驱动、类

    下面主要描述一下总线、设备、驱动、类之间的关系,Documentation/driver-model下亦有描述。对于总线、设备、驱动、类的操作函数的实现,code shows you everything,详见drivers/base下的bus.ccore.cdriver.cdd.cclass.c等。

    2.1 总线

    总线是处理器与一个或多个设备之间的通道,在设备模型中,所有的设备都通过总线相连。总线用struct bus_type来描述,bus_type是该总线下设备和驱动的管理机构。

    struct bus_type定义在include/linux/device.h中:

     50 struct bus_type { 
     51         const char              *name; 
     52         struct bus_attribute    *bus_attrs; 
     53         struct device_attribute *dev_attrs; 
     54         struct driver_attribute *drv_attrs; 
     55 
     56         int (*match)(struct device *dev, struct device_driver *drv); 
     57         int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 
     58         int (*probe)(struct device *dev); 
     59         int (*remove)(struct device *dev); 
     60         void (*shutdown)(struct device *dev); 
     61 
     62         int (*suspend)(struct device *dev, pm_message_t state); 
     63         int (*resume)(struct device *dev); 
     64 
     65         const struct dev_pm_ops *pm; 
     66 
     67         struct subsys_private *p; 
     68 }; 

    重点看一下结构struct subsys_private,该结构描述了总线与设备和驱动的关系:

     27 struct subsys_private { 
     28         struct kset subsys; 
     29         struct kset *devices_kset; 
     30 
     31         struct kset *drivers_kset; 
     32         struct klist klist_devices; 
     33         struct klist klist_drivers; 
     34         struct blocking_notifier_head bus_notifier; 
     35         unsigned int drivers_autoprobe:1; 
     36         struct bus_type *bus; 
     37 
     38         struct list_head class_interfaces; 
     39         struct kset glue_dirs; 
     40         struct mutex class_mutex; 
     41         struct class *class;   
     42 };

    1devices_ksetdrivers_kset分别指向该总线下所有设备和驱动的集合,在sysfs中,/sys/bus/xxx/下总是存在/sys/bus/xxx/devices/sys/bus/xxx/drivers目录。

    2bus_type还管理着两个链表,klist_devicesklist_drivers,分别表示该总线下的所有设备和所有驱动。

    2.2 设备

    设备驱动模型中,每一个设备都用struct device描述,struct device定义在include/linux/device.h中,下面只列出部分成员:

     struct device { 
    407         struct device           *parent; 
    408 
    409         struct device_private   *p; 
    410 
    411         struct kobject kobj; 
                   ......
                   ......
    418 
    419         struct bus_type *bus;           /* type of bus device is on */ 
    420         struct device_driver *driver;   /* which driver has allocated this 
    421                                                          device */ 
                   ......
                   ......
    452 
    453         struct klist_node       knode_class; 
    454         struct class            *class; 
                   ......
                   ......
    458 }; 
     68 struct device_private {         
     69         struct klist klist_children; 
     70         struct klist_node knode_parent; 
     71         struct klist_node knode_driver; 
     72         struct klist_node knode_bus;    
     73         void *driver_data; 
     74         struct device *device; 
     75 };

    1)父子关系:它是一个父设备,它维护一个子设备的链表klist_children;它同时是一个子设备, parent指向它的父设备,knode_parent是该设备在其父设备的子设备链表中的节点;

    2)与总线的关系:它挂在某个总线下,bus指向该总线的bus_type结构, knode_bus是其所在总线所维护的设备链表中的一个节点;

    3)与驱动的关系:它是一个设备,理所当然要跟一个驱动匹配, driver指向与该设备匹配的device_driver结构,bus下的每一个驱动会维护一个设备链表表示该驱动支持的所有设备, knode_driver便表示该链表下的一个节点;

    4)与类的关系:类是一个设备的高层视图,它抽象出了底层的实现细节,允许用户空间使用设备所提供的功能,而不关心设备是如何连接以及它们是如何工作的。即具体相似功能的设备被划为一类。class 指向该设备所属的类,每个类会维护一个链表表示该类型下的所有设备, knode_class便是该链表中的一个节点。

    2.3 驱动

    struct device_driver用来描述驱动程序,其定义在include/linux下:

    122 struct device_driver { 
    123         const char              *name;  
    124         struct bus_type         *bus; 
    125         
                   ......
                   ......
    144         struct driver_private *p; 
    145 };
     45 struct driver_private { 
     46         struct kobject kobj;             
     47         struct klist klist_devices; 
     48         struct klist_node knode_bus; 
     49         struct module_kobject *mkobj; 
     50         struct device_driver *driver; 
     51 };

    1)与设备的关系:每个驱动程序可以支持多个设备,device_driver维护了一个链表表示该驱动支持的所有设备,klist_devices指向该链表头;

    2)与总线的关系:每个总线维护一个链表表示该总线下的所有驱动,knode_bus便是该链表下的一个节点, bus指向该驱动所在的总线;

    2.4

    类是一个设备的高层视图,它抽象出了底层的实现细节,允许用户空间使用设备所提供的功能,而不关心设备是如何连接以及它们是如何工作的。即具体相似功能的设备被划为一类。类用struct class描述,定义在include/device.h中:

    193 struct class { 
    194         const char              *name; 
    195         struct module           *owner; 
    196 
    197         struct class_attribute          *class_attrs; 
    198         struct device_attribute         *dev_attrs; 
    199         struct bin_attribute            *dev_bin_attrs; 
    200         struct kobject                  *dev_kobj; 
    201 
    202         int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); 
    203         char *(*devnode)(struct device *dev, mode_t *mode); 
    204 
    205         void (*class_release)(struct class *class); 
    206         void (*dev_release)(struct device *dev); 
    207 
    208         int (*suspend)(struct device *dev, pm_message_t state); 
    209         int (*resume)(struct device *dev); 
    210 
    211         const struct kobj_ns_type_operations *ns_type; 
    212         const void *(*namespace)(struct device *dev); 
    213 
    214         const struct dev_pm_ops *pm; 
    215 
    216         struct subsys_private *p; 
    217 }; 
    27 struct subsys_private { 
     28         struct kset subsys; 
     29         struct kset *devices_kset; 
     30 
     31         struct kset *drivers_kset; 
     32         struct klist klist_devices; 
     33         struct klist klist_drivers; 
     34         struct blocking_notifier_head bus_notifier; 
     35         unsigned int drivers_autoprobe:1; 
     36         struct bus_type *bus; 
     37 
     38         struct list_head class_interfaces; 
     39         struct kset glue_dirs;  
     40         struct mutex class_mutex; 
     41         struct class *class; 
     42 };

    1)与设备的关系:每个类会维护一个链表表示该类型下的所有设备, devices_kset指向该链表头

  • 相关阅读:
    [转]多线程更新Processbar
    不能因技术后天的死 而迷茫了今天的“学” 生
    NSIS 安装包制作相关
    [转]yslow 评分标准
    c# winform 打印 窗体 及 窗体控件内容 的 初级尝试
    严重认知自身成长 与诸博友共勉
    [转]NSIS 的 Modern UI 教程
    爱的幸福
    遍历WinForm窗体 根据语言类型设置其控件Text显示
    多借鉴 多思考
  • 原文地址:https://www.cnblogs.com/tanghuimin0713/p/3826904.html
Copyright © 2020-2023  润新知