Linux内核代码中create_proc_entry()和read_proc的替代方法

时间:2018-06-15 02:01:56

标签: c linux-kernel procfs

几年前,Linux 3.8被移植到TI-nSpire图形计算器(https://github.com/tangrs/linux)。虽然一些变化被上调了,但其中大多数都没有。我一直在重写最新内核源代码的补丁,但我仍然坚持使用弃用的功能:
create_proc_entry()

我收到两条与此相关的GCC错误消息。我通过将create_proc_entry(BOOT1_PROCFS_NAME, 0644, NULL);更改为proc_create_data(BOOT1_PROCFS_NAME, 0644, NULL, NULL, NULL);来解决的第一个问题  (如果有更好的东西,请告诉我。)

第二个错误,

arch/arm/mach-nspire/boot1.c:37:18: error: dereferencing pointer to incomplete type ‘struct proc_dir_entry’
boot1_proc_entry->read_proc = boot1_read;

我一直无法修复。我查看了git历史记录,其中read_proc_t *read_proc;struct proc_dir_entry的一部分;然后位于include/linux/proc_fs.h中,位于fs/proc/internal.h中)已被删除(https://github.com/torvalds/linux/commit/3cb5bf1bf947d325fcf6e9458952b51cfd7e6677#diff-a2f17c99c50d86d5160c8f7f0261fbbd),期待看到其他东西放在它的位置,但事实并非如此。相反,它已与create_proc_entry()一起弃用。

那么我应该如何重写行boot1_proc_entry->read_proc = boot1_read;(这里的完整文件:https://github.com/tangrs/linux/blob/nspire/arch/arm/mach-nspire/boot1.c),以便用当前的内核源代码编译?

1 个答案:

答案 0 :(得分:1)

函数proc_create_data有原型

struct proc_dir_entry *proc_create_data(const char *, umode_t,
                       struct proc_dir_entry *,
                       const struct file_operations *,
                       void *);

及其第4个参数是文件操作的结构。

要指定如何从文件中读取数据,您需要设置该结构的.read字段:这是替换(旧)分配read_proc proc_dir_entry对象中的字段。

虽然.read函数(回调)的签名非常通用:

ssize_t (*read) (struct file * file, char __user * buf, size_t size, loff_t * ppos);

对于简单的情况,Linux内核有几个帮助器来实现这个功能。

例如,如果您想将某个缓冲区“映射”为文件内容,可以使用simple_read_from_buffer帮助程序:

ssize_t my_read (struct file * file, char __user * buf, size_t size, loff_t * ppos)
{
    return simple_read_from_buffer(
        buf, size, ppos, // first 3 arguments are just ones for .read function
        NSPIRE_BOOT1_VIRT_BASE, // address of the buffer's start
        NSPIRE_BOOT1_SIZE // size of the buffer
    )
}

其余代码:

// Define file operations for given file.
static const struct file_operations my_fops = {
    .owner = THIS_MODULE, // This is useful almost in any case
    .read = my_read, // Setup .read function
};

// And create the file itself
entry = proc_create_data(BOOT1_PROCFS_NAME, 0644, NULL, &my_fops, NULL);