Linux设备驱动---Kset
实验内核版本3.0.8
一个简单的kset测试代码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kobject.h>MODULE_LICENSE("Dual BSD/GPL");
/*
* struct kset {
* struct subsystem * subsys; 所在的subsystem的指针
* struct kobj_type * ktype; 指向该kset对象类型描述符的指针
* struct list_head list; 用于连接该kset中所有kobject的链表头
* struct kobject kobj; 嵌入的kobject
* struct kset_uevent_ops *uevent_ops; 指向热插拔操作表的指针
* };
*/
struct kset my_kset_parent;
struct kset my_kset_child;int my_kset_filter(struct kset *kset,struct kobject *kobj)
{
printk("===my_kset_filter===\n");
return 1; //返回1事事件可以上报
}
const char *my_kset_name(struct kset *kset, struct kobject *kobj )
{
static char buf[200]; //可以动态申请
printk("===my_kset_name is %s===\n", kobj->name);
sprintf(buf,"%s","what's this mean");return buf;
}int my_kset_uevent(struct kset *kset, struct kobject *kobj, struct kobj_uevent_env *env)
{
int i = 0;
printk("===my_kset_uevent===\n");
while(i<env->envp_idx)
{
printk("%s\n",env->envp[i++]);
}
return 0;
}/*
* struct kset_uevnt_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);
* }
*/
struct kset_uevent_ops my_uevent_ops =
{
.filter = my_kset_filter,
.name = my_kset_name,
.uevent = my_kset_uevent,
};struct kobj_type my_kobj_type ;
static int __init my_kset_init(void)
{
printk("===my_kset_init===\n");
kobject_set_name(&my_kset_parent.kobj,"my_keset_parent");
my_kset_parent.uevent_ops = &my_uevent_ops;
/* int kset_register(struct kset *kset); *///下面这句多余,是为了规避kernel oops bug
my_kset_parent.kobj.ktype = &my_kobj_type;
kset_register(&my_kset_parent);kobject_set_name(&my_kset_child.kobj,"my_kset_child");
my_kset_child.kobj.kset = &my_kset_parent;
my_kset_child.kobj.ktype = &my_kobj_type;
kset_register(&my_kset_child);return 0;
}static void __exit my_kset_exit(void)
{
printk("===my_kset_exit===\n");
kset_unregister(&my_kset_parent);
kset_unregister(&my_kset_child);
}module_init(my_kset_init);
module_exit(my_kset_exit);
运行结果:
执行sudo insmod XXX.ko后
===my_kset_init===
===my_kset_filter===
===my_kset_name is my_kset_child===
===my_kset_uevent===
ACTION=add
DEVPATH=/my_keset_parent/my_kset_child
SUBSYSTEM=what's this mean
执行sudo rmmod XXX后
===my_kset_exit===
===my_kset_filter===
===my_kset_name is my_kset_child===
===my_kset_uevent===
ACTION=remove
DEVPATH=/my_keset_parent/my_kset_child
SUBSYSTEM=what's this mean
注意:注册一个kobject不会产生事件,只有注册kset才会产生
当有热插拔事件发生时,hotplug机制是内核hotplug程序读取事件,再通知关心该事件的应用程序。hotplug机制已经基本被udev机制取代。
udev机制:监听内核通过NETLINK传递过来的事件,再根据/etc/udev/rules.d目录下对应的规则对ACTION采取对应的动作,例如如果ACTION=ADD,则查找/sys/DEVPATH下面的dev文件,读取其中的主次设备号信息添加设备节点。
参考文献:
Kset相关:
[1] http://blog.csdn.net/jianchi88/article/details/6997615
[2] http://www.serverphorums.com/read.php?12,483658
热插拔事件相关:
[1] http://hi.baidu.com/li32768/blog/item/378711dcc41f482e5882dd78.html