When you are setting-up a new kernel module you often need to change some values or get some outputs. It is where Debugsys_fs is the most useful (exchanging message from user space to kernel space).
During my work I had to make a kernel module speaking with user space and scheduler (CFS). Today I will speak about Debugsys_fs and how I used it for my purpose. Be careful to check if your kernel was compiled with correct option for debugfs (see your .config file).
Debugfs is simple to use (like most linux stuff), you need to include some headers to handle the debugfs :
#include <linux/debugfs.h> the main header for debugfs use
#include <linux/seq_file.h> a useful header to read/write to debugfs
also you may need things like :
#include <linux/kernel.h>
#include <linux/module.h>
If you are making a kernel module (my case) and maybe a lot more if needed.
Debugfs API gives two main functions :
debugfs_create_dir(
const
char
*name,
struct
dentry *parent)
and debugfs_create_file(
const
char
*name, mode_t mode,
struct
dentry *parent,
void
*data,
struct
file_operations *fops)
you can also use things like : debugfs_create_u8(
const
char
*name, mode_t mode,
struct
dentry *parent, u8 *value) if you only need to pass a u8 value to your kernel module.
example code for creating the debugfs :
static struct dentry *debug_dir; //declare debugfs directory
static int modulek_init_debugfs(void) { debug_dir = debugfs_create_dir("my_debug", NULL); debugfs_create_file("file_control", 0444, debug_dir, NULL, &my_debug_file_control_fops); debugfs_create_file("file_usage", 0666, debug_dir, NULL, &my_debug_file_usage_fops); debugfs_create_file("file_fail", 0644, debug_dir, NULL, &my_debug_file_fail_fops); debugfs_create_file("file_sched", 0444, debug_dir, NULL, &my_debug_file_sched_fops); return 0; }
It will create a my_debug directory in /sys/kernel/debug/ with 4 files in this folder.
The last advice is about cleaning-up things, you need to clean debugs when no-more needed.
debugfs_remove(struct dentry *dentry)
Or in my case :
debugfs_remove_recursive(my_debug) //erase all debugfs in your debug_directory
Some functions must be declared to set up operations on files
//struct of debugfs file sched static const struct file_operations my_debug_file_sched_fops = { .open = my_debug_sched_open, .write = my_debug_sched_write, .read = seq_read, .llseek = seq_lseek, .release = single_release, };
You can set functions like « my_debug_sched_open » to use your own implementation.
At the end you need to initiate all of this, for this purpose add to your »
int init_module( void ) » :
modulek_init_debugfs();
and don’t forget to callback in the »
void cleanup_module( void ) » to your cleanup of debugfs :
debugfs_remove_recursive(my_debug);