6

在 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 物理内存(如果可用)?

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

4

3 回答 3

1

看这里:http

://www.xml.com/ldd/chapter/book/ch13.html 内核低内存是“真正的”内存映射,在 x86 上用 32 位指针寻址。

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

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

。至少,我就是这样读的。哇,你问的这个问题好复杂。

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

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

于 2009-02-23T07:25:09.353 回答
0

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

于 2009-02-23T07:39:27.120 回答
0

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

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

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

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

于 2014-10-05T07:53:17.630 回答