###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);