linux内核驱动模型

时间:2022-09-30 21:38:31

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. UML中的六大关系(转)

    UML定义的关系主要有六种:依赖.继承.关联.实现.聚合和组合.这些类间关系的理解和使用是掌握和应用UML的关键,而也就是这几种关系,往往会让初学者迷惑.这里给出这六种主要UML关系的说明和类图描述, ...

  2. Linux基本操作命令总结

    1.命令基本格式     root用户:[root@localhost ~] # 或者普通用户:[hadoop@localhost ~] $     用户@主机名 目录 [#|$]管理员类型     ...

  3. DAG上的动态规划之嵌套矩形

    题意描述:有n个矩形,每个矩形可以用两个整数a.b描述,表示它的长和宽, 矩形(a,b)可以嵌套在矩形(c,d)当且仅当a<c且b<d, 要求选出尽量多的矩形排成一排,使得除了最后一个外, ...

  4. spring 方法注入

    package com.haut.grain.junit.test; public  class Command {private Object state;public void setState( ...

  5. C&plus;&plus; 设计模式2 (面向对象设计原则)

    1. 变化是复用的天敌! 面向对象设计的最大优势在于 : 抵御变化 2. 重新认识面向对象 理解隔离变化: 从宏观层面来看,面向对象的构建方式更能适应软件的变化, 能将变化所带来的影响减为最小. 各司 ...

  6. eclipse - copy类的全名

    由于多次操作,感觉eclipse应该提供这个功能,网上搜一下,发现需要安装插件. 下载地址为 http://www.jave.de/eclipse/copyfully/copyfully_1.2.0. ...

  7. 如何构建高性能web网站:分布式缓存

    一.数据库前端缓冲区 要清除数据库前缓冲区,首先必须明确什么是文件系统的内核缓冲区(Buffer Area):它位于内核的物理内存地址空间,除了使用O_DIRECT比其他标签中打开文件,所有的磁盘的读 ...

  8. &lbrack;C&num;&rsqb;使用Process的StandardInput与StandardOutput写入读取控制台数据

    本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 开发工具:VS2017 语言:C# DotNet版本:.Net FrameWork 4.0及以 ...

  9. Angular之ngRoute与uiRoute

    ngRoute不支持嵌套路由 用法如下: <!DOCTYPE html> <html lang="en" ng-app="myApp"> ...

  10. (二十)即时通信的聊天气泡的实现I

    Tip:通过xib和storyboard不可能将一个控件作为ImageView的子控件,只能通过代码的addSubview方法实现. 设置图片的细节:如果button比图片大(为了方便对齐),将图片设 ...