首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修复错误:从不兼容的指针类型传递'proc_create‘的参数4

如何修复错误:从不兼容的指针类型传递'proc_create‘的参数4
EN

Stack Overflow用户
提问于 2020-11-20 22:46:43
回答 1查看 2.5K关注 0票数 5

我正在尝试将内容加载到我的内核中,以了解如何添加内容!

我这里有两个文件!

下面是skynet.c:

代码语言:javascript
复制
#include <linux/module.h>    // included for all kernel modules
#include <linux/kernel.h>    // included for KERN_INFO
#include <linux/init.h>      // included for __init and __exit macros

#include <linux/proc_fs.h>   // file operations
#include <linux/seq_file.h>  // seq_read, ...

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dr. Dyson");
MODULE_DESCRIPTION("Global Information Grid");

static int skynet_show(struct seq_file *m, void *v);

static int skynet_open(struct inode *inode, struct  file *file);

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


static int skynet_show(struct seq_file *m, void *v) {
 here:
  seq_printf(m, "Skynet location: 0x%lx\n", (unsigned long)&&here);
  return 0;
}

static int skynet_open(struct inode *inode, struct  file *file) {
  return single_open(file, skynet_show, NULL);
}


static int __init skynet_init(void) {
  proc_create("skynet", 0, NULL, &skynet_fops);
  printk(KERN_INFO "Skynet in control\n");

  return 0;
}

static void __exit skynet_cleanup(void) {
  remove_proc_entry("skynet", NULL);
  printk(KERN_INFO "I'll be back!\n");
}

module_init(skynet_init);
module_exit(skynet_cleanup);

下面是Makefile:

obj-m += skynet.o

全部:生成-C /lib/-r/$(shell uname /build M=$)PWD模块

清理:清理-C /lib/-r/$(Shell uname Module)/build M=$(PWD)

但是当我在make中写的时候,我在下面的终端中得到了这个错误:

代码语言:javascript
复制
make -C /lib/modules/5.8.0-29-generic/build M=/home/jonteyh/ID1200/Device/skynet modules
make[1]: Entering directory '/usr/src/linux-headers-5.8.0-29-generic'
  CC [M]  /home/jonteyh/ID1200/Device/skynet/skynet.o
/home/jonteyh/ID1200/Device/skynet/skynet.c: In function ‘skynet_init’:
/home/jonteyh/ID1200/Device/skynet/skynet.c:37:34: error: passing argument 4 of ‘proc_create’ from incompatible pointer type [-Werror=incompatible-pointer-types]
   37 |   proc_create("skynet", 0, NULL, &skynet_fops);
      |                                  ^~~~~~~~~~~~
      |                                  |
      |                                  const struct file_operations *
In file included from /home/jonteyh/ID1200/Device/skynet/skynet.c:5:
./include/linux/proc_fs.h:107:122: note: expected ‘const struct proc_ops *’ but argument is of type ‘const struct file_operations *’
  107 | struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct proc_ops *proc_ops);
      |                                                                                                   ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:290: /home/jonteyh/ID1200/Device/skynet/skynet.o] Error 1
make[1]: *** [Makefile:1780: /home/jonteyh/ID1200/Device/skynet] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.8.0-29-generic'
make: *** [Makefile:4: all] Error 2

我尝试的是将file_operations更改为proc_ops以下内容:

代码语言:javascript
复制
static const struct proc_ops skynet_fops = {
  .owner = THIS_MODULE,
  .open = skynet_open,
  .read = seq_read,
  .llseek = seq_lseek,
  .release = single_release,
};

但后来我得到了其他错误,比如release不存在。如何解决此错误不兼容??

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-20 23:47:56

有两种解决方案。

第一个解决方案是在5.6或更高版本的内核中用struct proc_ops替换struct file_operations

代码语言:javascript
复制
#include <linux/version.h>
#include <linux/module.h>    // included for all kernel modules
#include <linux/kernel.h>    // included for KERN_INFO
#include <linux/init.h>      // included for __init and __exit macros

#include <linux/proc_fs.h>   // file operations
#include <linux/seq_file.h>  // seq_read, ...

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dr. Dyson");
MODULE_DESCRIPTION("Global Information Grid");

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
#define HAVE_PROC_OPS
#endif

static int skynet_show(struct seq_file *m, void *v);

static int skynet_open(struct inode *inode, struct  file *file);

#ifdef HAVE_PROC_OPS
static const struct proc_ops skynet_ops = {
  .proc_open = skynet_open,
  .proc_read = seq_read,
  .proc_lseek = seq_lseek,
  .proc_release = single_release,
};
#else
static const struct file_operations skynet_ops = {
  .owner = THIS_MODULE,
  .open = skynet_open,
  .read = seq_read,
  .llseek = seq_lseek,
  .release = single_release,
};
#endif


static int skynet_show(struct seq_file *m, void *v) {
 here:
  seq_printf(m, "Skynet location: 0x%lx\n", (unsigned long)&&here);
  return 0;
}

static int skynet_open(struct inode *inode, struct  file *file) {
  return single_open(file, skynet_show, NULL);
}


static int __init skynet_init(void) {
  proc_create("skynet", 0, NULL, &skynet_ops);
  printk(KERN_INFO "Skynet in control\n");

  return 0;
}

static void __exit skynet_cleanup(void) {
  remove_proc_entry("skynet", NULL);
  printk(KERN_INFO "I'll be back!\n");
}

module_init(skynet_init);
module_exit(skynet_cleanup);

第二种解决方案是,对于内核版本4.18或更高版本,当所需的只是一个基本的、只读的proc文件时,用proc_create_single替换proc_create

代码语言:javascript
复制
#include <linux/version.h>
#include <linux/module.h>    // included for all kernel modules
#include <linux/kernel.h>    // included for KERN_INFO
#include <linux/init.h>      // included for __init and __exit macros

#include <linux/proc_fs.h>   // file operations
#include <linux/seq_file.h>  // seq_read, ...

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dr. Dyson");
MODULE_DESCRIPTION("Global Information Grid");

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,18,0)
#define HAVE_PROC_CREATE_SINGLE
#endif


static int skynet_show(struct seq_file *m, void *v) {
 here:
  seq_printf(m, "Skynet location: 0x%lx\n", (unsigned long)&&here);
  return 0;
}

#ifndef HAVE_PROC_CREATE_SINGLE
static int skynet_open(struct inode *inode, struct  file *file) {
  return single_open(file, skynet_show, NULL);
}

static const struct file_operations skynet_fops = {
  .owner = THIS_MODULE,
  .open = skynet_open,
  .read = seq_read,
  .llseek = seq_lseek,
  .release = single_release,
};
#endif


static int __init skynet_init(void) {
#ifdef HAVE_PROC_CREATE_SINGLE
  proc_create_single("skynet", 0, NULL, skynet_show);
#else
  proc_create("skynet", 0, NULL, &skynet_fops);
#endif
  printk(KERN_INFO "Skynet in control\n");

  return 0;
}

static void __exit skynet_cleanup(void) {
  remove_proc_entry("skynet", NULL);
  printk(KERN_INFO "I'll be back!\n");
}

module_init(skynet_init);
module_exit(skynet_cleanup);
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64931555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档