根据x86和ppc上的linux设计,4g虚拟地址空间分为3:1。 用户虚拟地址直到3g。
现在,如果用户应用程序执行ioctl传递指向缓冲区的指针,内核模块,可以直接执行memcpy,我试过并且它有效。 =>为什么我们需要copy_to / copy_from用户。
注意:如果页面被换出,那么内核页面故障处理程序会将其返回,并且它对内核模块是不可见的。
需要你的想法...评论
答案 0 :(得分:9)
copy_to_user
/ copy_from_user
使用正确的函数有几个很好的理由:
在某些体系结构上,一个简单的memcpy()
使不工作,因此使用这些函数可以让您的代码在那里工作。我相信即使选择HIGHMEM
配置选项的x86也在这艘船上。
这些函数会进行access_ok()
检查,以确保真正引用的用户空间地址是真正的用户空间地址。如果只执行memcpy()
,ioctl()
的调用者可以提供与内核地址重叠的地址范围,这是一个安全漏洞。
但是,主要的原因是要正确处理错误的用户地址。如果你只使用一个裸memcpy()
,未处理的错误将导致内核oops。用户访问函数使用"fixup" mechanism,它允许处理错误(读或写很短,在这种情况下通常EFAULT
返回给用户空间。)
答案 1 :(得分:0)
你很幸运。
用户空间和内核空间在完全不同的地址空间中运行。当您copy_to_user时,内核会将用户空间虚拟地址转换为真实的物理地址,并在那里复制数据。反过来也会发生类似的过程。
如果您的硬件支持分散/聚集DMA,则可以直接跳过/从步骤复制。在这里,您将一个连续的虚拟内存块映射到一系列物理页面,然后使用该信息直接DMA到用户空间。当然,如果任何虚拟地址空间当前未映射到物理内存(思考交换或文件支持的mmaps),则会出现复杂情况。