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

[2] http://blog.csdn.net/absurd/article/details/1587938

posted @ 2012-05-28 16:26  sky-zhang  阅读(776)  评论(0编辑  收藏  举报