博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用debugfs来调试内核
阅读量:4042 次
发布时间:2019-05-24

本文共 4203 字,大约阅读时间需要 14 分钟。

1.简介

debugfs,是一种用于内核调试的虚拟文件系统,内核开发者可以通过debugfs和用户空间交换数据。虚拟文件系统还有procfs和sysfs等,虚拟文件系统都并不实际存储在硬盘上,而建立在内存中。

我们最常用的内核调试手段是printk。但printk并不是所有情况都好用,比如打印的数据可能过多,我们真正关心的数据在大量的输出里不是那么一目了然;或者我们在调试时可能需要修改某些内核变量,这种情况下printk就无能为力,而如果为了修改某个值重新编译内核或者驱动又过于低效,此时就需要一个临时的文件系统可以把我们需要关心的数据映射到用户空间。

在过去,procfs可以实现这个目的,到了2.6时代,新引入的sysfs也同样可以实现,但不论是procfs或是sysfs,用它们来实现某些debug的需求,似乎偏离了它们创建的本意。比如procfs,其目的是反映进程的状态信息;而sysfs主要用于Linux设备模型。不论是procfs或是sysfs的接口应该保持相对稳定,因为用户态程序很可能会依赖它们。当然,如果我们只是临时借用procfs或者sysfs来作debug之用,在代码发布之前将相关调试代码删除也无不可。但如果相关的调试借口要在相当长的一段时间内存在于内核之中,就不太适合放在procfs和sysfs里了。故此,debugfs应运而生。

2.配置内核

配置CONFIG_DEBUG_FS=y让内核支持debugfs,也可以在menuconfig中指定:

             Kernel hacking  --->
                   [*] Debug Filesystem
             内核默认会将debugfs挂载在/sys/kernel/debug目录下,也可以指定挂载目录:mount -t debugfs none /mnt

3.创建debugfs

1. 创建根目录

/* 第一个参数是目录的名称, * 第二个参数用来指定这个目录的上级目录,如果是NULL,则表示是放在debugfs的根目录里。 */my_debugfs_root = debugfs_create_dir("test_debug", NULL);  

2.创建调试文件

static int test_open(structinode *inode, structfile *filp)  {      filp->private_data = inode->i_private;      return0;   }       static ssize_t test_read(structfile *filp, char__user *buffer,                            size_tcount, loff_t *ppos)   {       if(*ppos >= 32)           return0;       if(*ppos + count > 32)           count = 32 - *ppos;          if(copy_to_user(buffer, hello + *ppos, count))           return-EFAULT;           *ppos += count;          return count;   }       static ssize_t test_write(structfile *filp, constchar __user *buffer,                         size_tcount, loff_t *ppos)   {       if(*ppos >= 32)           return0;       if(*ppos + count > 32)           count = 32 - *ppos;          if(copy_from_user(hello + *ppos, buffer, count))           return-EFAULT;           *ppos += count;          returncount;   }       structfile_operations teat_fops = {       .owner = THIS_MODULE,      .open  = test_open,      .read  = test_read,      .write = test_write,  };         /* 第一个参数为文件名,第二个参数为文件权限属性,第三个文件参数为父目录 * 第四个参数指向驱动程序分配的数据,第五个参数指向驱动分配的file_operations结构体 */debugfs_create_file("test", 0644, test_debug, NULL, &test_fops);   

4.移除调试文件

驱动退出时,我们要记得在module_exit中释放创建的数据,有两种方法可以移除创建的dentry:

1. debugfs_remove_recursive(test_debug);   //debugfs_remove_recursive可以递归地移除每个分配的dentry

2. 如果您想一个一个手动的移除,也可以直接调用debugfs_remove。

5.常用函数

1.创建和移除目录和文件

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);void debugfs_remove(struct dentry *dentry);void debugfs_remove_recursive(struct dentry *dentry);

2.创建单值文件

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_u64(const char *name, mode_t mode,                                   struct dentry *parent, u64 *value); /* x8、x16、x32三个函数是指debugfs中的数据用十六进制表示 */struct dentry *debugfs_create_x8(const char *name, mode_t mode,                                  struct dentry *parent, u8 *value);struct dentry *debugfs_create_x16(const char *name, mode_t mode,                                   struct dentry *parent, u16 *value);struct dentry *debugfs_create_x32(const char *name, mode_t mode,                                   struct dentry *parent, u32 *value); struct dentry *debugfs_create_size_t(const char *name, mode_t mode,                                      struct dentry *parent, size_t *value);struct dentry *debugfs_create_bool(const char *name, mode_t mode,                                    struct dentry *parent, u32 *value);

3.创建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);

 

转载地址:http://ykadi.baihongyu.com/

你可能感兴趣的文章
Oracle 删除表后多出了类似BIN$bdqTEdDrT7iRIC2+iRTfXQ==$0的表
查看>>
Oracle 18c创建PDB的几种方式
查看>>
ORA-65016: FILE_NAME_CONVERT must be specified
查看>>
oralce 18c 创建PDB方式——利用seed(种子)模板来创建
查看>>
RAC, Data Gurad, Stream 讲解
查看>>
Oracle 18c CON_GUID_TO_ID
查看>>
Oracle 18c 创建PDB可使用的参数说明
查看>>
ORA-39071: Value for EXCLUDE is badly formed.
查看>>
ORA-65359: unable to create pluggable database with no data
查看>>
ORA-12754: Feature PDB SNAPSHOT CAROUSEL is disabled due to missing capability
查看>>
Oracle数据库——Scheduler Job
查看>>
Oracle执行语句跟踪(1)——使用sql trace实现语句追踪
查看>>
oralce 18c 创建PDB几种方式
查看>>
oracle exp 导出表时会发现少表,空表导不出解决方案
查看>>
ORA-14450:试图访问已经在使用的事务处理临时表
查看>>
ORACLE RMAN 各种场景恢复
查看>>
oracle 自动导出package/package body/procedure 等为sql文件并且自动上传到ftp服务器上
查看>>
linux 下 su - oracle 切换不了
查看>>
初学MonggoDb—Linux平台安装MongoDB
查看>>
使用“rz -be”命令上传文件至服务器;使用“sz 文件名”从服务器下载文件到本地
查看>>