【问题标题】:copy_from_user and segmentationcopy_from_user 和分段
【发布时间】:2016-07-13 08:17:42
【问题描述】:

我正在阅读“The Linux Kernel Module Programming Guide”中的一段,我对以下段落有一些疑问。

copy_from_user 或 get_user 的原因是 Linux 内存(在 Intel架构,在其他一些处理器下可能会有所不同) 是分段的。这意味着指针本身不引用 内存中的唯一位置,仅内存段中的位置,以及 您需要知道它能够使用哪个内存段。 内核有一个内存段,每个内核都有一个内存段 进程。

但是据我了解,Linux 使用分页而不是分段,并且 0xc0000000 及以上的虚拟地址具有内核映射。

  1. 我们是否使用 copy_from_user 来适应旧内核?
  2. 当前的 linux 内核是否以任何方式使用分段?如果有怎么办?
  3. 如果 (1) 不成立,使用 copy_from_user 还有其他优势吗?

【问题讨论】:

    标签: c linux linux-kernel


    【解决方案1】:

    是的。我也不喜欢这种解释。从技术意义上讲,细节基本上是正确的(另请参见Why does Linux on x86 use different segments for user processes and the kernel?),但正如您所说,linux 通常映射内存以便内核代码可以直接访问它,所以我认为这不是为什么copy_from_user 的一个很好的解释等实际存在。

    IMO,使用copy_from_user / copy_to_user(和朋友)的主要原因仅仅是有许多事情需要检查(需要防范的危险),而且将所有这些检查放在一个地方是有意义的。您不希望每个需要从用户空间复制数据进出的地方都必须重新实施所有这些检查。特别是当细节可能因一种架构而异时。

    例如,当您需要复制到该内存或从该内存复制时,可能实际上不存在用户空间页面,因此从可以容纳页面错误的上下文中进行调用很重要(因此睡觉)。

    此外,需要仔细检查用户空间数据指针,以确保它们实际上指向用户空间并且它们指向数据区域,并且复制长度不会超出有效区域的末尾,等等。

    最后,用户空间实际上可能与内核共享相同的页面映射。曾经有一个针对 32 位 x86 的 linux 补丁,它使完整的 4G 虚拟地址空间可供用户空间进程使用。在这种情况下,内核代码不能假设用户空间指针可以直接访问,并且这些函数可能需要一次映射一个单独的用户空间页面才能访问它们。 (见4GB/4GB Kernel VM Split

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-31
      • 2015-06-06
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-24
      相关资源
      最近更新 更多