关于linux设备模型网上有一些论述,有些东西我就用了拿来主义,进行了修改和整理。

§1 Kobject

Kobject 是Linux 2.6引入的新的设备管理机制,在内核中由struct kobject表示。通过这个数据结构使所有设备在底层都具有统一的接口,kobject提供基本的对象管理,是构成Linux2.6设备模型的核心结构,它与sysfs文件系统紧密关联,每个在内核中注册的kobject对象都对应于sysfs文件系统中的一个目录。Kobject是组成设备模型的基本结构。类似于C++中的基类,它嵌入于更大的对象的对象中--所谓的容器--用来描述设备模型的组件。如bus,devices, drivers 都是典型的容器。这些容器就是通过kobject连接起来了,形成了一个树状结构。这个树状结构就与/sys相对应。

kobject 结构为一些大的数据结构和子系统提供了基本的对象管理,避免了类似机能的重复实现。这些机能包括

- 对象引用计数.

- 维护对象链表(集合).

- 对象上锁.

- 在用户空间的表示.

Kobject结构定义为:

文件:include/linux/kobject.h

struct kobject {
const char                  *name;指向设备名称的指针
struct list_head        entry;挂接到所在kset中去的单元
struct kobject           *parent;指向父对象的指针
struct kset                 *kset;所属kset的指针
struct kobj_type       *ktype;指向其对象类型描述符的指针
struct kernfs_node  *sd; sysfs文件系统中与该对象对应的文件节点路径指针
struct kref                  kref;对象引用计数
#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
struct delayed_work        release;
#endif
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};

其中的kref域表示该对象引用的计数,内核通过kref实现对象引用计数管理,内核提供两个函数kobject_get()、kobject_put()分别用于增加和减少引用计数,当引用计数为0时,所有该对象使用的资源释放。Ktype域是一个指向kobj type结构的指针,表示该对象的类型。

相关函数

void kobject_init(struct kobject * kobj);kobject初始化函数。

int kobject_set_name(struct kobject *kobj, const char *format, ...);设置指定kobject的名称。

struct kobject *kobject_get(struct kobject *kobj);将kobj对象的引用计数加1,同时返回该对象的指针。

void kobject_put(struct kobject * kobj);将kobj对象的引用计数减1,如果引用计数降为0,则调用kobject_release ()释放该kobject对象。

int kobject_add(struct kobject * kobj);将kobj对象加入Linux设备层次。挂接该kobject对象到kset的list链中,增加父目录各级kobject的引用计数,在其parent指向的目录下创建文件节点,并启动该类型内核对象的hotplug函数。

int kobject_init_and_add(struct kobject * kobj);kobject注册函数。通过调用kobject_init ()初始化kobj,再调用kobject_add()完成该内核对象的注册。

void kobject_del(struct kobject * kobj);从Linux设备层次(hierarchy)中删除kobj对象。

void kset_unregister(struct kobject * kobj);kobject注销函数。与kobject_register()相反,它首先调用kobject_del从设备层次中删除该对象,再调用kobject_put()减少该对象的引用计数,如果引用计数降为0,则释放kobject对象。

§2 Kobj type

include/linux/kobject.h

struct kobj_type {
void (*release)(struct kobject *kobj);
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);
};

Kobj_type数据结构包含五个域:一个release方法用于释放kobject占用的资源;一个sysfs_ops指针指向sysfs操作表和一个sysfs文件系统缺省属性列表。Sysfs操作表包括两个函数store()和show()。当用户态读取属性时,show()函数被调用,该函数编码指定属性值存入buffer中返回给用户态;而store()函数用于存储用户态传入的属性值。

include/linux/sysfs.h

struct attribute {
const char      *name;
umode_t         mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
bool            ignore_lockdep:1;
struct lock_class_key   *key;
struct lock_class_key   skey;
#endif
};

attribute, 属性。它以文件的形式输出到sysfs的目录当中。在kobject对应的目录下面。文件名就是name。文件读写的方法对应于kobj_type中的sysfs_ops。

§3. kset

kset最重要的是建立上层(sub-system)和下层的(kobject)的关联性。kobject也会利用它来分辨自已是属于哪一个类型,然后在/sys下建立正确的目录位置。而kset的优先权比较高,kobject会利用自已的*kset找到自已所属的kset,並把*ktype指定成該kset下的ktype,除非沒有定义kset,才会用ktype來建立关系。Kobject通过kset组织成层次化的结构,kset是具有相同类型的kobject的集合,在内核中用kset数据结构表示,定义为:

include/linux/kobject.h

struct kset {
struct list_head list;用于连接该kset中所有kobject的链表头
spinlock_t list_lock;
struct kobject kobj;嵌入的kobject
const struct kset_uevent_ops *uevent_ops;
};

包含在kset中的所有kobject被组织成一个双向循环链表,list域正是该链表的头。Kset数据结构内嵌了一个kobject对象(由kobj域表示),所有属于这个kset的kobject对象的parent域均指向这个内嵌的对象。此外,kset还依赖于kobj维护引用计数:kset的引用计数实际上就是内嵌的kobject对象的引用计数。

见图1,kset与kobject的关系图

这幅图很经典,她反映了整个kobject的连接情况。

相关函数

与kobject 相似,kset_init()完成指定kset的初始化,kset_get()和kset_put()分别增加和减少kset对象的引用计数。kset_register()函数完成kset的注册而kset_unregister()函数则完成kset的注销。

Linux那些事儿之我是Sysfs(2)linux设备底层模型相关推荐

  1. Linux那些事儿之我是Sysfs(3)设备模型上层容器

    §1 bus 系统中总线由struct bus_type描述,定义为: include/linux/device.h struct bus_type { const char *name;总线类型的名 ...

  2. Linux那些事儿之我是Sysfs(11)sysfs 创建普通文件

    sysfs文件系统中,普通文件对应于kobject中的属性.用sysfs_create_file(),参数如下: sysfs_create_file(struct kobject * kobj, co ...

  3. Linux那些事儿之我是Sysfs(9)sysfs文件系统模型

    最近Linus炮轰C++,"C++是一种糟糕的(horrible)语言.而且因为有大量不够标准的程序员在使用而使许多真正懂得底层问题,而不会折腾那些白痴'对象模型'".牛人就是牛气 ...

  4. Linux那些事儿之我是Sysfs(8)一起散散步-pathwalk

    前面说过,只要知道文件的索引节点号,就可以得到那个文件.但是我们在操作文件时,从没听说谁会拿着索引节点号来操作文件,我们只知道文件名而已.它们是如何"和谐"起来的呢?linux把目 ...

  5. Linux那些事儿之我是Sysfs(7)dentry与inode

    我们在进程中要怎样去描述一个文件呢?我们用目录项(dentry)和索引节点(inode).它们的定义如下: include/linux/dcache.h struct dentry { /* RCU ...

  6. Linux那些事儿之我是Sysfs(6)文件系统

    接下来,我们进入sysfs部分.看看 kobject_add()->kobject_add_varg->kobject_add_internal->create_dir()-> ...

  7. Linux那些事儿之我是Sysfs(1)sysfs初探

    "sysfs is a ram-based filesystem initially based on ramfs. It provides a means to export kernel ...

  8. linux lddbus设备,Linux那些事儿之我是Sysfs(4)举例一lddbus | 技术部落

    接下来我们从例子着手 localhost:/home/XX/examples/lddbus#insmod lddbus.ko 此时再看/sys/bus/ 这时就多了一个文件夹ldd.里面的文件构成是这 ...

  9. Linux那些事儿之我是Sysfs(10)sysfs 创建目录

    每当我们新增一个kobject结构的时候,同时会在/sys下创建一个目录. kobject_add()  ->  create_dir() -> sysfs_create_dir() 此时 ...

最新文章

  1. Delphi 常用API 函数(好多都没见过)
  2. python输出姓名年龄_Python格式化输出--%s,%d,%f的代码解析
  3. 自定义异常时exception is never thrown in the corresponding try block和unhandled exception
  4. flex image 控件显示bmp 格式图片
  5. 数据结构课程设计---学生信息管理系统
  6. excel表格在保存时出现“隐私问题警告提示”
  7. 如何为 .NET Core 3.0 中 WPF 配置依赖注入 ?
  8. static函数的申明
  9. python 爬虫 scrapy1_官网教程
  10. 20200909:链表类题目集合下
  11. 监听屏幕解锁和判断屏幕状态
  12. 《统计学习方法》——k近邻法
  13. 新手用手机学黑客编程一秒变黑客
  14. web压力测试的几个指标
  15. 【小飞兔整站下载】整站下载器哪个好用_整站下载工具哪个好
  16. 海洋cms播放器html,海洋cms怎么添加播放器
  17. 一个屌丝程序猿的人生(四十)
  18. 使用gevent的Pool实现异步并发
  19. ie11兼容问题汇总及解决方案
  20. 微信云函数的使用步骤

热门文章

  1. 【转】Vue.js 2.0 快速上手精华梳理
  2. [LeetCode]42. Trapping Rain Water雨水填坑
  3. PyTorch 笔记(16)— torch.nn.Sequential、torch.nn.Linear、torch.nn.RelU
  4. Go 学习笔记(43)— Go 标准库之 os/exec(执行外部命令、非阻塞等待、阻塞等待、命令输出)
  5. 个人作业1——四则运算题目生成程序
  6. Java基于对象基础 基于对象和面向对象的区别(转)
  7. Android应用性能优化
  8. Java中的文件上传2(Commons FileUpload:commons-fileupload.jar)
  9. [代码]--WinForm 窗体之间相互嵌套
  10. MyEclipse中运行环境jre、编译级别、tomcat运行环境区别