// SPDX-License-Identifier: GPL-2.0 #include #include #include #include /* Global variable for sysfs folder hello */ static struct kobject *dummy_kobj; /** * @brief Read callback for hello/dummy */ static ssize_t dummy_show(struct kobject *kobj, struct kobj_attribute *attr, char *buffer) { return sprintf(buffer, "You have read from /sys/kernel/%s%s\n", kobj->name, attr->attr.name); } /** * @brief Read callback for hello/dummy */ static ssize_t dummy_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buffer, size_t count) { pr_notice("sysfs_test - You wrote '%s' to /sys/kernel/%s%s\n", buffer, kobj->name, attr->attr.name); return count; } static struct kobj_attribute dummy_attr = __ATTR(dummy , 0660, dummy_show, dummy_store); /** * @brief This function is called when the module is loaded into the kernel */ static int __init my_init(void) { pr_notice("sysfs_test - Creating /sys/kernel/hello/dummy\n"); dummy_kobj = kobject_create_and_add("hello", kernel_kobj); if(!dummy_kobj) { pr_err("sysfs_test - Error creating /sys/kernel/hello\n"); return -ENOMEM; } /* Create the sysfs file dummy */ if(sysfs_create_file(dummy_kobj, &dummy_attr.attr)) { pr_err("sysfs_test - Error creating /sys/kernel/hello/dummy\n"); kobject_put(dummy_kobj); return -ENOMEM; } return 0; } /** * @brief This function is called when the module is removed from the kernel */ static void __exit my_exit(void) { pr_info("sysfs_test - Deleting /sys/kernel/hello/dummy\n"); sysfs_remove_file(dummy_kobj, &dummy_attr.attr); kobject_put(dummy_kobj); } module_init(my_init); module_exit(my_exit); /* Meta Information */ MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("David D'Ulisse"); MODULE_DESCRIPTION("A Hello, World! Test Module");