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)和 ...
随机推荐
- 无法找到AdbWinApi.dll问题解决 .
无法找到AdbWinApi.dll问题解决: 1. 现象: 在运行程序时,显示“无法启动此程序,因为丢失AdbWinApi.dll”.2. 解决方法: 到SDK的platform-tools和 ...
- CSS3 旋转的八卦图
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 在IOS中 NSRange类详解
NSRange的定义 typedef struct _NSRange { NSUInteger location; NSUInteger length; } NSRange; NSRange是一个结构 ...
- 关于jQuery源码中(function(window,undefined){//dosomething()})(window)写法解释
一.首先是最常见的闭包 (Closure) 范式自执行函数的写法,这里用匿名函数封装(构造块级作用域),避免了匿名函数内部的代码与外部之间发生冲突(如使用了相同的变量名). (function() { ...
- bvp4c--语法
bvp4c--语法 1. bvp4c: sol = bvp4c(odefun,bcfun,solinit) sol = bvp4c(odefun,bcfun,solinit,options) so ...
- B/S一些小知识及常用控件
一: B/S网页的运行 页面在设计的时候,本身就是一个类.在运行的时间,是一个对象. 其中aspx和aspx.cs是在同一个类下. aspx是主要是负责界面,而aspx.cs主要是负责数据逻辑. 呈现 ...
- hdu 1040 As Easy As A+B
As Easy As A+B Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- PHP自动执行程序
/****config.php***/ <?php return 1; //需要停止时改成0 ?> /******************/ ignore_user_abort();//关 ...
- elfinder-2.x的java servlet后端——elfinder-2.x-servlet
去年在美期间在外导的项目中,需要用到el-finder的完美界面,但苦于没有java后端,因此做了一个elfinder-2.x-servlet. 托管地址:https://github.com/blu ...
- C# 调试程序弹出 没有可用于当前位置的源代码 对话框
解决方案: 1.右键点击解决方案->属性->通用属性->调试源文件. 2.看看你的程序有没有被增加到“不查找这些源文件”这个框里. 3.如果有删除,然后重新编译即可调试,解决问题.