zoukankan      html  css  js  c++  java
  • linux设备驱动模型之Kobject、kobj_type、kset【转】

    本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/74838165

     

    目录(?)[+]

     

    学习中platform平台驱动中,慢慢发现底层有一个叫做Linux设备驱动模型的东西。发现是它是底层驱动重要的组织结构,现在针对设备驱动模型进行分析。从而加深对整个设备驱动注册的理解。

    用户空间程序通过sysfs虚拟文件系统访问设备的相关信息。这些信息被组织成层次结构,用sysfs虚拟文件系统来表示,用户通过对sysfs的操作,就可以控制设备或者读取设备的信息。

    一、sysfs文件系统简介:

    1、sysfs概述

    sysfs文件系统是内核对象(kobject)、属性(kobj_type)、及它们相互关系的一种表现。
    sysfs非常重要的特征:用户可以从sysfs中读出内核数据,也可以将用户数据写入内核。

    2、内核结构与sysfs对应关系:

    kobject    -->目录

    kobj_type-->属性文件

    3、特点

    sysfs文件系统只存在于内存中,动态的表示内核数据结构。设备启动时,设备驱动模型会注册kobject对象,并在sysfs文件系统中产生sys下目录文件。

    sys/bus:下列出了注册到系统中的总线,如USB总线、platform总线。
    sys/class:注册到内核中的设备类,如声音类(sound)、输入类(input)。

    二、核心数据结构

    在Linux的驱动表示中,主要有三个基本的结构,分别是kobject、kset、ktype.这三个结构是设备模型中的下层架构。
    模型中的每一个元素都对应一个kobject.
    kset和ktype可以看成是kobject在层次结构与属性结构方面的扩充。将三者之间的关系用图的方示描述如下:
    参考:http://blog.csdn.net/lizuobin2/article/details/51511336
    如上图所示,sysfs中每一个目录都对应一个kobject.
    这些kobject都有自己的parent。在没有指定parent的情况下,都会指向它所属的kset->object。
    其次,kset也内嵌了kobject.这个kobject又可以指它上一级的parent。就这样。构成了一个空间上面的层次关系。
    其实,每个对象都有属性。例如,电源管理,执插拨事性管理等等。
    因为大部份的同类设备都有相同的属性,因此将这个属性隔离开来,存放在ktype中。
    这样就可以灵活的管理了.记得在分析sysfs的时候。
    对于sysfs中的普通文件读写操作都是由kobject->ktype->sysfs_ops来完成的.

    1、kobject结构体

    kobject组成设备驱动模型的基本结构。
    sysfs中,设备用树形结构来表示,树形结构每一个目录对应一个kobject对象(目录组织结构和名字等信息)

    [cpp] view plain copy
     
     print?
    1. struct kobject {  
    2.     const char      *name;                 kobject的名称,显示在sysfs文件系统中,作为一个目录的名字。  
    3.     struct list_head    entry;                   链接下一个kobject结构  
    4.     struct kobject      *parent;               指向父kobject结构体  
    5.     struct kset     *kset;                   指向所属的kest集合  
    6.     struct kobj_type    *ktype;                 指向kobject的属性文件,每个对象都有属性  
    7.                                     将属性单独组织成数据结构kobj_type存放在ktype中  
    8.                                     对于sysfs中的普通文件读写操作都是由kobject->ktype->sysfs_ops来完成的  
    9.     struct sysfs_dirent *sd;                      对应sysfs的文件目录  
    10.     struct kref     kref;                             kobject的引用计数  
    11.     unsigned int state_initialized:1;           初始化状态  
    12.     unsigned int state_in_sysfs:1;            是否已经加入到sysfs中  
    13.     unsigned int state_add_uevent_sent:1;  
    14.     unsigned int state_remove_uevent_sent:1;  
    15.     unsigned int uevent_suppress:1;  
    16. };  

    在内核中,没有用kobject直接定义的变量,kobject只是作为一个抽象的基类而存在。一般都是将kobject嵌入到另一个结构,这个结构就可以看做是kobject的一个子类。而kobject的子类会比较关心kobject的属性和方法。

    内核里的设备之间是以树状形式组织的,在这种组织架构里比较靠上层的节点可以看作是下层节点的父节点,
    反映到sysfs里就是上级目录和下级目录之间的关系,在内核里,正是kobject帮助我们实现这种父子关系。

    kobject的成员:

    name表示的是kobject在sysfs中的名字;

    指针parent用来指向kobject的父对象;

    Kref大家应该比较熟悉了,kobject通过它来实现引用计数;

    Kset指针用来指向这个kobject所属的kset;

    对于ktype用来描述kobject的类型信息。

    kobject的作用:

    (1)kobject始终代表sysfs文件系统中的一个目录,name成员指定了目录名,不是文件。

    (2)parent成员指定了kobject在sysfs中的目录,从而形成一个树形结构。

    (3)ktype是kobject的属性,属性用文件来表示,放在kobject对应目录下。

    2、设备属性kobj_type

    每个kobject对象都有一些属性,这些属性由kobj_type表示,kobject中有指向kobj_type的指针,属性用文件来表示。
    [cpp] view plain copy
     
     print?
    1. struct kobj_type {  
    2.     void (*release)(struct kobject *kobj); 释放kobject和其占用资源的函数  
    3.     const struct sysfs_ops *sysfs_ops;      操作下一个属性数组的方法  
    4.     struct attribute **default_attrs;        属性数组  
    5.     const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);  
    6.     const void *(*namespace)(struct kobject *kobj);  
    7. };  
    kobj_type的default_attrs成员保存了属性数组,每个kobject对象可以一个或多个属性,属性的定义如下:
    [cpp] view plain copy
     
     print?
    1. struct attribute {  
    2.     const char      *name;      属性的名称,对应目录下一个文件的名字  
    3.     umode_t         mode;         属性的读写权限  
    4. #ifdef CONFIG_DEBUG_LOCK_ALLOC  
    5.     struct lock_class_key   *key;  
    6.     struct lock_class_key   skey;  
    7. #endif  
    8. };  
    kobj_type的default_attrs数组表明了kobject有哪些属性,但是没有说明如何操作这些属性,这个任务由kobj_type的
    sysfs_ops->sysfs_ops来完成
    [cpp] view plain copy
     
     print?
    1. struct sysfs_ops {  
    2.     ssize_t (*show)(struct kobject *, struct attribute *,char *);                      读属性操作函数  
    3.     ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);         写属性操作函数  
    4.     const void *(*namespace)(struct kobject *, const struct attribute *);  
    5. };  
    kobject:要读写的kobject指针,attribute:要读写的属性。

    3.kset结构体

    之前说kobject对应文件系统/sys里的一个目录,kset中包含kobject结构体,所以kset也对应于/sys里的一个目录。
    简单来说,kset 与 kobj 都是目录,既然是目录,那么在就是一个树状结构,每一个目录都将有一个父节点,
    在kset中使用kset.kobj->parent 指定 
    在kboject中使用  kobj->parent 指定
    显然,整个树状目录结构,都是通过kobj来构建的,只不过有些kobj嵌在Kset里,分析目录结构时把kset当成一个普通的kobj会好理解很多。
    kobject通过kset组织成层次化的结构,kset是具有相同类型的kobject集合。像驱动程序放在/sys/drivers目录下一样,目录drivers是一个kset对象,包含系统中驱动程序对应的目录,驱动程序的目录有kboject表示。内核将相似的kboject结构连接在kset集合中。
    [cpp] view plain copy
     
     print?
    1. struct kset {  
    2.     struct list_head list;  
    3.     spinlock_t list_lock;  
    4.     struct kobject kobj;  
    5.     const struct kset_uevent_ops *uevent_ops;  
    6. };  

    kobject与kset对应关系:

    目前的简单理解:

    linux存在一个虚拟文件系统/sysfs,内核启动挂接文件系统后会将sysfs文件系统挂接到/sys下。内核启动时会初始化并注册一些总线、设备,这些总线、设备等会在sys下创建目录,来存储,如/sys/bus/platform 下存储了平台设备信息。如何组织管理设备,并创建目录呢,通过设备驱动模型的几个重要结构体:Kobject、kobj_type、kset来组织和管理目录及文件结构。

  • 相关阅读:
    高手 读书笔记-1.精英社会的神话
    企业IT架构转型之道 读书笔记-1.阿里巴巴集团中台战略引发的思考
    Redis学习-内存优化
    Redis学习笔记--常用命令
    Go语言备忘录(3):net/http包的使用模式和源码解析
    Go语言备忘录(2):反射的原理与使用详解
    Go语言备忘录(1):基本数据结构
    Go的接口总结
    Go的类型断言解析
    StrangeIoc框架学习
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/7250096.html
Copyright © 2011-2022 走看看