Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1132094
  • 博文数量: 300
  • 博客积分: 37
  • 博客等级: 民兵
  • 技术积分: 772
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-26 04:46
文章分类
文章存档

2017年(4)

2016年(7)

2015年(19)

2014年(72)

2013年(71)

2012年(127)

分类:

2012-07-31 21:56:55

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所管理的kobjectkset状态发生变化时(如被加入,移动),这三个函数将被调用。

Filter:决定是否将事件传递到用户空间。如果filter返回0,将不传递事件。

Name:负责将相应的字符串传递给用户空间的热插拔处理程序。

Uevent:将用户空间需要的参数添加到环境变量中。

int (*uevent)(struct kset *kset,

struct kobject *kobj, /*产生事件的目标对象*/

char **envp, /*一个保存其他环境变量定义(通常为NAME=value的格式)的数组*/

int num_envp, /*环境变量数组中包含的变量数(数组大小)*/

char *buffer, int buffer_size/*环境变量被放入的缓冲区的指针和字节数*/

);/*返回值正常时是,若返回非零值将终止热插拔事件的产生*/


实例源码: temp.rar    


点击(此处)折叠或打开

  1. /**
  2.  * 热插拔事件
  3.  * Lzy    2012-7-27
  4.  */
  5. #include <linux/device.h>
  6. #include <linux/module.h>
  7. #include <linux/kernel.h>
  8. #include <linux/init.h>
  9. #include <linux/string.h>
  10. #include <linux/sysfs.h>
  11. #include <linux/stat.h>
  12. #include <linux/kobject.h>


  13. static struct attribute test_attr =
  14. {
  15.         .name = "kobj_config",
  16.         .mode = S_IRWXUGO,
  17. };

  18. static struct attribute *def_attrs[] =
  19. {
  20.         &test_attr,
  21.         NULL,
  22. };

  23. ssize_t kobj_test_show(struct kobject *kobject,struct attribute *attr,char *buf)
  24. {
  25.         printk("Have show -->\n");
  26.         printk("attrname: %s.\n",attr->name);
  27.         sprintf(buf,"%s\n",attr->name);
  28.         return strlen(attr->name) + 2;
  29. }

  30. ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr, const char *buf,size_t size)
  31. {
  32.         printk("Have store -->\n");
  33.         printk("write: %s.\n",buf);
  34.         return size;
  35. }

  36. static struct sysfs_ops obj_test_sysops =
  37. {
  38.         .show = kobj_test_show,
  39.         .store = kobj_test_store,        
  40. };


  41. void obj_test_release(struct kobject *kobject)
  42. {
  43.         printk("[kobj_test: release!]\n");
  44. }

  45. static struct kobj_type ktype =
  46. {
  47.         .release = obj_test_release,
  48.         .sysfs_ops = &obj_test_sysops,
  49.         .default_attrs = def_attrs,
  50. };



  51. static int kset_filter(struct kset *kset,struct kobject *kobj)
  52. {
  53. //    int ret=0;
  54. //    struct kobj_type *ktype = get_ktype(kobj); /* 得到属性类型 */
  55. //    ret = (ktype == &ktype_part);

  56.     printk("Filter: kobj %s.\n",kobj->name);
  57.     
  58.     return 1;
  59. }

  60. static const char *kset_name(struct kset *kset,struct kobject *kobj)
  61. {    
  62.     static char buf[20];


  63. /*    struct device *dev = to_dev(kobj);
  64.     if(dev->bus)
  65.         return dev->bus->name;
  66.     else if(dev->class)
  67.         return dev->class->name;
  68.     else
  69. */    {
  70.         printk("Name kobj %s.\n",kobj->name);
  71.         sprintf(buf,"%s","kset_name");
  72.     }
  73.     
  74.     return buf;
  75. }


  76. static int kset_uevent(struct kset *kset,struct kobject *kobj, struct kobj_uevent_env *env)
  77. {
  78.     int i = 0;
  79.     printk("uevent: kobj %s.\n",kobj->name);

  80.     while(i < env->envp_idx)
  81.     {
  82.         printk("%s.\n",env->envp[i]);
  83.         i ++;
  84.     }

  85.     return 0;
  86. }

  87. static struct kset_uevent_ops uevent_ops =
  88. {
  89.     .filter = kset_filter,
  90.     .name = kset_name,
  91.     .uevent = kset_uevent,
  92. };


  93. struct kset *kset_p;
  94. struct kset kset_c;

  95. static int __init kset_test_init(void)
  96. {
  97.     int ret = 0;

  98.     printk("kset test init!\n");
  99.     
  100.     /* 创建并注册 kset_p */
  101.     kset_p = kset_create_and_add("kset_p", &uevent_ops, NULL);    
  102.     
  103.     kobject_set_name(&kset_c.kobj,"kset_c");
  104.     kset_c.kobj.kset = kset_p;    /* 添加 kset_c 到 kset_p */

  105.     /* 对于较新版本的内核,在注册 kset 之前,需要
  106.          * 填充 kset.kobj 的 ktype 成员,否则注册不会成功 */
  107.     kset_c.kobj.ktype = &ktype;
  108.     ret = kset_register(&kset_c);

  109.     if(ret)
  110.         kset_unregister(kset_p);
  111.     
  112.     return ret;
  113. }


  114. static void __exit kset_test_exit(void)
  115. {
  116.     printk("kset test exit!\n");
  117.     
  118.     kset_unregister(&kset_c);
  119.     kset_unregister(kset_p);
  120. }

  121. module_init(kset_test_init);
  122. module_exit(kset_test_exit);

  123. MODULE_AUTHOR("Lzy");
  124. MODULE_LICENSE("GPL");


 

阅读(7830) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~