歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux內核 >> Linux內核 簡化版kset-example.c解析

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

日期:2017/3/1 10:49:36   编辑:Linux內核
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. #include <linux/kobject.h>
  8. #include <linux/string.h>
  9. #include <linux/sysfs.h>
  10. #include <linux/slab.h>
  11. #include <linux/module.h>
  12. #include <linux/init.h>
  13. /*
  14. * 將要創建的文件foo對應的kobj.
  15. */
  16. struct foo_obj {
  17. struct kobject kobj;
  18. int foo;
  19. int baz;
  20. int bar;
  21. };
  22. /* 通過域成員返回結構體的指針 */
  23. #define to_foo_obj(x) container_of(x, struct foo_obj, kobj)
  24. /* 屬性 */
  25. struct foo_attribute {
  26. struct attribute attr;
  27. ssize_t (*show)(struct foo_obj *foo, struct foo_attribute *attr, char *buf);
  28. ssize_t (*store)(struct foo_obj *foo, struct foo_attribute *attr, const char *buf, size_t count);
  29. };
  30. #define to_foo_attr(x) container_of(x, struct foo_attribute, attr)
  31. /*
  32. * 屬性foo信息顯示函數 (涉及文件目錄foo/)
  33. */
  34. static ssize_t foo_attr_show(struct kobject *kobj,
  35. struct attribute *attr,
  36. char *buf)
  37. {
  38. struct foo_attribute *attribute;
  39. struct foo_obj *foo;
  40. attribute = to_foo_attr(attr);
  41. foo = to_foo_obj(kobj);
  42. if (!attribute->show)
  43. return -EIO;
  44. return attribute->show(foo, attribute, buf);
  45. }
  46. /*
  47. * 屬性foo存儲函數(涉及文件目錄foo/) (when a value is written to a file.)
  48. */
  49. static ssize_t foo_attr_store(struct kobject *kobj,
  50. struct attribute *attr,
  51. const char *buf, size_t len)
  52. {
  53. struct foo_attribute *attribute;
  54. struct foo_obj *foo;
  55. attribute = to_foo_attr(attr);
  56. foo = to_foo_obj(kobj);
  57. if (!attribute->store)
  58. return -EIO;
  59. return attribute->store(foo, attribute, buf, len);
  60. }
  61. /*
  62. * foo的show/store列表
  63. */
  64. static const struct sysfs_ops foo_sysfs_ops = {
  65. .show = foo_attr_show,
  66. .store = foo_attr_store,
  67. };
  68. /*
  69. * The release function for our object. This is REQUIRED by the kernel to
  70. * have. We free the memory held in our object here.
  71. */
  72. static void foo_release(struct kobject *kobj)
  73. {
  74. struct foo_obj *foo;
  75. foo = to_foo_obj(kobj);
  76. kfree(foo);
  77. }
  78. /*
  79. * 當需要從foo文件中讀取信息時,調用此函數
  80. */
  81. static ssize_t foo_show(struct foo_obj *foo_obj, struct foo_attribute *attr,
  82. char *buf)
  83. {
  84. return sprintf(buf, "%d\n", foo_obj->foo);
  85. }
  86. /*
  87. * 當往foo文件寫入信息時,調用此函數
  88. */
  89. static ssize_t foo_store(struct foo_obj *foo_obj, struct foo_attribute *attr,
  90. const char *buf, size_t count)
  91. {
  92. sscanf(buf, "%du", &foo_obj->foo);
  93. return count;
  94. }
  95. static struct foo_attribute foo_attribute =
  96. __ATTR(foo, 0666, foo_show, foo_store);
  97. /*
  98. * foo_ktype的屬性列表
  99. */
  100. static struct attribute *foo_default_attrs[] = {
  101. &foo_attribute.attr,
  102. NULL, /* need to NULL terminate the list of attributes */
  103. };
  104. /*
  105. * 定義kobj_type結構體
  106. * 指定sysfs_ops,release函數, 屬性列表foo_default_attrs
  107. */
  108. static struct kobj_type foo_ktype = {
  109. .sysfs_ops = &foo_sysfs_ops,
  110. .release = foo_release,
  111. .default_attrs = foo_default_attrs,
  112. };
  113. static struct kset *example_kset;
  114. static struct foo_obj *foo_obj;
  115. static struct foo_obj *create_foo_obj(const char *name)
  116. {
  117. struct foo_obj *foo;
  118. int retval;
  119. /* allocate the memory for the whole object */
  120. foo = kzalloc(sizeof(*foo), GFP_KERNEL);
  121. if (!foo)
  122. return NULL;
  123. foo->kobj.kset = example_kset;
  124. /*
  125. * 初始化kobject數據結結構foo->lobj,
  126. * 即 在foo->kobj的層次組織kset中創建個名為name的文件foo/foo
  127. * 成功返回0
  128. */
  129. retval = kobject_init_and_add(&foo->kobj, &foo_ktype, NULL, "%s", name);
  130. if (retval) {
  131. /* 減小kobj的引用計數 */
  132. kobject_put(&foo->kobj);
  133. return NULL;
  134. }
  135. /*
  136. * 發送 KOBJ_ADD / KOBJ_REMOVE 等事件
  137. * We are always responsible for sending the uevent that the kobject
  138. * was added to the system.
  139. */
  140. kobject_uevent(&foo->kobj, KOBJ_ADD);
  141. return foo;
  142. }
  143. static void destroy_foo_obj(struct foo_obj *foo)
  144. {
  145. /* 減小kobj的引用計數 */
  146. kobject_put(&foo->kobj);
  147. }
  148. static int __init example_init(void)
  149. {
  150. /*
  151. * 動態地在kernel_kobj所對應的目錄/sys/kernel/下創建一個目錄kset_example
  152. * 並返回kset_example對應的kset
  153. */
  154. example_kset = kset_create_and_add("kset_example", NULL, kernel_kobj);
  155. if (!example_kset)
  156. return -ENOMEM;
  157. foo_obj = create_foo_obj("foo");
  158. if (!foo_obj)
  159. goto foo_error;
  160. return 0;
  161. foo_error:
  162. return -EINVAL;
  163. }
  164. static void __exit example_exit(void)
  165. {
  166. destroy_foo_obj(foo_obj);
  167. kset_unregister(example_kset);
  168. }
  169. module_init(example_init);
  170. module_exit(example_exit);
  171. MODULE_LICENSE("GPL");
  172. MODULE_AUTHOR("lewiyon <[email protected]>");
Copyright © Linux教程網 All Rights Reserved