linux设备驱动模型(kobject与kset)
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结构。
- #include <linux/kobject.h>
- struct kset {
- struct list_head list; /* 用于连接kset中所有kobject的链表头 */
- spinlock_t list_lock; /* 扫描kobject组成的链表时使用的锁 */
- struct kobject kobj; /* 嵌入的kobject */
- const struct kset_uevent_ops *uevent_ops; /* kset的uevent操作 */
- };
实例:
#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)的更多相关文章
- Linux设备驱动之Kobject、Kset
作者:lizuobin(也是我们兼职的论坛答疑助手) 原文: https://blog.csdn.net/lizuobin2/article/details/51523693 纠结又纠结,虽然看了一些 ...
- linux设备驱动模型之Kobject、kobj_type、kset【转】
本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/74838165 版权声明:本文为博主原创文章,转载请注明http://blog.c ...
- 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 设备驱动模型
Linux系统将设备和驱动归一到设备驱动模型中了来管理 设备驱动程序功能: 1,对硬件设备初始化和释放 2,对设备进行管理,包括实参设置,以及提供对设备的统一操作接口 3,读取应用程序传递给设备文件的 ...
- Linux设备驱动模型简述(源码剖析)
1. Linux设备驱动模型和sysfs文件系统 Linux内核在2.6版本中引入设备驱动模型,简化了驱动程序的编写.Linux设备驱动模型包含设备(device).总线(bus).类(class)和 ...
- 探究linux设备驱动模型之——platform虚拟总线(一)
说在前面的话 : 设备驱动模型系列的文章主要依据的内核版本是2.6.32的,因为我装的Linux系统差不多就是这个版本的(实际上我用的fedora 14的内核版本是2.6.35.13的.) ...
- linux设备驱动模型
尽管LDD3中说对多数程序员掌握设备驱动模型不是必要的,但对于嵌入式Linux的底层程序员而言,对设备驱动模型的学习非常重要. Linux设备模型的目的:为内核建立一个统一的设备模型,从而又一个对系统 ...
随机推荐
- 电商ERP如何接入智选物流平台?
智选物流是综合地址库+时效库+逻辑库(成本.订单属性.仓库)选择出最优快递,通过多家快递网点地址库精准数据,点对点的运输时间,各种行业包裹的所有快递价格逻辑,不同产品类型.支付方式等分析,实现不同仓库 ...
- Columbus’s bargain
Columbus’s bargain Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- CSS 实现行内和上下自适应的几种方法
在写一个移动端网页,发现网页的头部搜索框两边各有固定宽度的按钮,搜索框可以根据宽度的变化来改变自己的宽度,达到填充的目的,也就是一种自适应吧,下面写写自己尝试的几种方法 一 利用css3 的width ...
- 邮件工具类--EmailUtil
/* Copyright Notice ===================================================* * This file contains propri ...
- asp.net session容易丢失解决方案
web Form 网页是基于HTTP的,它们没有状态, 这意味着它们不知道所有的请求是否来自 同一台客户端计算机,网页是受到了破坏,以及是否得到了刷新,这样就可能造成信息的 丢失. 于是, 状态管理就 ...
- linux 主机免验证登录
1.ssh-keygen -t [rsa|dsa],将会生成密钥文件和私钥文件 id_rsa,id_rsa.pub或id_dsa,id_dsa.pub 2.scp -p port ~/.ssh/id ...
- Ionic中弹窗
Ionic中弹窗有两种ionicModal和ionicPopup; $ionicModal是完整的页面: $ionicPopup是(Dialog)对话框样式的,直接用JavaScript设定对话框的一 ...
- CF Tavas and Karafs (二分)
Tavas and Karafs time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- LeetCode 3
Longest Substring Without Repeating Characters Given a string, find the length of the longest substr ...
- Scala中的If判断&While&For循环
If 判断: object TestScalaIf { def main(args: Array[String]): Unit = { // val resutlt = judge1(-100) // ...