内核设备模型
目的:表示设备和设备在系统中的拓扑关系
优点:1减少内核代码量,2可以统一查看所有设备状态和所连接的总线,3可以联系好设备和其对应的驱动,或者驱动对应的设备。4可以按类型分类,可以沿着叶子节点方向向根节点访问来保证正确关闭设备电源(先关目的节点的所有子节点,再关闭该节点)
 
设备模型的样子:
已经被用数据结构抽象了一遍。用户的角度可以从sys目录鸟瞰内核中的设备模型关系
通常sys下打开的
一级目录是不同的类型的子系统,
----------------------------------------------------------
二级目录是在同一类型的目录集合 
----------------------------------------------------------
三级目录是唯一的目录
 
内核中的样子 usb设备模型为例子
设备子系统           
-----------------------------------------------------------
usb集线器
-----------------------------------------------------------
usb设备
-----------------------------------------------------------
 
内核中抽象后的样子   
设备子系统       ( kset x,kset a 。。。) subsystem    
-----------------------------------------------------------
usb集线器     (kobject b kobject a。。。)kset a
-----------------------------------------------------------
usb设备 a             kobject a
-----------------------------------------------------------
 
设备抽象后所具有的功能:
可以区分设备类型:
    字符设备,访问方式:访问设备节点,不可寻址;
              miscdev简化的设备驱动
    块设备, 访问方式:访问设备节点,可以寻址。(就是支持上次的lseek随机访问的方式)
    网络设备,访问方式:套接字API,而非访问设备节点。
    伪设备,随机数发生器,空设备,零设备,满设备。
    
设备模型有数据结构套路:准备好核心工作者kobject,把相同类型的kobject归到同一个车间kset工作,把不同车间的kset整合出一个子系统。
 
 
 
kobject ,他会是一个很好的设备看管员
    1kobject对象给他所看管的设备保存着引用计数器, 没对这个设备对象引用时, 该对象将结束工作周期。该设备可以从内存中删除。
    2sysfs中显示的目录对应着一个kobject,
    3kobject对象有指定好paren他的上层节点,形成了不同kobject间的层次关系,维持车间kset中的层次列表(parent下面解释和kset的区别)
    4 热插拔kobject子系统产生时间通知用户控件
 
kset 对象:看管员的管理者
    1每个kobject被创建的时候基本都指定好了他们对应的kset,所以分类时自动会找到所属上层所属的kset。说到这里指只是给大家介绍下层次感。
    2 将uevent,ktype的操作汇集到kset
 
subsystem子系统:
    实际是kset和信号量的集合
 
 
打开数据结构,一些疑惑和介绍。
struct kobject {
const char *name;//名字
struct list_head entry;//作为父对象的链表节点
struct kobject *parent;//父对象
struct kset *kset;//属于哪个对象集合  (上层kset内有个自己的kobject)
struct kobj_type *ktype; //对象类型
struct sysfs_dirent *sd;//sysfs文件系统目录
struct kref kref;//引用
unsigned int state_initialized:1;//已经初始化
unsigned int state_in_sysfs:1;//已经加入sysfs文件系统
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};
 
struct kset {  
    struct list_head list;//连接该kset中所有kobject的链表头     
    spinlock_t list_lock;  
    struct kobject kobj; //内嵌的kobject  
    const struct kset_uevent_ops *uevent_ops;//处理热插拔事件的操作集合  
};  
 
struct kobj_type {
void (*release)(struct kobject *kobj);//释放kobject和其他占用资源的函数
const struct sysfs_ops *sysfs_ops;//操作属性的方法
struct attribute **default_attrs;//属性数组
const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
const void *(*namespace)(struct kobject *kobj);
};
 
1*kset;  *ktype;既然说kset是相同类型的kobject的集合,为什么会说,ktype相同的kobject可能出现在不同的kset中?
     kobject在创建后就指定好了自己所属于的kset,这些找到了kset的kobject的对象会把自身的kobj_type类型成员 ktype替换成目标kset的对象类型。kset的用自己的属性把所有来认自己的kobject都给刷了一遍,导致我们常说kset下是包含相同类型的看object的集合。
     两个ktype不同的kobject,的确可以存在不同的kset中。只要他们不是指定同一个kset就可以了。
     由于是kset的优先级高,导致了分类时,就按kobject对应的kobject来分的,如果创建好的kobject没有指定kset那就会用ktype看来指定。
 
 
2 都说kset和parent都是支持设备模型上下层次结构用的。两者有什么关系?
kset是ktype类型相同的处理对象聚集和集合。底层kobject中的kset指向上层的对应的kset,
 parent是用来在sysfs分层中定位kobject对象的,parent指向了上层中的kobject,表示上一层节点。  
联系:
      a.默认kset是其下的kobject的parent。
    在kobject加入到kset集合的链表前, 会检查下这个kobject是否有parent存在,如果不存在,那就不能在sysfs中找到这个kobject了,所以会让这个kobject的parent直接指向指定的kset层的kobject
parent = kobject_get(&kobj->kset->kobj);
 
      b.kobject(也包括kset)的kset可能为空 比如/sys/bus/platform下的drivers kset和devices kset,虽然在用户空间看来platform作为kset包含了driver和device,实际不是。
kobject(也包括kset)的parent可能为空(树形结构顶级节点)
kobjectd 的parent不一定是包含他的kset
  
3 kobject相关介绍
kobject
kobject用于控制大型域对象的访问,通常是被别的struct包含了。
工作1:用来获取结构体入口,
字符设备cdev中有kobject成员, 
经常看到 使用container_of(kp,strcut cdev, kobj);  宏定义来找cdev这个结构体的起始地址。
有个公式:绝对地址-相对与结构体起点的地址,得到结构体的起始地址。
 #define container_of(ptr, type, member) ({            \
           const typeof(((type *)0)->member) * __mptr = (ptr);    \    ptr是内存中指向member成员hlist_head绝对地址
            (type *)((char *)__mptr - offsetof(type, member)); })      hlist_head 链表的节点, 减掉已经得到的节点位置,往前挪offsetof个位置就得到了
 
工作2:创建kobject,保管好引用计数器。
a.kobject初始化就是用menmset 先整个把kobject中的引用计数kref设置为0,再用kobject_init()把引用计数设置为1,
b.把kobject_set_name()设置好名字好在sysfs目录显示
c.增加对kobject引用/减引用要注意返回值,kobject_get() kobject_put()
创建kobject_add()+ kobject_init() =kobject_register
删除 kobject_del  + kobject_put = kobject_unregister
    创建对cdev的引用 还是最终要调用对模块owner中kobject 的引用。失败则要释放引用计数module_put(owner)
d 发没引为0的通知。kobject的kref为0时没人知道kobject过得怎么样了,所以要变0前先异步通知大家, 用contariner获得包含kobject的类对象,接着kfree(对象)   有引用时,不能释放,因为不安全, 引用没释放完也不能释放。
 
 
  4kset和ktype相关介绍  
    a.kset管理者一个链表要加入kobject成员, 先初始化kobject中的kset指向上层目标kset
    b.管理kset的引用计数 kset_get() kset_put 增加和减少kset自带的kobject的引用计数,管理引用的原理基本和kobject一致
    c.kset有名字,另外kset的ktype成员是实际上被使用的成员,也就是之前说的kset的类型覆盖底层的类型的那个ktype
d.析构相关的函数
ktype是真正的看管员,设备后来怎么样了,要怎么处理都是ktype在照看的,把对设备共同的操作从kobject中分离出来了。
release: 定好了kobject的ktype也就是定好了release函数指针
sysfs_ops:{(*show)(*kobj,*attr,*buffer) (*store)(*kobj,*attr,*buffer,size)}两个操作函数用户读属性,
 
调用show把指定值编码后放到缓冲区,实际长度作为返回值返回。或者所有kobject属性使用同一个show
store把保存在缓冲区中的数据解码,并返回实际解码的字节数,属性有写权限才能调用store注意取数据前验合法输入
 attribute **default_attrs 最后一个元素必须用零填充。说明有什么属性。这个kobj_type 中的sysfs_ops提供方法实现attribute中的属性
这个attribute有*name属性名在sysfs中的名字,
module *owner指向模块的指针 
mode属性保护位 S_IRUGO只读 S_IWUSR只给root写  
修改属性,填一个attr 传给sysfs增删目录文件函数 sysfs_create_remove_file
sysfs属性传固件代码给内核,bin_attribute 里面有attribute  size (*read) (*write)一次可以读写1页
 
 
5子系统相关介绍
内核提供了sysf子树上实际是已经被注册上去的各种kobject,和kobject集合的关系,上层通常是已经注册好的subsystem
sysfs下的子系统:
 块设备子系统:对应sys/block,里面每个目录都对应一个已经注册的块设备
设备分层结构核心 :对应sys/devices 系统中实际的设备拓扑。很重要哦,其他很多目录都是抄了他里面的层次
总线子系统:对应sys/bus 系统总线视图
设备节点子系统:对应sys/dev 已经注册的设备节点视图
固件子系统:对应sys/firmware 包含底层子系统的特殊树
文件子系统:对应sys/fs 已经注册的文件系统视图
内核子系统:对应sys/kernel 内核配置项和状态信息
模块子系统:对应sys/module 已加载模块的信息
电源子系统:对应sys/power 系统范围的电源管理数据
总线有两个ket,一个是总线的设备驱动集合, 一个是插在总线上的所有设备
 
设备和驱动程序的关系用新的指针,符号链接
int sysfs_create_link(struct kobject *kobj,struct  kobject *target,char *name); 设置kobject和sysfs入口target的相对连接,
int sysfs_remove_link(struct kobject *kobj,char *name); 删除符号链接
子系统是对ket和信号的封装,每个keset必须属于一个子系统,rwsem信号量用于串行访问kset内部链表
sysfs和kobect关系就是用来kobect_add 那sysfs中就会有新的目录,目录名就是kobect的唯一名称,kobect的parent就是对应在sysfs中的入口位置,为NULL时在sysfs的最高层目录
 
6热插拔相关介绍:
     热插拔事件,是内核空间发到用户空间的通知是系统配置变化了,插拔usb 用户控制台切换,磁盘分区都会有这事要报,
kobject_add 或kobkect_del调用后才真正产生这事件
      kset中的hotplug_ops 中有指向struct kset_hotplug_ops结构体的指针,kset中没指定的kobject就要用parent指针找到一个包含kset的kobject,再使用这个kset的热插拔操作
    内核要为指定的kobject产生事件都要调用fliter函数0不产生事件,让kset确定是否要发特定事件给用户控件 get_ktype知道事件类型
调用热插拔时相关子系统名*name作为唯一参数传递给它  
热插拔的信息通过环境变量传递,提供添加环境变量的方法使用hotplug。
 
7类:
     设备模型的类,是抽象底层的实现细节,  值关注提供的功能,基本上是在sys/class 目录下
      类关心设备功能 总线跟踪设备,用户用设备的功能,设备用sysfs和用户空间通信
 

内核设备模型从kobject到子系统的更多相关文章

  1. Linux设备模型之kobject

    阿辉原创,转载请注明出处 参考文档:LDD3-ch14.内核文档Documentation/kobject.txt,本文中使用到的代码均摘自Linux-3.4.75 ----------------- ...

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

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

  3. linux设备模型_转

    建议原博文查看,效果更佳. 转自:http://www.cnblogs.com/wwang/category/269350.html Linux设备模型 (1) 随着计算机的周边外设越来越丰富,设备管 ...

  4. Linux设备模型(3)_Uevent【转】

    转自:http://www.wowotech.net/device_model/uevent.html 1. Uevent的功能 Uevent是Kobject的一部分,用于在Kobject状态发生改变 ...

  5. Linux设备模型 (1)

    随着计算机的周边外设越来越丰富,设备管理已经成为现代操作系统的一项重要任务,这对于Linux来说也是同样的情况.每次Linux内核新版本的发布,都会伴随着一批设备驱动进入内核.在Linux内核里,驱动 ...

  6. Linux 设备模型之 (kobject、kset 和 Subsystem)(二)

    问题描写叙述:前文我们知道了/sys是包括内核和驱动的实施信息的,用户能够通过 /sys 这个接口.用户通过这个接口能够一览内核设备的全貌.本文将从Linux内核的角度来看一看这个设备模型是怎样构建的 ...

  7. linux设备驱动模型(kobject与kset)

    Linux设备模型的目的:为内核建立一个统一的设备模型,从而又一个对系统结构的一般性抽象描述.换句话说,Linux设备模型提取了设备操作的共同属性,进行抽象,并将这部分共同的属性在内核中实现,而为需要 ...

  8. Linux内核(8) - 设备模型(下)

    设备模型拍得再玄幻,它也只是个模型,必须得落实在具体的子系统,否则就只能抱着个最佳技术奖空遗恨.既然前面已经以USB子系统的实现分析示例了分析内核源码应该如何入手,那么这里就仍然以USB子系统为例,看 ...

  9. Linux内核(7) - 设备模型(上)

    对于驱动开发来说,设备模型的理解是根本,毫不夸张得说,理解了设备模型,再去看那些五花八门的驱动程序,你会发现自己站在了另一个高度,从而有了一种俯视的感觉,就像凤姐俯视知音和故事会,韩峰同志俯视女下属. ...

随机推荐

  1. [HDU2276]Kiki & Little Kiki 2

    题目:Kiki & Little Kiki 2 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2276 分析: 1)如果前一盏灯亮着,则改变这一盏灯 ...

  2. [CSP-S模拟测试]:涂色游戏(DP+组合数+矩阵快速幂)

    题目描述 小$A$和小$B$在做游戏.他们找到了一个$n$行$m$列呈网格状的画板.小$A$拿出了$p$支不同颜色的画笔,开始在上面涂色.看到小$A$涂好的画板,小$B$觉得颜色太单调了,于是把画板擦 ...

  3. [CSP-S模拟测试]:Lost My Music(凸包)

    题目描述 小$w$在天堂看到了一棵世界树.世界树上有$n$个节点,其中$1$节点为根,每个节点有一个正整数权值$c_i$.现在小$w$想要对每个节点$u$求出它的祖先$v$中$\frac{c_v-c_ ...

  4. 使用Echarts中遇到值得记录的小案例(一)

    需求部分 在开发项目的时候遇到一个需求,就是如何保证echarts图表里至少显示一个图例的数据(也就是最后一个图例不能变成unselected的状态)下图是最初加载时的画面 不想出现图例都被点击取消导 ...

  5. Cent OS (一)Cents OS的基本安装

    1.实验环境: VMware Workstation Pro   14 Pro Cent OS 7 系列. 2. 镜像地址传送门: 阿里云开源镜像站:http://mirrors.aliyun.com ...

  6. mysql8.0 新特性,对json类型的常用操作

    mysql8 新特性-json数据类型操作 -- 根据key(可多个)获取value SELECT JSON_EXTRACT('{"id": 14, "name" ...

  7. yarn 国内加速,修改镜像源

    为什么慢 由于默认情况下执行 yarn 各种命令是去国外的 yarn 官方镜像源获取需要安装的具体软件信息,所以在不使用代理.不翻墙的情况下,从国内访问国外服务器的速度相对比较慢 可以通过以下命令快速 ...

  8. boostrap中lg,md,sm,xs分别对应的像素宽度

    col-xs-   超小屏幕 手机 (<768px)col-sm-  小屏幕 平板 (≥768px)col-md-  中等屏幕 桌面显示器 (≥992px)col-lg-    大屏幕 大桌面显 ...

  9. poj3252 Round Numbers(数位dp)

    题目传送门 Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16439   Accepted: 6 ...

  10. docker--container的port映射

    使用nginx为例 先运行nginx [root@localhost ~]# docker run --name web -d nginx Unable to find image 'nginx:la ...