内核设备模型
目的:表示设备和设备在系统中的拓扑关系
优点: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. Android中插件开发篇总结和概述

    刚刚终于写完了插件开发的最后一篇文章,下面就来总结一下,关于Android中插件篇从去年的11月份就开始规划了,主要从三个方面去解读Android中插件开发原理.说白了,插件开发的原理就是:动态加载技 ...

  2. Python基础教程(019)--执行Python的方式,IPython

    前言 了解IPython 内容 IPython 是一个Python的交互式shell,比默认的Python shell 好用的多 查看图片 在提示符下执行 目的 了解进入IPython 退出IPyth ...

  3. Scrapy模拟登陆豆瓣抓取数据

    scrapy  startproject douban 其中douban是我们的项目名称 2创建爬虫文件 进入到douban 然后创建爬虫文件 scrapy genspider dou douban. ...

  4. 解决Mac下使用root 权限依旧无法读写文件的问题

    当时在学习selenium的时候,需要配合使用chromedriver 和phantomjs 进行浏览器的自动化测试.. chromedriver下载结束后.无法移动到/user/bin下面 会提示权 ...

  5. Linux随笔 - Linux统计某文件夹下文件、文件夹的个数

    统计某文件夹下文件的个数 ls -l |grep "^-"|wc -l 统计某文件夹下目录的个数 ls -l |grep "^d"|wc -l 统计文件夹下文件 ...

  6. JDK 与 JRE

    JDK就是Java Development Kit.简单的说JDK是面向开发人员使用的SDK,它提供了Java的开发环境和运行环境.SDK是Software Development Kit 一般指软件 ...

  7. js-xlsx sheet_to_json 读取小数位数变多

    read as string . 例如:2.85 读取后变成 2.84999999999999999 这种. 以字符串形式读取. XLSX.utils.sheet_to_json(workbook.S ...

  8. Kindeditor在线文本编辑器过滤HTML

    KindEditor.ready(function (K) { editor = K.create('textarea[name="content"]', { filterMode ...

  9. HTML段落,换行,字符实体

    HTML段落,换行,字符实体 html段落 <p>标签定义一个文本段落,一个段落含有默认的上下间距,段落之间会用这种默认间距隔开,代码如下: <!DOCTYPE html> & ...

  10. LR 场景设置

    LR 场景设置group:多个脚本按照独立设置模式跑,各个脚本可以单独设置虚拟用户.运行时间scenario:多个脚本之间按照相同模式跑,将总的虚拟用户数按照一定比例分配给各个脚本 schedule ...