在linux内核中,mem_map
是包含所有“struct page”描述符的数组。这些页面包含lowmem中的128MiB内存,用于动态映射highmem。
由于lowmem大小为1GiB,因此mem_map
数组只有1GiB / 4KiB = 256KiB条目。如果每个条目大小为32字节,则mem_map
内存大小= 8MiB。但是如果我们可以使用mem_map
映射所有4GiB物理内存(如果我们在x86-32上有这么多物理内存可用),则mem_map数组将占用32MiB,这不是很多内核内存(或者是我错了吗?)
所以我的问题是:为什么我们首先需要将低128MiB用于间接高精度映射?或换句话说,为什么不直接在内核空间中映射所有最大4GiB物理内存(如果可用)?
注意:如果我对上面的内核源码的理解有误,请更正。谢谢!
答案 0 :(得分:1)
看这里:http://www.xml.com/ldd/chapter/book/ch13.html
内核低内存是“真正的”内存映射,在x86上使用32位指针进行寻址
内核高内存是“虚拟”内存映射,使用x86上的虚拟结构进行寻址
您不希望将它全部映射到内核地址空间,因为您无法始终解决所有这些问题,并且您需要大部分内存用于虚拟内存段(虚拟,页面映射的进程空间。)
至少,这就是我读它的方式。哇,这是你提出的一个复杂的问题
为了引起更多混淆,第13章讨论了一些无法解决32位空间的PCI设备,这是我之前评论的起源:
在x86上,由于DMA寻址问题,一些内核内存使用仅限于第一千兆字节的内存。我不是100%熟悉这个主题,但PCI总线上有DMA的共处模式。这可能就是你所看到的。
答案 1 :(得分:0)
当使用物理地址扩展时,3.6 GB不是天花板,这在大多数现代x86主板上都是常用的,特别是对于内存热插拔。
答案 2 :(得分:0)
或换句话说,为什么不映射所有那些最大的4GiB物理 内核空间中的内存(如果可用)直接?
一个原因是用户空间:每个使用空间进程都有自己的虚拟地址空间。假设你在x86上有4Gb的RAM。因此,如果我们建议内核拥有1Gb内存(~800直接映射+ ~200 vmalloc),那么所有其他~3Gb应该动态分布在用户空间中旋转的进程之间。那么当你有几个地址空间时,如何直接映射4Gbs?
为什么我们在x86上需要zone_highmem?
原因是一样的。对于低内存,内核仅保留~800Mb。所有其他内存将仅按需分配并与特定虚拟地址连接。例如,如果要执行二进制文件,将创建一个新的虚拟地址空间,并将分配一些页面来存储二进制代码和数据(堆,堆栈......)。因此,高mem的关键属性是提供动态内存分配请求,你事先不知道用户空间会触发什么......