繁体   English   中英

为什么在尝试从内核模块访问共享内存时出现“未处理的错误:不精确的外部异常终止”?

[英]Why do i get “Unhandled fault: imprecise external abort” while trying to access shared memory from my kernel module?

我在内核模块中有这个:

/*global scope declared*/ 
static int array[10]={1,2,3,4,5,6,7,8,9,10};

并且我具有用于打开关闭读写操作的功能,我想与本页底部的用户空间应用程序共享array[8]

在内核模块中:

static int *my_mmap (struct file *filep, struct vm_area_struct *vma ) {

    if (remap_pfn_range(vma,
                vma->vm_start,
                virt_to_phys(array)>> PAGE_SHIFT,
                10,
                vma->vm_page_prot) < 0) {
        printk("remap_pfn_range failed\n");
        return -EIO;
    }


    return 0;

用户空间源代码中的应用程序:

#define LEN (64*1024)
/* prototype for thread routine */

#define FILE_PATH "/dev/my_module"


int main() 
{
    int i=0;
    int fd = open(FILE_PATH,O_RDWR);    
    int* vadr = mmap(0, LEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

    for (i=0;i<10;++i){

        printf("%d",*(vadr+i));
    }

    return 0;
}

在很多级别上这都是错误的,我什至不知道从哪里开始:-)

  1. virt_to_phys可能实际上不适用于vmalloc分配的内存,这是Linux在大多数平台上用于动态模块数据部分的功能。
  2. 即使是这样,数据在物理内存中也可能根本不连续。
  3. 该数组可能不在页面边界上对齐。
  4. 您的数据结构为40字节,您正在映射10页随机内核内存。
  5. 如果处理器具有虚拟索引的物理标记(VIPT)缓存,则当多个虚拟映射到同一物理地址时,可能会遇到缓存一致性问题。

可能还有更多问题,但这是我想到的。

正确的做法不是在内核空间和用户空间之间共享数据,而是使用copy_to_user和好友复制数据,除非您真的知道自己在做什么以及为什么。

如果您确实必须共享内存,则分配一个空闲页面,从内核空间(例如kmap)和用户空间(就像您一样)映射它,并希望您的平台没有VIPT缓存。

我是内核编程的一个相对较新的人,因此我可能会缺少一些东西,但是在这种情况下您是否可以使用copy_to_user?

    unsigned long copy_to_user(void __user * to, const void * from, unsigned long n); 

简单来说

to = address in userspace (destination)
from = address in kernel (source)
n = number of bytes to copy 

您的数组是char数组,但是您的用户空间程序正在将其作为int数组进行访问。

有关如何在内核空间和用户空间之间正确共享数据的指南,请参阅实现将mmap从用户空间传输到内核空间的mmap 我已经在我的自定义驱动程序中实现了它,并且效果很好。 如果您不需要速度,则使用copy_to_user更安全,更轻松。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM