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内核驱动模型的更多相关文章

  1. Linux Platform驱动模型(二) _驱动方法

    在Linux设备树语法详解和Linux Platform驱动模型(一) _设备信息中我们讨论了设备信息的写法,本文主要讨论平台总线中另外一部分-驱动方法,将试图回答下面几个问题: 如何填充platfo ...

  2. Linux设备驱动模型之platform(平台)总线详解

    /********************************************************/ 内核版本:2.6.35.7 运行平台:三星s5pv210 /*********** ...

  3. LINUX设备驱动模型之class

    转自 https://blog.csdn.net/qq_20678703/article/details/52754661 1.LINUX设备驱动模型中的bus.device.driver,.其中bu ...

  4. Linux设备驱动模型底层架构及组织方式

    1.什么是设备驱动模型? 设备驱动模型,说实话这个概念真的不好解释,他是一个比较抽象的概念,我在网上也是没有找到关于设备驱动模型的一个定义,那么今天就我所学.所了解 到的,我对设备驱动模型的一个理解: ...

  5. 探究linux设备驱动模型之——platform虚拟总线(一)

    说在前面的话 :      设备驱动模型系列的文章主要依据的内核版本是2.6.32的,因为我装的Linux系统差不多就是这个版本的(实际上我用的fedora 14的内核版本是2.6.35.13的.) ...

  6. Linux Platform驱动模型(二) _驱动方法【转】

    转自:http://www.cnblogs.com/xiaojiang1025/archive/2017/02/06/6367910.html 在Linux设备树语法详解和Linux Platform ...

  7. Linux 设备驱动模型

    Linux系统将设备和驱动归一到设备驱动模型中了来管理 设备驱动程序功能: 1,对硬件设备初始化和释放 2,对设备进行管理,包括实参设置,以及提供对设备的统一操作接口 3,读取应用程序传递给设备文件的 ...

  8. linux设备驱动模型之Kobject、kobj_type、kset【转】

    本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/74838165 版权声明:本文为博主原创文章,转载请注明http://blog.c ...

  9. Linux设备驱动模型简述(源码剖析)

    1. Linux设备驱动模型和sysfs文件系统 Linux内核在2.6版本中引入设备驱动模型,简化了驱动程序的编写.Linux设备驱动模型包含设备(device).总线(bus).类(class)和 ...

随机推荐

  1. Jordan Lecture Note-3: 梯度投影法

    Jordan Lecture Note-3:梯度投影法 在这一节,我们介绍如何用梯度投影法来解如下的优化问题: \begin{align} \mathop{\min}&\quad f(x)\n ...

  2. 【思考】由安装zabbix至排障php一系列引发的思考

    [思考]由安装zabbix至排障php一系列引发的思考 linux的知识点林立众多,很有可能你在排查一个故障的时候就得用到另一门技术的知识: 由于linux本身的应用依赖的库和其它环境环环相扣,但又没 ...

  3. 用CentOS 7打造合适的科研环境

    http://seisman.info/linux-environment-for-seismology-research.html 这篇博文记录了我用CentOS 7搭建地震学科研环境的过程,供我个 ...

  4. 开始学习HTML5

    今天学习了HTML的一些知识,从一本<HTML5网页设计案例课堂>开始.逐步了解从最早的网页的一直到现在HTML5的过程.现在到了最新版HTML5 从这本书中基本学习到了以下内容: HTM ...

  5. Python(2.7.6) 迭代器

    除了对列表.集合和字典等进行迭代,还能对其他对象进行迭代:实现 __iter__ 方法的对象.例如, 文件对象就是可迭代的: >>> dir(file) ['__class__', ...

  6. ASP.Net Core 运行在Linux(Ubuntu)

    这段时间一直在研究asp.net core部署到linux,今天终于成功了,这里分享一下我的部署过程. Linux Disibutaion:Ubuntu 14.04 Web Server:nginx. ...

  7. [转]十年前的老文:以 Linux 的名义

    一.灰姑娘的狂欢 今年初,林纳斯·托瓦兹承认:“如果在12年前,有人告诉我Linux会发展到今天的模样,我肯定会惊得目瞪口呆.” 托瓦兹说的是实话.1991年,这名21岁的芬兰赫尔辛基大学的学生,偶然 ...

  8. Hql 中实用查询时候 引号的使用

    出错代码://List vlist = this.getHibernateTemplate().find("from AndroidCustomer ct where ct.token = ...

  9. Linq 查询 与方法调用

    通常,使用linq查询时需要一个实现IQueryable<T> 的查询对象 public class DataA<T> : IQueryable<T> {....} ...

  10. (转)QRCODE二维码介绍及常用控件推荐

    什么是QR Code码? QR Code码是由日本Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字及图象多种文字信息.保密防 ...