Adding procfs and sysfs interface in your lkml
[Warning: This post is a backup recovery from my previous Wordpress blog. All content was automatically converted accessing a MySQL database using a Python script (details). Mostly are in Portuguese but if you are interest I can translate to English. If you found any problem dont’t hesitate to contact me in comments.]
Hi. This post will show how to add two important things about device model in your linux kernel module (lkml). Sysfs is the user-space manifestation of the kernel's structured device model. It's similar to procfs in that both are in-memory filesystem containing information about kernel data structures. Basically:
- procfs is a generic window into kernel internals
- sysfs is specific to device model
Information such as process descriptors and sysctls parameters belong to procfs and not sysfs. Note that:Sysfs is not a replacement for procfs.
Lets create two useless (in a practical way) that presents the “idea” behind these constructions.
1. Procfs
The snippet below creates a /proc/coding allowing read or write some content.
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> /* for proc_dir_entry and create_proc_entry */ #include <linux/proc_fs.h> /* For sprintf and snprintf */ #include <linux/string.h> /* For copy_from_user */ #include <linux/uaccess.h> static char internal_buffer[256]; int buf_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len; len = snprintf(buf, count, "%s", internal_buffer); return len; } static int buf_write(struct file *file, const char *buf, unsigned long count, void *data) { if(count > 255) /* to avoid overflowwwwwwwwww */ count = 255; /* Copies data from user space to kernel space */ copy_from_user(internal_buf, buf, count); /* inserting NULL to end the string */ internal_buf[count] = '\0'; return count; } int __init proc_init(void) { /* Simple */ struct proc_dir_entry *de = create_proc_entry("coding", 0667, 0); /* Set pointers to our functions */ de->read_proc = buf_read; /* reading */ de->write_proc = buf_write; /* writing */ /* We initialize our internal_buffer with some text. */ sprintf(internal_buffer, "www.coding.com.br"); return 0 ; } void __exit proc_cleanup(void) { /* We delete our entry */ remove_proc_entry("coding", NULL); } module_init(proc_init); module_exit(proc_cleanup); MODULE_LICENSE("GPL");
2. Sysfs
This example only creates a /sys/class/<module-name> directorywith nothing inside. This may not be clear now but remember when I show - in the next posts - some practical use with device node (/dev).
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> /* for sysfs class creation */ #include <linux/platform_device.h> static struct class *sysfs_class; int __init sysfs_init(void) { sysfs_class = class_create(THIS_MODULE, "sysfs" ); return 0 ; } void __exit sysfs_cleanup(void) { /* We delete our entry */ class_destroy(sysfs_class); } module_init(sysfs_init); module_exit(sysfs_cleanup); MODULE_LICENSE("GPL");