From 75afeba635bfe22a678a2312398ba0dfc5febec8 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Thu, 27 Jul 2017 15:10:00 +0100 Subject: [PATCH] sysfs --- kernel_module/README.md | 1 + kernel_module/sysfs.c | 84 +++++++++++++++++++++++++++++++++++++++++ rootfs_overlay/sysfs.sh | 11 ++++++ 3 files changed, 96 insertions(+) create mode 100644 kernel_module/sysfs.c create mode 100755 rootfs_overlay/sysfs.sh diff --git a/kernel_module/README.md b/kernel_module/README.md index a2f9964..892ea3e 100644 --- a/kernel_module/README.md +++ b/kernel_module/README.md @@ -10,6 +10,7 @@ 1. Pseudo filesystems 1. [debugfs](debugfs.c) 1. [procfs](procfs.c) + 1. [sysfs](sysfs.c) 1. [fops](fops.c) 1. [ioctl](ioctl.c) 1. [poll](poll.c) diff --git a/kernel_module/sysfs.c b/kernel_module/sysfs.c new file mode 100644 index 0000000..79bd56e --- /dev/null +++ b/kernel_module/sysfs.c @@ -0,0 +1,84 @@ +/* +Adapted from: https://github.com/t3rm1n4l/kern-dev-tutorial/blob/1f036ef40fc4378f5c8d2842e55bcea7c6f8894a/05-sysfs/sysfs.c + +Vs procfs: + +- https://unix.stackexchange.com/questions/4884/what-is-the-difference-between-procfs-and-sysfs +- https://stackoverflow.com/questions/37237835/how-to-attach-file-operations-to-sysfs-attribute-in-platform-driver + +This example shows how sysfs is more restricted, as it does not take a file_operations. + +So you basically can only do open, close, read, write, and lseek on sysfs files. + +It is kind of similar to a seq_file file_operations, except that write is also implemented. + +TODO: what are those kobject structs? Make a more complex example that shows what they can do. + +- https://www.kernel.org/doc/Documentation/kobject.txt +- https://www.quora.com/What-are-kernel-objects-Kobj +- http://www.makelinux.net/ldd3/chp-14-sect-1 +- https://www.win.tue.nl/~aeb/linux/lk/lk-13.html +*/ + +#include +#include +#include +#include +#include +#include +#include /* S_IRUSR, S_IWUSR */ + +enum { FOO_SIZE_MAX = 4 }; +static int foo_size; +static char foo_tmp[FOO_SIZE_MAX]; + +static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buff) +{ + strncpy(buff, foo_tmp, foo_size); + return foo_size; +} + +static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buff, size_t count) +{ + foo_size = min(count, (size_t)FOO_SIZE_MAX); + strncpy(foo_tmp, buff, foo_size); + return count; +} + +static struct kobj_attribute foo_attribute = + __ATTR(foo, S_IRUGO | S_IWUSR, foo_show, foo_store); + +static struct attribute *attrs[] = { + &foo_attribute.attr, + NULL, +}; + +static struct attribute_group attr_group = { + .attrs = attrs, +}; + +static struct kobject *kobj; + +static int myinit(void) +{ + int ret; + + kobj = kobject_create_and_add("lkmc_sysfs", kernel_kobj); + if (!kobj) + return -ENOMEM; + ret = sysfs_create_group(kobj, &attr_group); + if (ret) + kobject_put(kobj); + return ret; +} + +static void myexit(void) +{ + kobject_put(kobj); +} + +module_init(myinit); +module_exit(myexit); +MODULE_LICENSE("GPL"); diff --git a/rootfs_overlay/sysfs.sh b/rootfs_overlay/sysfs.sh new file mode 100755 index 0000000..73a1d63 --- /dev/null +++ b/rootfs_overlay/sysfs.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -x +insmod /sysfs.ko +cd /sys/kernel/lkmc_sysfs +printf 12345 >foo +cat foo +# => 1234 +dd if=foo bs=1 count=2 skip=1 status=none +# => 23 +rmmod sysfs