在 Linux 内核代码中替代 create_proc_entry() 和 read_proc
Alternative to create_proc_entry() and read_proc in Linux kernel code
几年前,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)以便它可以使用当前的内核源代码进行编译?
函数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 内核有几个帮助程序来为简单的情况实现这个功能。
例如,如果你想"map"一些缓冲区作为文件的内容,你可以使用simple_read_from_buffer
helper:
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);
几年前,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)以便它可以使用当前的内核源代码进行编译?
函数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 内核有几个帮助程序来为简单的情况实现这个功能。
例如,如果你想"map"一些缓冲区作为文件的内容,你可以使用simple_read_from_buffer
helper:
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);