歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

Linux內核 簡化版kset-example.c解析

Linux內核 簡化版kset-example.c解析
  1. /********************************************** 
  2.  * Author: [email protected] 
  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 <[email protected]>");  
Copyright © Linux教程網 All Rights Reserved