Linux 为什么x86上需要zone_highmem?

Linux 为什么x86上需要zone_highmem?,linux,memory-management,linux-kernel,Linux,Memory Management,Linux Kernel,在linux内核中,mem_-map是包含所有“结构页面”描述符的数组。这些页面包括lowmem中的128MiB内存,用于动态映射highmem 由于lowmem大小为1GiB,因此mem_map数组只有1GiB/4KiB=256KiB条目。如果每个条目大小为32字节,则mem\u映射memory size=8MiB。但是如果我们可以使用mem_-map映射所有4Gb物理内存(如果我们在x86-32上有这么多物理内存可用),那么mem_-map数组将占用32MiB,这不是很多内核内存(或者我错了

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

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

所以我的问题是:为什么我们首先需要在low中使用128MiB进行间接highmem映射?或者换句话说,为什么不直接映射内核空间中的所有最大4GiB物理内存(如果可用)

注意:如果我对上述内核源代码的理解是错误的,请更正。谢谢

看这里:

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

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

您不希望将其全部映射到内核地址空间,因为您不能总是对其全部进行寻址,并且需要将大部分内存用于虚拟内存段(虚拟的、页映射的进程空间)。

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

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


在x86上,由于DMA寻址问题,一些内核内存的使用量被限制在前千兆字节。我对这个主题不是100%熟悉,但是PCI总线上的DMA有一种兼容模式。这可能就是您所看到的。
使用物理地址扩展时,3.6 GB不是上限,这是大多数现代x86板上通常需要的,尤其是使用内存热插拔时

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

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

为什么x86上需要zone_highmem

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