###1. debugfs
“/proc” 和 “/sys” 文件系统都可以通过文件来导出内核信息, 内核模块也可以通过在其中添加文件来导出调试信息, 但是, procfs的是反映进程的状态信息,而sysfs主要用于Linux设备模型, 使用它们来实现debug偏离了它们的本意, 为此, linux中添加了debugfs
###2. enable debugfs
让内核支持DEBUGFS,使能宏CONFIG_DEBUG_FS,在内核配置中选中,一般是在Kernel hacking中
Kernel Hacking --->
[] Debug Filesystem
debugfs 挂载在 “/sys/kernel/debug” 目录下, 如果没有挂载, 可以使用如下命令来挂载或者添加到 fstab 中来自动挂载
mount -t debugfs none /sys/kernel/debug
###3. debugfs API
要使用debugfs提供的api必须包含头文件 “<linux/debugfs.h>”
debugfs 提供如下的API
/* 在 debugfs 中建立一个目录, 如果parent为NULL, 则在debugfs的根目录即 /sys/kernel/debug 中建立目录 */
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
/* 删除debugfs 中的目录 */
void debugfs_remove_recursive(struct dentry *dentry);
/* 在 debugfs 中建立文件, 还需要实现文件的操作方法 */
struct dentry *debugfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
/* 删除 debugfs 中的文件 */
void debugfs_remove(struct dentry *dentry);
有时候, 仅仅只想通过debugfs中的文件导出一个数字, 还需要自己实现文件的读写方法就太麻烦了, 针对这种情况, debugfs 提供了如下的API
/* 在debugfs中创建一个文件,绑定到一个u8 变量上 */
struct dentry *debugfs_create_u8(const char *name, umode_t mode,
struct dentry *parent, u8 *value);
/* 在debugfs中创建一个文件,绑定到一个u16 变量上 */
struct dentry *debugfs_create_u16(const char *name, umode_t mode,
struct dentry *parent, u16 *value);
/* 在debugfs中创建一个文件,绑定到一个u32 变量上 */
struct dentry *debugfs_create_u32(const char *name, umode_t mode,
struct dentry *parent, u32 *value);
/* 在debugfs中创建一个文件,绑定到一个u64 变量上 */
struct dentry *debugfs_create_u64(const char *name, umode_t mode,
struct dentry *parent, u64 *value);
以上的4个api均支持读写操作(只要配置为可读写的话), 并且使用10进制来显示数字, 如果希望使用16进制的话, 可以使用如下版本的API
struct dentry *debugfs_create_x8(const char *name, umode_t mode,
struct dentry *parent, u8 *value);
struct dentry *debugfs_create_x16(const char *name, umode_t mode,
struct dentry *parent, u16 *value);
struct dentry *debugfs_create_x32(const char *name, umode_t mode,
struct dentry *parent, u32 *value);
struct dentry *debugfs_create_x64(const char *name, umode_t mode,
struct dentry *parent, u64 *value);
可以在debugfs中创建文件, 绑定一个 size_t 类型的变量
struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
struct dentry *parent, size_t *value);
可以在debugfs中创建文件, 绑定一个 u32 类型的变量, 做为布尔值来处理, 读取是返回 “Y” 或者 “N”, 可以写入 y/Y/n/N/1/0, 其它值被忽略
struct dentry *debugfs_create_bool(const char *name, umode_t mode,
struct dentry *parent, u32 *value);
可以在debugfs中创建文件(注意这一文件是只读的), 绑定一块二进制数据
struct debugfs_blob_wrapper {
void *data;
unsigned long size;
};
struct dentry *debugfs_create_blob(const char *name, umode_t mode,
struct dentry *parent,
struct debugfs_blob_wrapper *blob);
可以在debugfs中创建文件, 绑定到一堆寄存器集合上
struct debugfs_reg32 {
char *name;
unsigned long offset;
};
struct debugfs_regset32 {
struct debugfs_reg32 *regs;
int nregs;
void __iomem *base;
};
struct dentry *debugfs_create_regset32(const char *name, umode_t mode,
struct dentry *parent,
struct debugfs_regset32 *regset);
int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs,
int nregs, void __iomem *base, char *prefix);
还有2个API用于修改 debugfs 文件的名称, 或者建立符号链接
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);