Linux kernel 在内核驱动程序中,为什么mmap不能在procfs中工作?

Linux kernel 在内核驱动程序中,为什么mmap不能在procfs中工作?,linux-kernel,linux-device-driver,embedded-linux,Linux Kernel,Linux Device Driver,Embedded Linux,我实现了mmap函数,并将其挂载到文件操作中。 并在/proc中创建一个文件。 但当我insmod时,它会响应“mmap\u示例2:未知符号\u页面\u可访问\u默认值” insmod:无法插入'mmap_example2.ko':模块中的未知符号或未知参数 当我从文件操作中删除mmap函数时,可以插入它。 那么我是不是忽略了什么?如何使mmap在procfs中工作 代码如下 #include <linux/init.h> #include <linux/module.h>

我实现了mmap函数,并将其挂载到文件操作中。 并在/proc中创建一个文件。 但当我insmod时,它会响应“mmap\u示例2:未知符号\u页面\u可访问\u默认值” insmod:无法插入'mmap_example2.ko':模块中的未知符号或未知参数

当我从文件操作中删除mmap函数时,可以插入它。 那么我是不是忽略了什么?如何使mmap在procfs中工作

代码如下

#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>

#define FILE_NAME "test"

typedef enum ALLOC_TYPE
{
    KMALLOC = 0, VMALLOC, MAX_ALLOC_TYPE,
} eAllocType;

static unsigned char array[10]={0,1,2,3,4,5,6,7,8,9};
static unsigned char *buffer;

static int file_open(struct inode *pInode, struct file *pFile)
{
    printk("%s\n", __FUNCTION__);
    return 0;
}

static int file_release(struct inode *pInode, struct file *pFile)
{
    printk("%s\n", __FUNCTION__);
    return 0;
}

static int file_mmap(struct file *pFile, struct vm_area_struct* pVMA)
{
    unsigned long page;
    unsigned char i;
    unsigned long start = (unsigned long)pVMA->vm_start;
    unsigned long size = (unsigned long)(pVMA->vm_end - pVMA->vm_start);

    page = virt_to_phys(buffer);

    if(remap_pfn_range(pVMA,start,page>>PAGE_SHIFT,size,PAGE_SHARED))
    return -1;

     for(i=0;i<10;i++)
         buffer[i] = array[i];
     return 0;
}

struct file_operations file_ops =
{
    .open       = file_open,
    .release    = file_release,
    .mmap       = file_mmap,
};

static int mmap_example2_init(void)
{
    struct proc_dir_entry* entry = NULL;
    printk("%s init\n", __FUNCTION__);
    if(!(entry = create_proc_entry(FILE_NAME,0666,NULL)))
    {
    printk("%s fail to create proc file\n",__FUNCTION__);
    return -EINVAL;
    }
    entry->proc_fops = &file_ops;
    buffer = kmalloc(10,GFP_KERNEL);
    if (!buffer)
    {
    printk("allocate mem error\n");
    return -1;
    }
    SetPageReserved(virt_to_page(buffer));
    return 0;
}

static void mmap_example2_exit(void)
{
    printk("%s exit\n", __FUNCTION__);
    remove_proc_entry(FILE_NAME,NULL);
    ClearPageReserved(virt_to_page(buffer));
    kfree(buffer);
}

module_init(mmap_example2_init);
module_exit(mmap_example2_exit);
#包括
#包括
#包括
#包括
#包括
#包括
#定义文件名“测试”
类型定义枚举分配类型
{
KMALLOC=0,VMALLOC,MAX_ALLOC_类型,
}eAllocType;
静态无符号字符数组[10]={0,1,2,3,4,5,6,7,8,9};
静态无符号字符*缓冲区;
静态int文件\u打开(结构inode*pInode,结构文件*pFile)
{
printk(“%s\n”,函数);
返回0;
}
静态int文件发布(结构inode*pInode,结构文件*pFile)
{
printk(“%s\n”,函数);
返回0;
}
静态int文件\u mmap(结构文件*pFile,结构vm\u区域\u结构*pVMA)
{
未签名的长页;
无符号字符i;
无符号长启动=(无符号长)pVMA->vm\U启动;
无符号长字符=(无符号长字符)(pVMA->vm\U end-pVMA->vm\U start);
页面=虚拟到物理(缓冲区);
if(重新映射pfn范围(pVMA、开始、页面>>页面移位、大小、页面共享))
返回-1;
对于(i=0;iproc\u fops=&file\u ops;
buffer=kmalloc(10,GFP_内核);
如果(!缓冲区)
{
printk(“分配内存错误\n”);
返回-1;
}
SetPageReserved(虚拟到虚拟页面(缓冲区));
返回0;
}
静态无效mmap_示例2_退出(无效)
{
printk(“%s exit\n”,函数);
删除\u proc\u条目(文件名,NULL);
ClearPageReserved(虚拟到虚拟页面(缓冲区));
kfree(缓冲区);
}
模块初始化(mmap示例2初始化);
模块退出(mmap示例2退出);

要添加文件操作,请使用proc\u create而不是create\u proc\u条目,并将文件操作对象传递给它

static struct file_operations myops = 
{
    .read = myread,
    .mmap = mymmap,
};
static int simple_init(void)
{
    ent=proc_create("mytest",0660,NULL,&myops);
    printk(KERN_ALERT "hello, module %d...\n",irq);
    return 0;
}

它不工作。仍然使用proc\u create响应“mmap\u example2:Unknown symbol\u page\u cacable\u default insmod:cannot insert'mmap\u example2.ko”:模块中的未知符号,或未知参数“what is the kernel version”仍然不工作。内核版本是2.6.27.29。应该启用哪个配置?首先尝试将mmap保留为空(仅返回0)然后看看是否会出现同样的错误。如果不将virt_添加到_phys并再次测试它,当我将mmap留空时,它会工作。当此函数具有remap_pfn_范围时,会发生错误。因此,此函数实现了这一点。但我将此mmap放入char设备驱动程序中,并成功工作。但我仍然不知道为什么procfs可以使用mmap?