debugfs 使用指南

debugfs 使用指南debugfs 使用指南 debugfs

大家好,欢迎来到IT知识分享网。

debugfs 使用指南  https://zhuanlan.zhihu.com/p/

Linux驱动调试中的Debugfs的使用简介 CONFIG_DEBUG_FS 的功能与配置  debugfs 使用指南

linux DebugFS介绍  https://zhuanlan.zhihu.com/p/

https://www.cnblogs.com/dennis-wong/p/16391598.html

ebugfs#

概述#

类似sysfs、procfs,debugfs 也是一种内存文件系统。不过不同于sysfs一个kobject对应一个文件,procfs和进程相关的特性,

debugfs的灵活度很大,可以根据需求对指定的变量进行导出并提供读写接口。

debugfs又是一个Linux中 everything is a file 哲学的体现,通过VFS实现了对驱动的控制。可以通过以下命令,来挂载debugfs到指定目录。

mount -t debugfs none /sys/kernel/debug 

支持的读写类型#

debugfs支持比较丰富的数据类型,如下所示。

使用方式#

  1. 创建目录和文件
    使用 debugfs_create_dir 创建一个目录,如果parent为NULL,则默认其父目录为debugfs的根目录。函数的返回值为NULL表示目录创建成功。
    debugfs_create_file和debugfs_create_file_size都用来创建文件,不同的是debugfs_create_file_size可以通过file_size字段指定一个初始的大小。

struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); struct dentry *debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); void debugfs_create_file_size(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops, loff_t file_size); 
  1. 创建无符号整型文件
//创建十进制的无符号文件 void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value); void debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value); void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, u64 *value); //创建十六进制的无符号文件 void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value); //创建一个size_t类型的文件 void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value); //创建一个unsigned long类型的文件 struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); //创建一个十六进制的unsigned long类型的文件 void debugfs_create_xul(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); 
  1. 布尔类型文件
void debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, bool *value); 

读布尔文件会显示Y或者N,写该文件时,只接受(Y, N, y, n, 0, 1)等值,其他值都只会被简单的忽略。

  1. 原子类型
void debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value) 
  1. blob类型

使用debugfs_create_blob创建一个blob类型的文件,调用该函数前,我们需要在debugfs_blob_wrapper的data字段指定要展示的内容,size表示data长度。

需要注意的是blob类型的文件是只读的

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); 
  1. 寄存器类型

使用 debugfs_reg32 表示一个寄存器内容,name表示文件名,offset表示相对于基地址的偏移。debugfs_regset32 表示一组寄存器文件,nregs:寄存器文件个数 base:io基地址

struct debugfs_reg32 { char *name; unsigned long offset; }; struct debugfs_regset32 { const struct debugfs_reg32 *regs; int nregs; void __iomem *base; struct device *dev; /* Optional device for Runtime PM */ }; debugfs_create_regset32(const char *name, umode_t mode, struct dentry *parent, struct debugfs_regset32 *regset); void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix); 

踩坑#

  1. debugfs的API的都是GPL的,因此在自己的模块必须要指定协议为GPL
  2. 使用echo写文件的话,open函数是必须的。

代码实例#

#include <linux/debugfs.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/errno.h> #include <linux/dcache.h> #include <linux/types.h> static char zen_buf[512] = "hello\n"; static struct dentry *zen_dir; static int zen_open(struct inode *inode, struct file *filp) { printk("zen open\n"); filp->private_data = inode->i_private; return 0; } ssize_t zen_read(struct file *filp, char __user *buf, size_t count, loff_t *offp) { int retval = 0; if ((*offp + count) > 512) count = 512 - *offp; printk("read request: count:%u, offset:%u\n", count, *offp); if (copy_to_user(buf, zen_buf+*offp, count)) { printk("copy to user failed, count:%ld\n", count); retval = -EFAULT; goto out; } *offp += count; retval = count; out: return retval; } ssize_t zen_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp) { int retval; printk("write request: count:%u, offset:%u\n", count, *offp); if (*offp > 512) return 0; if (*offp + count > 512) count = 512 - *offp; if (copy_from_user(zen_buf+*offp, buff, count)) { printk("copy from user failed, count:%ld\n", count); retval = -EFAULT; goto out; } *offp += count; retval = count; out: return retval; } struct file_operations my_fops = { .owner = THIS_MODULE, .read = zen_read, .write = zen_write, .open = zen_open, }; static int __init debugfs_init(void) { printk("INIT MODULE\n"); zen_dir = debugfs_create_dir("zen_dir4", NULL); if (!zen_dir) { printk("zen_dir4 is null\n"); goto fail; } static struct dentry *sub_zen_dir; sub_zen_dir = debugfs_create_dir("sub_zen", zen_dir); if (!sub_zen_dir) { printk("sub zen dir is null\n"); goto fail; } struct dentry *filent = debugfs_create_file("zen", 0644, sub_zen_dir, NULL, &my_fops); if (!filent) { printk("zen file is null\n"); goto fail; } printk("INIT SUCCESS\n"); return 0; fail: //return -ENOENT; return -1; } static void __exit debugfs_exit(void) { printk("exit module\n"); debugfs_remove_recursive(zen_dir); printk("exit success\n"); } module_init(debugfs_init); module_exit(debugfs_exit); MODULE_LICENSE("GPL"); 

修订记录#

修改了文章格式

作者:dennis-wong

出处:https://www.cnblogs.com/dennis-wong/p/16391598.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/124427.html

(0)
上一篇 2025-10-07 17:45
下一篇 2025-10-07 18:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信