Debugfs详解

Debugfs是一种简单的文件系统,内核开发者可以方便的通过debugfs将信息从kernel space传给user space。

特点:

  • debugfs不像/proc仅用于传递进程信息,也不像sysfs每个文件只能有一个值,debugfs的使用更加自由。
  • debugfs一般挂载在/sys/kernel/debug, 指令:
mount -t debugfs none /sys/kernel/debug
  • debugfs的根目录(即上述目录)默认只能被root用户访问,可以通过“uid”, “gid” 以及“mode”等mount选项来修改访问权限。

 

debugfs的使用:

使用debugfs需要包含头文件<linux/debugfs.h>

常用函数:

  • Create at least one directory to hold a set of debugfs files

在parent目录下创建新的目录,如果parent为NULL,则会创建在debugfs根目录下。返回的dentry pointer在后续创建文件以及clean up的时候会用到。

错误返回值:ERR_PTR(-ERROR)表示出错了,如果返回ERR_PTR(-ENODEV) ,则表示kernel不支持debugfs功能。

struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);

 

  • Create a file within a debugfs directory:
struct dentry *debugfs_create_file(const char *name, umode_t mode,
                                   struct dentry *parent, void *data,
                                   const struct file_operations *fops);

mode表示文件的访问权限, 使用的值可以参考:https://www.gnu.org/software/libc/manual/html_node/Permission-Bits.html

fops表示系列文件操作,需要至少实现read() or write(),返回ERR_PTR(-ERROR) on error, or ERR_PTR(-ENODEV) if debugfs support is missing.

  • Remove all files and directories created when unload the module
void debugfs_remove_recursive(struct dentry *dentry);

The entire hierarchy below the directory will be removed.

 

Other related functions can refer to this page:

https://docs.kernel.org/filesystems/debugfs.html

 

Example:

写一个简单的利用了debugfs的kernel module:

复制代码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/debugfs.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("simple debugfs experiment");

char data[PAGE_SIZE];
int data_len = 0;

static struct dentry *debugfs_dir;
static struct dentry *debugfs_file;

static ssize_t file_read(struct file *, char *, size_t, loff_t *);
static ssize_t file_write(struct file *, const char *, size_t, loff_t *);

const struct file_operations data_file_fops = {
    .owner = THIS_MODULE,
    .write = file_write,
    .read = file_read,
};

static int __init debugfs_init(void)
{
    debugfs_dir = debugfs_create_dir("test_dir", NULL);
    if (!debugfs_dir)
        return -ENOENT;
    
    debugfs_file=debugfs_create_file("test_file", S_IRUSR, debugfs_dir, NULL, &data_file_fops);
    if (!debugfs_file)
        goto exit;
    
    return 0;

exit:

    debugfs_remove_recursive(debugfs_dir);
    return -ENOENT;

}

static void __exit debugfs_exit(void)
{
    debugfs_remove_recursive(debugfs_dir);
}

static ssize_t file_read(struct file *f, char *buffer, size_t len, loff_t *offset)
{
    // Copy data from the buffer to user space
    return simple_read_from_buffer(buffer, len, offset, data, data_len);
}

static ssize_t file_write(struct file *f, const char *buffer, size_t len, loff_t *offset)
{
    ssize_t ret;
    // Copy data from user space to the buffer 
    ret = simple_write_to_buffer(data, PAGE_SIZE, offset, buffer, len);
    if (ret < 0)
        return ret;
    
    data_len = ret;
    return len;
}

module_init(debugfs_init);
module_exit(debugfs_exit);
复制代码

 

Makefile:

需要机器上有当前kernel的source code

obj-m += simple_debugfs.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

 

测试:

复制代码
# make

# insmod simple_debugfs.ko

# ll /sys/kernel/debug/test_dir/test_file

# echo "simple_data" > /sys/kernel/debug/test_dir/test_file

#cat /sys/kernel/debug/test_dir/test_file
simple_data

#rmmod simple_debugfs

#ll /sys/kernel/debug/test_dir/test_file
ls: cannot access '/sys/kernel/debug/test_dir': No such file or directory
复制代码

 

Reference:

https://docs.kernel.org/filesystems/debugfs.html

https://janczer.github.io/create-simple-debugfs-object/

 

posted @   风一样的liz  阅读(4391)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
点击右上角即可分享
微信分享提示