一、Debugfs介绍
? ?DebugFS,是一种用于内核调试的虚拟文件系统,内核通过debugfs和用户空间交换数据,类似procfs和sysfs等,这几种虚拟文件系统都并不是实际存储在硬盘上,而是Linux内核运行起来以后才建立的。通常情况下,最常用的内核调试手段是printk,但printk并不是所有情况都好用,比如打印的数据可能过多,我们真正关心的数据在大量的输出里不是那么一目了然;或者我们在调试时可能需要修改某些内核变量,这种情况下printk就无能为力,而如果为了修改某个值重新编译内核或者驱动又过于低效,此时就需要一个临时的文件系统可以把我们需要关心的数据映射到用户空间。在过去,procfs可以实现这个目的,到了2.6时代,新引入的sysfs也同样可以实现,但无论是procfs还是sysfs,用它们来实现某些debug的需求,似乎偏离了它们创建的本意。比如procfs,其目的是反映进程的状态信息;而sysfs主要用于Linux设备模型。不论是procfs或是sysfs的接口应该保持相对的稳定,因为用户态程序很可能会依赖它们,当然,如果我们只是临时借用procfs或者sysfs来做debug之用,在代码发布之前将相关调试代码删除也不无不可。但如果相关的调试接口要在相当长的一段时间内存在于内核中,就不太适合放在procfs或者sysfs里了,故此,debugfs应运而生。
二、API
//name是创建的文件或目录名字,mode是文件的权限,parent是父目录,data通常指向驱动程序分配的数据,fops指向驱动分配的file_operations结构体
//该结构体指定了应用程序读写时对调用的驱动程序函数
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
struct dentry *debugfs_create_file(const char *name, mode_t mode, struct dentry *parent, void *data, const struct file_operations *fops);
//debugfs除了实现这个文件对函数的功能,还提供了一些API用来针对变量的操作,这样就可以在用户态去调试内核变量value了:
//使用以下API,需要我们清楚文件保存内容的大小和类型,否则不要轻易使用下面几个带类型的API
struct dentry *debugfs_create_u8(const char *name, mode_t mode, struct dentry *parent, u8 *value);
struct dentry *debugfs_create_u16(const char *name, mode_t mode, struct dentry *parent, u16?*value);
struct dentry *debugfs_create_u32(const char *name, mode_t mode, struct dentry *parent, u32?*value);
struct dentry *debugfs_create_bool(const char *name, mode_t mode, struct dentry *parent, bool?*value);
struct dentry *debugfs_create_size_t(const char *name, mode_t mode, struct dentry *parent, size_t?*value);
//当内核卸载时,debugfs并不会自动的去清楚我们创建的这些文件,对于创建的每一个文件我们都需要调用如下函数接口去清除:
void debugfs_remove_recursive(struct dentry *dentry);
//可以帮我们逐步移除每个分配的dentry,如果你想一个一个手动移除,也可以直接调用debugfs_remove
struct dentry *debugfs_remove(struct dentry *dentry);
//创建BLOB文件
struct debugfs_blob_wrapper{
void *data;
unsigned long size;
};
struct dentry *debugfs_create_blob(const char *name, mode_t mode, struct dentry *parent, struct debugfs_blob_wrapper *blob);
//其他
struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, struct dentry new_dir, const char *new_name);
struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, const char *target);
三、使用
1.要使用debugfs,首先我们要配置一下选项CONFIG_DEBUG_FS,可以在config文件中设置CONFIG_DEBUG_FS=y,也可以通过menuconfig来设置:
Kernelhacking--->[*]Debug Filesystem
2.驱动中使用debugfs需要包含头文件<linux/debugfs.h>,为了在用户态下使用debugfs,必须把它mount到一个目录下,默认情况下,debugfs会被挂载在目录/sys/kernel/debug之下,如果您的发行版里没有自动挂载,可以用如下命令手动完成:
//包含头文件
#include <linux/debugfs.h>
//为了在用户态下使用debugfs,必须把它mount到一个目录下:
mount -t debugfs none /sys/kernel/debug
|