linux内核驱动模型
linux内核驱动模型,以2.6.32内核为例。(一边写一边看的,有点乱。)
1、以内核对象为基础。用kobject表示,相当于其它对象的基类,是构建linux驱动模型的关键。
具有相同类型的内核对象构成内核对象集,用kset表示,内核对象集也包含自己的内核对象,从而组成层次化的结构。
2、用sysfs文件系统导出到用户空间。内核中的所有内核对象组织成树状,以对象属性为叶子。
通过sysfs文件系统,将用户空间对文件的读写操作转化为对内核对象属性的显示和保存方法。从而导出内核对象信息,并提供配置接口。
3、将linux子系统表达为总线类型、驱动、设备、类、接口的关系,分别用bus_type、device_driver、device、class、class_interface结构表示。
每个子系统有自己的总线类型,它有一条驱动链表和一条设备链表,用来链接已加载的驱动和已发现的设备,驱动加载和设备发现的顺序可以是任意的。
每个设备可以被绑定到最多一个驱动,被绑定了驱动的设备可以正常工作。
除此之外,每个设备可以属于某个唯一的类,在类上包含多个接口,接口的方法被用于设备,不管是先添加接口,还是先发现设备。
内核引用计数kref
在程序动态运行的情况下,常常需要将一个内核分配好的对象多次传递和使用。为了在该对象不再被使用时回收其内存资源,需要对该对象的引用进行计数。
kref有两个好处:防止内存泄露,在对象不被使用时释放内存;防止访问已释放的内存,确保不会访问已释放的对象。
kref的操作
kref_init():初始化对象为1,而不是0,因为生成该对象的代码也需要一个最初的引用,以防止其他部分在调用kref_put()时释放对象。
kref_get():递增对象的引用计数。
kref_put():递减对象的引用计数,如果计数为0,则调用传入的release方法。
kset具有以下功能:
作为包含一组对象的容器,kset可以被内核用来跟踪“所有块设备”或者“所有PCI设备驱动”。
作为一个目录级的“粘合剂”,将设备模型中的内核对象(以及sysfs)黏在一起。每个kset都内嵌一个kobject,可以作为其他kobject的父亲,通过这种层次构造设备模型层次。
kset可以支持kobject的“热插拔”,影响热插拔事件被报告给用户空间的方式。
举个形象的例子:
kset好比一个文件夹,kobject是文件夹下面的内容,kobject的类型可以不同,好比文件夹下有图片、视频、文档、程序等。
不同的kset好比不同的文件夹,但它们下面可以有相同类型的kobject。比如文件夹A和B下面都有图片和视频。
kset自身也有一个kobject,好比文件夹本质上也是一个文件一样,如同视频、图片之类的。
通过kset的list能找到下面的kobject,即找到这个文件夹,就能找到该文件夹下面的内容。
kobject的kset指向该kobject所属的kset,即文件夹下面的内容都属于这个文件夹之内。
kset通过kobject的entery将kobject组织起来,类似于文件夹下面的文件的路径都是相同的。
kobject的parent可以指向同kset下的另一个kobject,或者NULL,或者kset的kobject。
1、创建或初始化内核对象:kobject_create()和kobject_init()。两者的区别是前者会为kobject分配存储空间,然后调用kobject_init(),而后者是用于初始化已经分配了内存的kobject()。
2、将内核对象添加到sysfs:kobject_add()。该函数只会为默认属性自动创建sysfs文件。如果有其他属性,则需要另外创建sysfs文件。
kobject的parent决定该kobject在sysfs树中的位置。
1)若kobject的parent和kset都是空,则该kobject在sysfs树的根目录下。
2)若kobject的parent是空,kset已设置,则该kobject在sysfs树的位置在kset的kobject目录下。
3)若kobject的parent和kset都已设置,则该kobject在sysfs的位置在parent下。
3、创建、初始化、添加内核对象集:
kset_init()、kset_create()两者的区别和kobject_create()、kobject_init()的一样。
kset_add():添加内核对象集到sysfs
kset_register():kset_init()+kset_add()
kset_create_and_add():等价于kset_create+()kset_add()
4、发送内核对象变化事件到用户态空间
kobject_uevent()->kobject_uevent_env()
sysfs
从两个角度理解:
1、从内部看,sysfs是一种表示内核对象、对象属性,以及对象关系的一种机制。sysfs核心将内核输出的对象、对象属性以及对象关系组织成树状结构,称为sysfs内部树。
2、从外部看,sysfs类似于proc文件系统,用于将系统中的设备组织成层次结构(sysfs外部树),向用户空间导出设备和驱动信息,并且为设备和驱动提供配置接口。
sysfs核心负责建立内部树和外部树的对应关系,也称为sysfs映射。
1)内核对象被映射为用户空间的目录
2)对象属性被映射为用户空间的常规文件
3)对象关系被映射为用户空间的符号链接
对sysfs的读写转换成对属性的show和store操作。
总线类型
结构体:bus_type、bus_type_private
操作:bus_register()、bus_unregister()、bus_for_each_dev()、bus_for_each_drv()
设备
结构体:device、device_private
操作:device_register()、device_unregister()
驱动
结构体:device_driver、driver_private
操作:driver_register()、driver_unregister()
类
结构体:class、class_private
操作:class_register()、class_unregister()
接口
结构体:class_interface
操作:class_interface_register()、class_interface_unregister()
普通双向链表
struct foo {
struct foo * prev;
struct foo * next;
int val;
};
prev/next是类型相关的,都是struct foo *型。如果要在另外一个struct foo1中使用链表,必须重新定义foo1私有的链表。
struct foo1 {
struct foo1 * prev;
struct foo1 * next;
int val;
char c;
};
foo和foo1的链表操作,本质上虽然相同,但由于两者类型不同,所以不同通用。
比如插入,foo的插入,操作的是struct foo *型;而foo1的插入,操作的是stcut foo1 *型。
内核链表
struct list_head {
struct list_head * prev;
struct list_head * next;
};
struct foo {
struct list_head list;
int val;
};
prev/next是类型无关的,都是struct list_head*型,和所在结构体无关。如果要在另一个结构体foo1中使用链表,只需在foo1中包含该成员即可。
struct foo1 {
struct list_head list;
int val;
char c;
};
链表的操作可以通用,都是操作struct list_head *型。
bus_register()
linux内核驱动模型的更多相关文章
- Linux Platform驱动模型(二) _驱动方法
在Linux设备树语法详解和Linux Platform驱动模型(一) _设备信息中我们讨论了设备信息的写法,本文主要讨论平台总线中另外一部分-驱动方法,将试图回答下面几个问题: 如何填充platfo ...
- Linux设备驱动模型之platform(平台)总线详解
/********************************************************/ 内核版本:2.6.35.7 运行平台:三星s5pv210 /*********** ...
- LINUX设备驱动模型之class
转自 https://blog.csdn.net/qq_20678703/article/details/52754661 1.LINUX设备驱动模型中的bus.device.driver,.其中bu ...
- Linux设备驱动模型底层架构及组织方式
1.什么是设备驱动模型? 设备驱动模型,说实话这个概念真的不好解释,他是一个比较抽象的概念,我在网上也是没有找到关于设备驱动模型的一个定义,那么今天就我所学.所了解 到的,我对设备驱动模型的一个理解: ...
- 探究linux设备驱动模型之——platform虚拟总线(一)
说在前面的话 : 设备驱动模型系列的文章主要依据的内核版本是2.6.32的,因为我装的Linux系统差不多就是这个版本的(实际上我用的fedora 14的内核版本是2.6.35.13的.) ...
- Linux Platform驱动模型(二) _驱动方法【转】
转自:http://www.cnblogs.com/xiaojiang1025/archive/2017/02/06/6367910.html 在Linux设备树语法详解和Linux Platform ...
- Linux 设备驱动模型
Linux系统将设备和驱动归一到设备驱动模型中了来管理 设备驱动程序功能: 1,对硬件设备初始化和释放 2,对设备进行管理,包括实参设置,以及提供对设备的统一操作接口 3,读取应用程序传递给设备文件的 ...
- linux设备驱动模型之Kobject、kobj_type、kset【转】
本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/74838165 版权声明:本文为博主原创文章,转载请注明http://blog.c ...
- Linux设备驱动模型简述(源码剖析)
1. Linux设备驱动模型和sysfs文件系统 Linux内核在2.6版本中引入设备驱动模型,简化了驱动程序的编写.Linux设备驱动模型包含设备(device).总线(bus).类(class)和 ...
随机推荐
- java_IO读写模版
InputStream in = null; OutputStream out = null; try{ in = new FileInputStream(); int len=0; byte buf ...
- posix thread概述
1. 基本概念 一个Unix进程可以理解为一个线程加上地址空间.文件描述符和其他数据.异步表明事情相互独立发生, 除非有强加的依赖性. 并发指实际可能是穿行发生的事情好像同时发生一样.并行指并发序列同 ...
- Python基础:1.数据类型(空、布尔类型、整型、长整型、浮点型、字符串)
提示:python版本2.7,windows系统 Python提供的基本数据类型:空.布尔类型.整型.长整型.浮点型.字符串.列表.元组.字典.日期 1.空(None) None,是一个特殊的值,不能 ...
- CentOS下安装福昕PDF软件
官方下载地址:http://www.foxitsoftware.cn/downloads/ tar -jxvf foxreader.tar.bz2问题:下载官方包以后解压,双击不能打开,也没有任何提示 ...
- 修改Atom 隐藏.gitignore忽略的文件/文件夹的配置
参考链接:.gitignored files are hidden from tree view regardless of setting 假如Atom打开的文件夹有.gitignore 文件,会隐 ...
- videojs 动态加载视频
VideoJS dynamic source change via RESTful API 'Undefined' issue with changing RTMP source on compres ...
- [转]分布式系统为什么需要 Tracing?
分布式系统为什么需要 Tracing? 先介绍一个概念:分布式跟踪,或分布式追踪. 电商平台由数以百计的分布式服务构成,每一个请求路由过来后,会经过多个业务系统并留下足迹,并产生对各种Cach ...
- 对css float 浮动的学习心得
css float浮动详解 @(css float)[hasLayout|clear float|妙瞳] css float的定义和用法 float 属性定义元素在哪个方向浮动.以往这个属性总应用于图 ...
- 一点关于this的理解
关于this,是很多前端面试必考的题目,有时候在网上看到这些题目,自己试了一下,额,还真的错了!在实际开发中,也会遇到 this 的问题(虽然一些类库会帮我们处理),例如在使用一些框架的时候,例如:k ...
- 在ASP中限制同一表单被多次提交
本文介绍在ASP应用中防止用户在当前会话期间多次提交同一表单的一个简单方法.它主要由四个子程序组成,在较为简单的应用场合,你只要将这些代码放在包含文件中直接引用即可:对于那些较为复杂的环境,我们在文章 ...