Linux设备模型的目的:为内核建立一个统一的设备模型,从而又一个对系统结构的一般性抽象描述。换句话说,Linux设备模型提取了设备操作的共同属性,进行抽象,并将这部分共同的属性在内核中实现,而为需要新添加设备或驱动提供一般性的统一接口,这使得驱动程序的开发变得更简单了,而程序员只需要去学习接口就行了。

                                     kobject                                                                                                                                   

1.sysfs文件系统

  1.1 sysfs文件系统与内核结构的关系

linux内核中的结构 sysfs中的结构             
kobject (内核对象) 目录  
kobj_type (属性)  属性文件
对象之间的关系 符号链接

  1.2 sysfs文件系统的目录结构

block:所有块设备

devices:系统所有设备(块设备特殊),对应struct device的层次结构

bus:系统中所有总线类型(指总线类型而不是总线设备,总线设备在devices下),bus的每个子目录都包含

--devices:包含到devices目录中设备的软链接

--drivers:与bus类型匹配的驱动程序

class:系统中设备类型(如声卡、网卡、显卡等)

fs:一些文件系统,具体可参考filesystems /fuse.txt中例子

dev:包含2个子目录

--char:字符设备链接,链接到devices目录,以<major>:<minor>命名

--block:块设备链接

2.设备驱动模型的核心数据结构

2.1 kobject结构体

  

  name 将显示在sysfs文件系统中,作为一个目录的名字;

  struct kobj_type *ktype 代表kobject的属性,对于sysfs中的普通文件读写操作都是kobjetc->ktype->sysfs_ops指针来完成的,即对default_attrs数组的操作。

  kobject始终是sysfs文件系统中的一个目录而不是文件。

2.2设备属性kobj_type

  下图是kobject与kobj_type的关系:

  

  kobj_type结构体的定义如下:

struct kobj_type {
void (*release)(struct kobject *kobj);//释放kobject和其他占用资源的函数
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);
};

  【1】attribute结构体如下:

struct attribute {
const char *name;//属性名字
struct module *owner;//
mode_t mode;//属性的读写权限
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lock_class_key *key;
struct lock_class_key skey;
#endif
};

  【2】sysfs_ops 属性操作结构体: 

struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *,char *);//读属性
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);//写属性
};

  【3】release()函数

    当kobject的引用计数为0时,系统自动会调用自定义的release()来释放kobject对象。

    e.g.

      

3.实例:

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/stat.h> MODULE_AUTHOR("David Xie");
MODULE_LICENSE("Dual BSD/GPL"); void obj_test_release(struct kobject *kobject);
ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf);
ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count); struct attribute test_attr = {
.name = "kobj_config",
.mode = S_IRWXUGO,
}; static struct attribute *def_attrs[] = {
&test_attr,
NULL,
}; struct sysfs_ops obj_test_sysops =
{
.show = kobj_test_show,
.store = kobj_test_store,
}; struct kobj_type ktype =
{
.release = obj_test_release,
.sysfs_ops=&obj_test_sysops,
.default_attrs=def_attrs,
}; void obj_test_release(struct kobject *kobject)
{
printk("eric_test: release .\n");
} ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf)
{
printk("have show.\n");
printk("attrname:%s.\n", attr->name);
sprintf(buf,"%s\n",attr->name);
return strlen(attr->name)+;
} ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count)
{
printk("havestore\n");
printk("write: %s\n",buf);
return count;
} struct kobject kobj;
static int kobj_test_init()
{
printk("kboject test init.\n");
kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test");
return ;
} static int kobj_test_exit()
{
printk("kobject test exit.\n");
kobject_del(&kobj);
return ;
} module_init(kobj_test_init);
module_exit(kobj_test_exit);

kset

kset是具有相同类型的kobject的集合,在sysfs中体现成一个目录;kobject不能包含目录,而kset可以包含目录。kobject通过kset组织成层次化的结构,kset将一系列相同类型的kobject使用(双向)链表连接起来,可以这样 认为,kset充当链表头作用,kset内部内嵌了一个kobject结构。

    1. #include <linux/kobject.h>
    2. struct kset {
    3. struct list_head list; /* 用于连接kset中所有kobject的链表头 */
    4. spinlock_t list_lock; /* 扫描kobject组成的链表时使用的锁 */
    5. struct kobject kobj; /* 嵌入的kobject */
    6. const struct kset_uevent_ops *uevent_ops; /* kset的uevent操作 */
    7. };

实例:

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/stat.h>
#include <linux/kobject.h> MODULE_AUTHOR("David Xie");
MODULE_LICENSE("Dual BSD/GPL"); struct kset kset_p;
struct kset kset_c; int kset_filter(struct kset *kset, struct kobject *kobj)
{
printk("Filter: kobj %s.\n",kobj->name);
return ;
} const char *kset_name(struct kset *kset, struct kobject *kobj)
{
static char buf[];
printk("Name: kobj %s.\n",kobj->name);
sprintf(buf,"%s","kset_name");
return buf;
} int kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env)
{
int i = ;
printk("uevent: kobj %s.\n",kobj->name); while( i < env->envp_idx){
printk("%s.\n",env->envp[i]);
i++;
} return ;
} struct kset_uevent_ops uevent_ops =
{
.filter = kset_filter,
.name = kset_name,
.uevent = kset_uevent,
}; int kset_test_init()
{
printk("kset test init.\n");
kobject_set_name(&kset_p.kobj,"kset_p");
kset_p.uevent_ops = &uevent_ops;
kset_register(&kset_p);
printk("kset_p finish\n"); /*下面会调用热插拔函数*/
kobject_set_name(&kset_c.kobj,"kset_c");
kset_c.kobj.kset = &kset_p;
kset_register(&kset_c);
return ;
} int kset_test_exit()
{
printk("kset test exit.\n");
kset_unregister(&kset_p);
kset_unregister(&kset_c);
return ;
} module_init(kset_test_init);
module_exit(kset_test_exit);

热插拔事件kset_uevent_ops

在Linux系统中,当系统配置发生变化时,如:添加kset到系统;移动kobject, 一个通知会从内核空间发送到用户空间,这就是热插拔事件。热插拔事件会导致用户空间中相应的处理程序(如udev,mdev)被调用, 这些处理程序会通过加载驱动程序, 创建设备节点等来响应热插拔事件。

Struct kset_uevent_ops {
int (*filter)(struct kset *kset, struct kobject *kobj);
const char *(*name)(struct kset *kset, struct kobject *kobj);
int (*uevent)(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env);
}

当该kset所管理的kobject和kset状态发生变化时(如被加入,移动),这三个函数将被调用。

                     kobject与kset的关系                                                                                                                               

参考:http://blog.csdn.net/xiahouzuoxin/article/details/8943863

linux设备驱动模型(kobject与kset)的更多相关文章

  1. Linux设备驱动之Kobject、Kset

    作者:lizuobin(也是我们兼职的论坛答疑助手) 原文: https://blog.csdn.net/lizuobin2/article/details/51523693 纠结又纠结,虽然看了一些 ...

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

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

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

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

  4. LINUX设备驱动模型之class

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

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

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

  6. Linux 设备驱动模型

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

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

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

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

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

  9. linux设备驱动模型

    尽管LDD3中说对多数程序员掌握设备驱动模型不是必要的,但对于嵌入式Linux的底层程序员而言,对设备驱动模型的学习非常重要. Linux设备模型的目的:为内核建立一个统一的设备模型,从而又一个对系统 ...

随机推荐

  1. Linux编程之《守护进程》

    Intro ----- 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常 ...

  2. css笔记12:块元素和行内元素

    1.概念: 行内元素:又叫内联元素,内联元素只能容纳文本或者其他内联元素,常见的内联元素有<span><a> 块元素:块元素一般都是从新行开始,可容纳文本,其他内联元素和其他块 ...

  3. [课程相关]homework-03

    零.准备工作 这次的作业是结对编程,因为一些原因我们的队伍一共有三个人,成员为:梁杰.夏天晗.谢祖三.由于大家不在一个班,交流起来也不是特别方便,所以我们经过讨论决定三个人约一个时间在一起完成这次作业 ...

  4. CF Drazil and Date (奇偶剪枝)

    Drazil and Date time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  5. hdu 2844 多重背包+单调队列优化

    思路:把价值看做体积,而价值的大小还是其本身,那么只需判断1-m中的每个状态最大是否为自己,是就+1: #include<iostream> #include<algorithm&g ...

  6. 使用GBK编码请求访问nodejs程序报415错误:Error: unsupported charset at urlencodedParser ...

    最近遇到一个问题,第三方用户向我们提供给的回调地址发送请求时一直报415错误,结果发现他们使用的是GBK编码请求,而我们使用的node + express4 程序,不支持GBK编码请求. 问题出在下面 ...

  7. python截取中文字符串

    python的中文处理还是比较麻烦的,utf-8的字符串的长度是1-6个字符,一不小心就会从中截断,出现所谓的乱码.下面这个函数提供了,从一段utf-8编码的字符串中,截取固定长度的字串.ord(ch ...

  8. 用VS2015打开cshtml识图文件的时候会报错 如指定的文件不存在

    用vs2015打开cshtml识图文件的时候会报错.百度后得到解决方法如下: 先关闭VS2015, 拷贝:%LocalAppData%\Microsoft\VisualStudio\14.0\Comp ...

  9. ubuntu共享文件夹给virtualbox

    在ubuntu或者linuxmint等linux系统下安装了virtualbox,可以通过共享文件夹的方式,把文件夹共享给virtualbox下的虚拟机系统,我这里的虚拟机系统是win7,共享过程如下 ...

  10. 关于CSS的一些总结

    通过对CSS基础一天的学习以及练习,觉得自己以前还是蛮无知的,一直以为CSS样式是别人写好的,自己只需要像导包一样拿过来用就可以.直到自己认真学了之后才直到是什么样的.自己如果不去敲代码感觉永远都学不 ...