【问题标题】:why do we need zone_highmem on x86?为什么我们在 x86 上需要 zone_highmem?
【发布时间】:2010-10-09 06:31:29
【问题描述】:

在 linux 内核中,mem_map 是包含所有“结构页面”描述符的数组。这些页面包括 lowmem 中的 128MiB 内存,用于动态映射 highmem。

由于lowmem大小为1GiB,所以mem_map数组只有1GiB/4KiB=256KiB的条目。如果每个条目大小为 32 字节,则 mem_map 内存大小 = 8MiB。但是如果我们可以使用mem_map 来映射所有 4GiB 物理内存(如果我们在 x86-32 上有这么多可用的物理内存),那么 mem_map 数组将占用 32MiB,这不是很多内核内存(或者我错了?)。

所以我的问题是:为什么我们首先需要将 128MiB 用于间接高端映射?或者换一种说法,为什么不直接在内核空间中映射所有最大 4GiB 物理内存(如果可用)?

注意:如果我对上面内核源码的理解有误,请指正。谢谢!

【问题讨论】:

    标签: linux memory-management linux-kernel


    【解决方案1】:

    看这里:http://www.xml.com/ldd/chapter/book/ch13.html

    内核低内存是“真正的”内存映射,在 x86 上使用 32 位指针寻址。

    内核高内存是“虚拟”内存映射,在 x86 上使用虚拟结构寻址。

    您不想将其全部映射到内核地址空间,因为您不能始终寻址所有这些,并且您需要将大部分内存用于虚拟内存段(虚拟的、页面映射的进程空间)。

    至少,我是这么读的。哇,你问的问题真复杂。

    为了引发更多混乱,第 13 章讨论了一些 PCI 设备无法处理 32 位空间,这是我之前评论的起源:

    在 x86 上,由于 DMA 寻址问题,某些内核内存使用仅限于内存的第一个千兆字节。我对这个话题不是 100% 熟悉,但是 PCI 总线上的 DMA 有一个兼容模式。这可能就是您正在查看的内容。

    【讨论】:

      【解决方案2】:

      在使用物理地址扩展时,3.6 GB 并不是上限,这在大多数现代 x86 主板上通常都需要,尤其是在内存热插拔时。

      【讨论】:

        【解决方案3】:

        或者换一种说法,为什么不映射所有那些最大 4GiB 物理 内存(如果可用)直接在内核空间中?

        一个原因是用户空间:每个用户空间进程都有自己的虚拟地址空间。假设您在 x86 上有 4Gb 的 RAM。因此,如果我们建议内核拥有 1Gb 的内存(~800 直接映射 + ~200 vmalloc),那么所有其他 ~3Gb 应该动态分布在用户空间中旋转的进程之间。那么,当您有多个地址空间时,如何直接映射您的 4Gbs?

        为什么我们在 x86 上需要 zone_highmem?

        原因是一样的。内核只为低内存保留约 800Mb。所有其他内存将仅在需要时分配并与特定的虚拟地址连接。例如,如果您将执行一个二进制文件,则会创建一个新的虚拟地址空间,并分配一些页面来存储您的二进制代码和数据(堆、堆栈...)。所以high mem的关键属性是服务于动态的内存分配请求,你永远不知道用户空间会触发什么...

        【讨论】:

          猜你喜欢
          • 2019-06-09
          • 2014-06-18
          • 2017-02-26
          • 2011-04-03
          • 2017-07-27
          • 2020-09-21
          • 2020-03-09
          • 2018-12-24
          • 2012-04-08
          相关资源
          最近更新 更多