为自己的module添加debugfs

来源:互联网 发布:数据侠客行txt下载 编辑:程序博客网 时间:2024/06/06 00:23
debugfs on /sys/kernel/debug type debugfs (rw,relatime)

首先定义一个dentry
static struct dentry *aat2870->dentry_root;
第二步:调用debugfs_create_dir 来创建文件夹,debugfs_create_dir的第一个参数表示文件夹的名字,第二个是父文件夹的名字,一般为NULL。这样在mount的时候再执行父文件夹的名字
char ixgbe_driver_name[] = "ixgbe";

    aat2870->dentry_root = debugfs_create_dir("aat2870", NULL);
    if (!aat2870->dentry_root) {
        dev_warn(aat2870->dev,
             "Failed to create debugfs root directory\n");
        return;
    }
第三步,在文件夹下面建立文件,已经针对这个文件read/write的函数
    aat2870->dentry_reg = debugfs_create_file("regs", 0644,
                          aat2870->dentry_root,
                          aat2870, &aat2870_reg_fops);
    if (!aat2870->dentry_reg)
        dev_warn(aat2870->dev,
             "Failed to create debugfs register file\n");
针对这个regs文件的read/write的函数
static const struct file_operations aat2870_reg_fops = {
    .open = simple_open,
    .read = aat2870_reg_read_file,
    .write = aat2870_reg_write_file,
};
可以看到open一般都是指定成simple_open。

static ssize_t aat2870_reg_read_file(struct file *file, char __user *user_buf,
                     size_t count, loff_t *ppos)
{
    struct aat2870_data *aat2870 = file->private_data;
    char *buf;
    ssize_t ret;

    buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
    if (!buf)
        return -ENOMEM;

    ret = aat2870_dump_reg(aat2870, buf);
    if (ret >= 0)
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);

    kfree(buf);

    return ret;
}
而read 函数主要call simple_read_from_buffer 将数据从kernel space copy到user space
ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos,
                const void *from, size_t available)
{
    loff_t pos = *ppos;
    size_t ret;
    if (pos < 0)
        return -EINVAL;
    if (pos >= available || !count)
        return 0;
    if (count > available - pos)
        count = available - pos;
    ret = copy_to_user(to, from + pos, count);
    if (ret == count)
        return -EFAULT;
    count -= ret;
    *ppos = pos + count;
    return count;
}


static ssize_t aat2870_reg_write_file(struct file *file,
                      const char __user *user_buf, size_t count,
                      loff_t *ppos)
{

    len = simple_write_to_buffer(ixgbe_dbg_netdev_ops_buf,
                     sizeof(ixgbe_dbg_netdev_ops_buf)-1,
                     ppos,
                     buffer,
                     count);
    if (len < 0)
        return len;

    ixgbe_dbg_netdev_ops_buf[len] = '\0';
    return count;
}
而write函数主要call simple_write_to_buffer 将数据从kernel space写到user space
ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
        const void __user *from, size_t count)
{
    loff_t pos = *ppos;
    size_t res;
    if (pos < 0)
        return -EINVAL;
    if (pos >= available || !count)
        return 0;
    if (count > available - pos)
        count = available - pos;
    res = copy_from_user(to + pos, from, count);
    if (res == count)
        return -EFAULT;
    count -= res;
    *ppos = pos + count;
    return count;
}

在kernel起来后就可以通过mount -t debugfs nodev /sys/kernel/debug 来将debugfs mount上,然后就可以在/sys/kernel/debug/xxx 下看到自己添加的entry

0 0