Linux kernel 内核模块的proc_create()示例

Linux kernel 内核模块的proc_create()示例,linux-kernel,linux-device-driver,Linux Kernel,Linux Device Driver,有人能给我举个例子吗 之前,他们在内核中使用了create\u proc\u entry(),但现在他们使用的是proc\u create()此示例将创建一个允许读取访问的proc条目。我认为您可以通过更改传递给函数的模式参数来启用其他类型的访问。我没有传递父目录,因为不需要传递。结构file\u operations是设置读写回调的地方 struct proc_dir_entry *proc_file_entry; static const struct file_operations pr

有人能给我举个例子吗


之前,他们在内核中使用了
create\u proc\u entry()
,但现在他们使用的是
proc\u create()

此示例将创建一个允许读取访问的proc条目。我认为您可以通过更改传递给函数的
模式
参数来启用其他类型的访问。我没有传递父目录,因为不需要传递。结构
file\u 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;
}

您可以查看此示例以了解更多详细信息:

这里是一个“hello\u proc”代码,它使用了较新的“proc\u 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);
#包括
#包括
#包括
静态int hello_proc_show(结构顺序文件*m,void*v){
seq_printf(m,“Hello proc!\n”);
返回0;
}
静态int hello\u proc\u open(结构索引节点*索引节点,结构文件*文件){
返回单个打开(文件,hello\u proc\u show,NULL);
}
静态常量结构文件\u操作hello\u proc\u fops={
.owner=此_模块,
.open=hello\u proc\u open,
.read=seq_read,
.llseek=seq_lseek,
.release=单次发布,
};
静态int\uu init hello\u proc\u init(void){
proc\u create(“hello\u proc”、0、NULL和hello\u proc\u fops);
返回0;
}
静态无效\uuu退出hello\uproc\u退出(无效){
删除\u proc\u条目(“hello\u proc”,NULL);
}
模块许可证(“GPL”);
模块_init(hello_proc_init);
模块退出(你好程序退出);

此代码取自

此回复只是@Alhaad Gokhale伟大答案的更新。kernels>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);
#包括
#包括
#包括
静态int hello_proc_show(结构顺序文件*m,void*v){
seq_printf(m,“Hello proc!\n”);
返回0;
}
静态int hello\u proc\u open(结构索引节点*索引节点,结构文件*文件){
返回单个打开(文件,hello\u proc\u show,NULL);
}
静态常量结构过程操作hello\u过程fops={
.proc_open=你好,proc_open,
.proc_read=seq_read,
.proc_lseek=seq_lseek,
.proc\u release=单次发布,
};
静态int\uu init hello\u proc\u init(void){
proc\u create(“hello\u proc”、0、NULL和hello\u proc\u fops);
返回0;
}
静态无效\uuu退出hello\uproc\u退出(无效){
删除\u proc\u条目(“hello\u proc”,NULL);
}
模块许可证(“GPL”);
模块_init(hello_proc_init);
模块退出(你好程序退出);
需要注意的主要区别是:

  • struct proc_ops替换struct file_操作
  • 成员名称从.open、.read更改为.proc\u open、.proc\u read
  • 需要删除.owner行
  • 进一步资料:

    • 这个

    为什么不下载当前内核源代码和grep for proc_create?感谢您提供的链接,非常有用。我建议阅读给那些想了解它是如何工作的人。这个例子有。这样你就可以在/proc下创建它。如何在/proc/pid/?下创建它谢谢你的回答+链接。我发布了一个更新,使您的代码在内核>5.6>上运行->查看内核源代码,我应该说一句话<代码>过程文件fops不得放在堆栈内存(函数局部变量)中。它必须是一个全局变量,或者位于使用某个堆内存函数分配的内存中。这样,您可以在/proc/pid/?下创建它。您提供的链接已断开。你能用一个相关的来修复它吗?