Linux内核 简化版kset-example.c解析


Linux内核 简化版kset-example.c解析
  1. /********************************************** 
  2.  * Author: lewiyon@hotmail.com 
  3.  * File name: kset_sample.c 
  4.  * Description: kset example 
  5.  * Date: 2011-12-10 
  6.  *********************************************/  
  7.   
  8. #include <linux/kobject.h>   
  9. #include <linux/string.h>   
  10. #include <linux/sysfs.h>   
  11. #include <linux/slab.h>   
  12. #include <linux/module.h>   
  13. #include <linux/init.h>   
  14.   
  15. /* 
  16.  * 将要创建的文件foo对应的kobj. 
  17.  */  
  18. struct foo_obj {  
  19.     struct kobject kobj;  
  20.     int foo;  
  21.     int baz;  
  22.     int bar;  
  23. };  
  24. /* 通过域成员返回结构体的指针 */  
  25. #define to_foo_obj(x) container_of(x, struct foo_obj, kobj)   
  26.   
  27. /* 属性 */  
  28. struct foo_attribute {  
  29.     struct attribute attr;  
  30.     ssize_t (*show)(struct foo_obj *foo, struct foo_attribute *attr, char *buf);  
  31.     ssize_t (*store)(struct foo_obj *foo, struct foo_attribute *attr, const char *buf, size_t count);  
  32. };  
  33. #define to_foo_attr(x) container_of(x, struct foo_attribute, attr)   
  34.   
  35. /* 
  36.  * 属性foo信息显示函数 (涉及文件目录foo/) 
  37.  */  
  38. static ssize_t foo_attr_show(struct kobject *kobj,  
  39.                  struct attribute *attr,  
  40.                  char *buf)  
  41. {  
  42.     struct foo_attribute *attribute;  
  43.     struct foo_obj *foo;  
  44.   
  45.     attribute = to_foo_attr(attr);  
  46.     foo = to_foo_obj(kobj);  
  47.   
  48.     if (!attribute->show)  
  49.         return -EIO;  
  50.   
  51.     return attribute->show(foo, attribute, buf);  
  52. }  
  53.   
  54. /* 
  55.  * 属性foo存储函数(涉及文件目录foo/) (when a value is written to a file.) 
  56.  */  
  57. static ssize_t foo_attr_store(struct kobject *kobj,  
  58.                   struct attribute *attr,  
  59.                   const char *buf, size_t len)  
  60. {  
  61.     struct foo_attribute *attribute;  
  62.     struct foo_obj *foo;  
  63.   
  64.     attribute = to_foo_attr(attr);  
  65.     foo = to_foo_obj(kobj);  
  66.   
  67.     if (!attribute->store)  
  68.         return -EIO;  
  69.   
  70.     return attribute->store(foo, attribute, buf, len);  
  71. }  
  72.   
  73. /*  
  74.  * foo的show/store列表 
  75.  */  
  76. static const struct sysfs_ops foo_sysfs_ops = {  
  77.     .show = foo_attr_show,  
  78.     .store = foo_attr_store,  
  79. };  
  80.   
  81. /* 
  82.  * The release function for our object.  This is REQUIRED by the kernel to 
  83.  * have.  We free the memory held in our object here. 
  84.  */  
  85. static void foo_release(struct kobject *kobj)  
  86. {  
  87.     struct foo_obj *foo;  
  88.   
  89.     foo = to_foo_obj(kobj);  
  90.     kfree(foo);  
  91. }  
  92.   
  93. /* 
  94.  * 当需要从foo文件中读取信息时,调用此函数 
  95.  */  
  96. static ssize_t foo_show(struct foo_obj *foo_obj, struct foo_attribute *attr,  
  97.             char *buf)  
  98. {  
  99.     return sprintf(buf, "%d\n", foo_obj->foo);  
  100. }  
  101.   
  102. /* 
  103.  * 当往foo文件写入信息时,调用此函数 
  104.  */  
  105. static ssize_t foo_store(struct foo_obj *foo_obj, struct foo_attribute *attr,  
  106.              const char *buf, size_t count)  
  107. {  
  108.     sscanf(buf, "%du", &foo_obj->foo);  
  109.     return count;  
  110. }  
  111.   
  112. static struct foo_attribute foo_attribute =  
  113.     __ATTR(foo, 0666, foo_show, foo_store);  
  114.   
  115. /* 
  116.  * foo_ktype的属性列表 
  117.  */  
  118. static struct attribute *foo_default_attrs[] = {  
  119.     &foo_attribute.attr,  
  120.     NULL,   /* need to NULL terminate the list of attributes */  
  121. };  
  122.   
  123. /* 
  124.  * 定义kobj_type结构体 
  125.  * 指定sysfs_ops,release函数, 属性列表foo_default_attrs 
  126.  */  
  127. static struct kobj_type foo_ktype = {  
  128.     .sysfs_ops = &foo_sysfs_ops,  
  129.     .release = foo_release,  
  130.     .default_attrs = foo_default_attrs,  
  131. };  
  132.   
  133. static struct kset *example_kset;  
  134. static struct foo_obj *foo_obj;  
  135.   
  136. static struct foo_obj *create_foo_obj(const char *name)  
  137. {  
  138.     struct foo_obj *foo;  
  139.     int retval;  
  140.   
  141.     /* allocate the memory for the whole object */  
  142.     foo = kzalloc(sizeof(*foo), GFP_KERNEL);  
  143.     if (!foo)  
  144.         return NULL;  
  145.   
  146.     foo->kobj.kset = example_kset;  
  147.   
  148.     /* 
  149.      * 初始化kobject数据结结构foo->lobj, 
  150.      * 即 在foo->kobj的层次组织kset中创建个名为name的文件foo/foo 
  151.      * 成功返回0 
  152.      */  
  153.     retval = kobject_init_and_add(&foo->kobj, &foo_ktype, NULL, "%s", name);  
  154.     if (retval) {  
  155.         /* 减小kobj的引用计数 */  
  156.         kobject_put(&foo->kobj);  
  157.         return NULL;  
  158.     }  
  159.   
  160.     /* 
  161.      * 发送 KOBJ_ADD / KOBJ_REMOVE 等事件 
  162.      * We are always responsible for sending the uevent that the kobject 
  163.      * was added to the system. 
  164.      */  
  165.     kobject_uevent(&foo->kobj, KOBJ_ADD);  
  166.   
  167.     return foo;  
  168. }  
  169.   
  170. static void destroy_foo_obj(struct foo_obj *foo)  
  171. {  
  172.     /* 减小kobj的引用计数 */  
  173.     kobject_put(&foo->kobj);  
  174. }  
  175.   
  176. static int __init example_init(void)  
  177. {  
  178.     /*  
  179.      * 动态地在kernel_kobj所对应的目录/sys/kernel/下创建一个目录kset_example 
  180.      * 并返回kset_example对应的kset 
  181.      */  
  182.     example_kset = kset_create_and_add("kset_example", NULL, kernel_kobj);  
  183.     if (!example_kset)  
  184.         return -ENOMEM;  
  185.   
  186.     foo_obj = create_foo_obj("foo");  
  187.     if (!foo_obj)  
  188.         goto foo_error;  
  189.   
  190.     return 0;  
  191.   
  192. foo_error:  
  193.     return -EINVAL;  
  194. }  
  195.   
  196. static void __exit example_exit(void)  
  197. {  
  198.     destroy_foo_obj(foo_obj);  
  199.     kset_unregister(example_kset);  
  200. }  
  201.   
  202. module_init(example_init);  
  203. module_exit(example_exit);  
  204. MODULE_LICENSE("GPL");  
  205. MODULE_AUTHOR("lewiyon <lewiyon@hotmail.com>");  

相关内容