是否会直接访问用户空间地址而不是copy_to_user?

时间:2016-08-26 05:06:46

标签: c linux-kernel

以下是我的简单驱动程序代码的摘录。

int vprobe_ioctl( struct file *filep, unsigned int cmd, void *UserInp)
{
    case IOCTL_GET_MAX_PORTS:

        *(int*)UserInp = TotalPorts;

    #if ENABLED_DEBUG
        printk("Available port :%u \n ", TotalPorts);
    #endif
        break;
}

我不知道在写入用户空间内存时应该使用的函数copy_to_user。代码直接访问用户地址。但是我的开发系统(x86_64架构)中没有任何内核崩溃。它按预期工作。

但是当我在其他一些x86_64机器中插入.ko文件时,有时我会看到内核崩溃。所以,我用copy_to_user替换了直接访问,它可以工作。

有人可以解释一下,

i)如何直接访问用户地址?

ii)为什么我在一些系统中看到内核崩溃,而在某些其他系统中它运行良好。系统之间是否存在任何内核配置不匹配,因为内核可以直接访问用户进程的虚拟地址?

注意:我使用的所有系统都具有相同的操作系统和内核.-通过kickstart生成相同的图像。 - 没有任何差异。

提前致谢。

1 个答案:

答案 0 :(得分:1)

看到崩溃会很有趣。现在,我所说的是基于我对记忆如何运作的了解的假设。 用户空间内存是虚拟的。这意味着特定进程地址X现在位于某个物理内存上,此物理内存是当前分配给进程的内存页面。复制到用户首先检查给定的内存是否真正属于进程和其他安全检查。除此之外还有地图问题。

内核内存有自己的地址空间,需要将虚拟映射到物理地址。内核使用mmu的帮助(这在每个架构中是不同的)。在x86中,内核虚拟和用户虚拟之间的映射是1:1(这里有不同的问题)。在其他系统中,这并非总是如此。