sysfs.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. Adapted from: https://github.com/t3rm1n4l/kern-dev-tutorial/blob/1f036ef40fc4378f5c8d2842e55bcea7c6f8894a/05-sysfs/sysfs.c
  3. Vs procfs:
  4. - https://unix.stackexchange.com/questions/4884/what-is-the-difference-between-procfs-and-sysfs
  5. - https://stackoverflow.com/questions/37237835/how-to-attach-file-operations-to-sysfs-attribute-in-platform-driver
  6. This example shows how sysfs is more restricted, as it does not take a file_operations.
  7. So you basically can only do open, close, read, write, and lseek on sysfs files.
  8. It is kind of similar to a seq_file file_operations, except that write is also implemented.
  9. TODO: what are those kobject structs? Make a more complex example that shows what they can do.
  10. - https://www.kernel.org/doc/Documentation/kobject.txt
  11. - https://www.quora.com/What-are-kernel-objects-Kobj
  12. - http://www.makelinux.net/ldd3/chp-14-sect-1
  13. - https://www.win.tue.nl/~aeb/linux/lk/lk-13.html
  14. */
  15. #include <linux/init.h>
  16. #include <linux/kobject.h>
  17. #include <linux/module.h>
  18. #include <linux/stat.h>
  19. #include <linux/string.h>
  20. #include <linux/sysfs.h>
  21. #include <uapi/linux/stat.h> /* S_IRUSR, S_IWUSR */
  22. enum { FOO_SIZE_MAX = 4 };
  23. static int foo_size;
  24. static char foo_tmp[FOO_SIZE_MAX];
  25. static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,
  26. char *buff)
  27. {
  28. strncpy(buff, foo_tmp, foo_size);
  29. return foo_size;
  30. }
  31. static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr,
  32. const char *buff, size_t count)
  33. {
  34. foo_size = min(count, (size_t)FOO_SIZE_MAX);
  35. strncpy(foo_tmp, buff, foo_size);
  36. return count;
  37. }
  38. static struct kobj_attribute foo_attribute =
  39. __ATTR(foo, S_IRUGO | S_IWUSR, foo_show, foo_store);
  40. static struct attribute *attrs[] = {
  41. &foo_attribute.attr,
  42. NULL,
  43. };
  44. static struct attribute_group attr_group = {
  45. .attrs = attrs,
  46. };
  47. static struct kobject *kobj;
  48. static int myinit(void)
  49. {
  50. int ret;
  51. kobj = kobject_create_and_add("lkmc_sysfs", kernel_kobj);
  52. if (!kobj)
  53. return -ENOMEM;
  54. ret = sysfs_create_group(kobj, &attr_group);
  55. if (ret)
  56. kobject_put(kobj);
  57. return ret;
  58. }
  59. static void myexit(void)
  60. {
  61. kobject_put(kobj);
  62. }
  63. module_init(myinit);
  64. module_exit(myexit);
  65. MODULE_LICENSE("GPL");