proc_dir_entry警告:从不兼容的指针类型初始化[默认启用]

时间:2015-05-16 10:50:49

标签: c linux linux-kernel

我正在尝试构建一个内核模块,但是在make文件中编译时我得到了一些我无法解决的错误。这是模块的代码:

#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>

#include "sar_main.h"

#define PROCFS_NAME "sarlkm"

char procfs_buffer[PROCFS_MAX_SIZE];

static unsigned long procfs_buffer_size = 0;

struct proc_dir_entry *proc_file_entry;


int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data){
    int ret;

    printk(KERN_INFO "procfile_read (/proc/%s) called \n",  PROCFS_NAME);

    if (offset > 0){
        ret = 0;
    }
    else{
        copy_to_user(procfs_buffer, buffer, procfs_buffer_size);
        ret = procfs_buffer_size;
    }
    return ret;
}

int procfile_write(struct file *file, const char *buffer, unsigned long count, void *data){

    procfs_buffer_size = count;
    if (procfs_buffer_size > PROCFS_MAX_SIZE){
        procfs_buffer_size = PROCFS_MAX_SIZE;
    }
    if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size)){
        return -EFAULT;
    }
    return procfs_buffer_size;
}

static const struct file_operations proc_file_ops = {
    .read = procfile_read,
    .write = procfile_write,
};


static int __init sar_init(void)
{
    proc_file_entry = proc_create(PROCFS_NAME, 0644, NULL, &proc_file_ops);

    if (proc_file_entry == NULL){
        remove_proc_entry(PROCFS_NAME, NULL);
        printk(KERN_ALERT "Error: Unable to create proc file");
        return -ENOMEM;
    }


    printk(KERN_INFO "proc/%s successfully created", PROCFS_NAME);
    return 0;
}

static void __exit sar_cleanup(void)
{
    remove_proc_entry(PROCFS_NAME, NULL);
    printk(KERN_INFO "proc/%s deleted", PROCFS_NAME);
}

module_init(sar_init);
module_exit(sar_cleanup);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

所以我在定义struct proc_file_ops时遇到错误。我还没有找到proc_dir_entry的读写函数的定义,但我在网上找到了一些使用了我所使用的完全相同的语句的例子。任何人都可以解释为什么我会收到这个警告以及该怎么办呢?

1 个答案:

答案 0 :(得分:3)

根本原因

您发现的示例可能适用于某些不同的内核版本(您使用的除外)。内部内核API因版本而异。看到 Documentation/stable_api_nonsense.txt了解详情。一般的建议是查看代码示例的内核源代码。例如,看看如何在kernel/time/timer_stats.c中实现proc API(当然在你的内核代码中)。

为什么要警告

procfile_read()procfile_write()函数的签名必须与struct file_operations中的签名相同:

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

但你有下一个签名:

int procfile_read(char *buffer, char **buffer_location, off_t offset,
                  int buffer_length, int *eof, void *data)
int procfile_write(struct file *file, const char *buffer,
                   unsigned long count, void *data)

您可能需要仔细检查struct file_operations中内核版本的实际签名。

示例代码洞察

另外,您可能会注意到需要设置.read回调(在新的内核版本中):

.read = seq_read,

实际阅读应通过.open回调:

完成
.open = tstats_open,

在open函数中,你需要调用你的实际show函数,如下所示:

static int tstats_open(struct inode *inode, struct file *filp)
{
    return single_open(filp, tstats_show, NULL);
}

show功能应该有这样的签名:

static int tstats_show(struct seq_file *m, void *v)

有关完整示例,请参阅内核中的kernel/time/timer_stats.c