我正在阅读" The Linux Kernel Module Programming Guide"我对以下段落有一些疑问。
copy_from_user或get_user的原因是Linux内存(打开 英特尔架构,在某些其他处理器下可能会有所不同) 被分割。这意味着指针本身不会引用 内存中的唯一位置,只有内存段中的位置,以及 你需要知道它能够使用哪个内存段。 内核有一个内存段,每个内存一个 过程
然而,我的理解是Linux使用分页而不是分段,并且0xc0000000及以上的虚拟地址都有内核映射。
答案 0 :(得分:2)
呀。我也不喜欢那种解释。细节在技术意义上基本上是正确的(另请参阅Why does Linux on x86 use different segments for user processes and the kernel?)但正如您所说,linux通常映射内存以便内核代码可以直接访问它,因此我认为这不是一个很好的解释为什么{ {1}}等确实存在。
IMO,主要使用copy_from_user
/ copy_from_user
(和朋友)的原因只是有很多事情需要检查(要防范的危险) ),将所有这些检查放在一个地方是有意义的。您不希望每个需要从用户空间复制数据的地方都必须重新实现所有这些检查。特别是当细节可能因建筑物而异。
例如,当您需要复制到该存储器或从该存储器复制时,实际上不存在用户空间页面,因此从可以容纳页面错误的上下文进行调用很重要(因此,睡觉了。)
此外,需要仔细检查用户空间数据指针,以确保它们实际指向用户空间并指向数据区域,并且复制长度不会超出有效区域的末尾,等等。
最后,实际上的用户空间可能与内核共享相同的页面映射。曾经有一个针对32位x86的Linux补丁,它为用户空间进程提供了完整的4G虚拟地址空间。在这种情况下,内核代码无法假设用户空间指针可以直接访问,并且这些函数可能需要一次映射一个用户空间页面以便访问它们。 (见4GB/4GB Kernel VM Split)