内核模块的proc_create()示例

34

可以有人给我一个proc_create()的例子吗?

以前内核中使用create_proc_entry(),但现在他们使用proc_create()


2
为什么不直接下载当前的内核源代码,然后使用grep命令查找proc_create函数呢? - Roland
3个回答

39

这个示例将创建一个进程条目,允许读取访问。我认为您可以通过更改传递给函数的mode参数来启用其他类型的访问。我没有传递父目录,因为没有必要。结构体file_operations是您设置读写回调的地方。

struct proc_dir_entry *proc_file_entry;

static const struct file_operations proc_file_fops = {
 .owner = THIS_MODULE,
 .open  = open_callback,
 .read  = read_callback,
};

int __init init_module(void){
  proc_file_entry = proc_create("proc_file_name", 0, NULL, &proc_file_fops);
  if(proc_file_entry == NULL)
   return -ENOMEM;
  return 0;
}
你可以查看这个例子了解更多细节:https://www.linux.com/learn/linux-training/37985-the-kernel-newbie-corner-kernel-debugging-using-proc-qsequenceq-files-part-1

查看内核源代码时,我应该做一个备注。proc_file_fops不能位于堆栈内存(函数局部变量)中。它必须是全局变量或位于使用某些堆内存函数分配的内存中。 - Alex P.
以这种方式创建它,您可以在/proc下创建它。如何在/proc/pid/下创建它? - Zibri
3
你提供的链接已经失效了,请问能否提供一个相关的修复链接? - St.Antario

28

这里有一个名为'hello_proc'的代码,它使用较新的'proc_create()'接口。

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

static int hello_proc_show(struct seq_file *m, void *v) {
  seq_printf(m, "Hello proc!\n");
  return 0;
}

static int hello_proc_open(struct inode *inode, struct  file *file) {
  return single_open(file, hello_proc_show, NULL);
}

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

static int __init hello_proc_init(void) {
  proc_create("hello_proc", 0, NULL, &hello_proc_fops);
  return 0;
}

static void __exit hello_proc_exit(void) {
  remove_proc_entry("hello_proc", NULL);
}

MODULE_LICENSE("GPL");
module_init(hello_proc_init);
module_exit(hello_proc_exit);

这段代码来自http://pointer-overloading.blogspot.com/2013/09/linux-creating-entry-in-proc-file.html


1
谢谢提供链接,非常有用。我推荐给那些想要了解它如何工作的人阅读。 - Ivan Baidakou
2
这个例子使用 QEMU + Buildroot 测试样板代码 - Ciro Santilli OurBigBook.com
你可以这样创建它在/proc下,如何在/proc/pid/下创建它? - Zibri
感谢您的回答和提供的链接。我发布了一个更新,使您的代码可以在内核大于5.6的情况下工作-> https://dev59.com/Gmoy5IYBdhLWcg3wfeIR#66926881 - luv2learn

6

此回复仅为@Alhaad Gokhale的出色答案的更新。截至内核版本>5.6,Hello World模块如下所示:

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

static int hello_proc_show(struct seq_file *m, void *v) {
  seq_printf(m, "Hello proc!\n");
  return 0;
}

static int hello_proc_open(struct inode *inode, struct  file *file) {
  return single_open(file, hello_proc_show, NULL);
}

static const struct proc_ops hello_proc_fops = {
  .proc_open = hello_proc_open,
  .proc_read = seq_read,
  .proc_lseek = seq_lseek,
  .proc_release = single_release,
};

static int __init hello_proc_init(void) {
  proc_create("hello_proc", 0, NULL, &hello_proc_fops);
  return 0;
}

static void __exit hello_proc_exit(void) {
  remove_proc_entry("hello_proc", NULL);
}

MODULE_LICENSE("GPL");
module_init(hello_proc_init);
module_exit(hello_proc_exit);

需要注意的主要差异包括:
  1. 结构体proc_ops代替了结构体file_operations。
  2. 成员名称从.open和.read变为.proc_open和.proc_read等等。
  3. 需要删除.owner行。
更多信息:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接