c - 从 create_proc_read_entry 迁移到 proc_create 并使用 seq_files

标签 c linux-kernel

我正在尝试从已弃用的函数 create_proc_read_entry 迁移到使用 proc_create。我一直在研究使用 seq_files 的新实现。以前,我使用 /proc 文件系统将指针传递给我 copy_from_user 到内核空间的结构。该结构包含我用来确定接下来调用哪个函数的信息(以及其他数据)。我正在为新的实现而苦苦挣扎。具体来说,我如何获取指向从用户空间传递的结构的指针。根据我的研究, seq_files 实现使用 seq 文件方便地迭代结构,而无需处理指针内容。

struct sCmd_t {
    u32 length;
    u8 type;
    int number;
    u16 command;
    u8 version;
} sCmd_t

ctrl_file = create_proc_read_entry("ctrl",
                                   0666,
                                   PROC_FILE,
                                   read_proc_ctrl,
                                   NULL);

ctrl_file->write_proc = write_proc_ctrl;

static int write_proc_ctrl( struct file *filp, const char __user *buff, unsigned long len, void *data){

    sCmd_t *sCmd = NULL;
    const unsigned char *curbuf = NULL;

    sCmd = (sCmd_t *) kmalloc(sizeof(sCmd_t), GFP_KERNEL);

    if (sCmd == NULL)
          return ERROR;

    memset(cmd, 0, sizeof(sCmd));

    curbuf = buff;

    if (copy_from_user( cmd, curbuf, sizeof(sCmd_t)))
            return -EFAULT;

    switch (sCmd->command){
     //based on the command the appropriate
    }

所以我想做的是从 seq_show 函数获取指向我的结构的指针,但它不起作用。

static int seq_show(struct seq_file *seqfile, void *v)
{
    //in here I'm trying to grab a pointer to the struct here
    sCmd_t *sCmd = NULL;
    const unsigned char *curbuf = NULL;

    sCmd = (sCmd_t *) kmalloc(sizeof(sCmd_t), GFP_KERNEL);

    if (sCmd == NULL)
          return ERROR;

    memset(cmd, 0, sizeof(sCmd));

    curbuf = v;

    if (copy_from_user( cmd, curbuf, sizeof(sCmd_t)))
//blah blah blah.....

    return 0;
}

static void *seq_start(struct seq_file *seqfile, loff_t *pos)
{
    return pos;
 }

static void *seq_next(struct seq_file *seqfile, void *v, loff_t *pos)
{
    return pos;
}

static void seq_stop(struct seq_file *seqfile, void *v)
{
   return;
}

static struct seq_operations seq_ops = {
    .start  = seq_start,
    .next   = seq_next,
    .stop   = seq_stop,
    .show   = seq_show
};

static int proc_open(struct inode *inode, struct file *file)
{
    return seq_open(file, &seq_ops);
}

static const struct file_operations fops = {
 .owner     = THIS_MODULE,
 .open      = proc_open,
 .read      = seq_read,
 .llseek    = seq_lseek,
 .release   = single_release,
 };

ctrl_file = proc_create("ctrl", 0644, proc_dir, &fops);

这只是第一次尝试。当我尝试这段代码时,当我取消引用结构的命令成员时,它会呕吐。正如您所看到的,我的结构非常小,因此该实现不必使用 seq 文件来检查它是否正在另一个页面上运行。这就是为什么我试图捕获 show 函数中的指针,因为我想象它必须迭代或“下一个”到结构或页面。根据我的阅读,seq_file 迭代将使遍历结构变得容易,但我首先需要了解如何获取指向我从用户空间写入 /proc 文件系统的内容的指针。

最佳答案

seq_file 是实现只读文件的助手。 show 回调的缓冲区是一个内核缓冲区,您应该在其中写入要返回到用户空间的数据。

您可以选择使用或不使用seq_file;但在这里没有意义。

但无论如何,procfs 操作都是用 struct file_operations 定义的; 要实现写入回调,只需在 fops 中实现 write 即可。

关于c - 从 create_proc_read_entry 迁移到 proc_create 并使用 seq_files,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24946863/

相关文章:

c - 如何使用 Clang 的 AST?

C: 在特定内存位置访问 'char'?

linux-kernel - skb_reserve 注释说明

通过引用调用与通过复制恢复调用

c - #ifdef SIOCSHWTSTAMP 未找到

c - fopen() 中 r+ 和 w+ 的区别

linux-kernel - 前缀 printk/pr_* 调用

linux - `make install` 之后出现内核编译和缺少模块错误

linux - 从 Yocto build 手动构建内核源代码

assembly - x86 中的 IN 和 OUT 指令有何用途?