Why Does Not X86_64 Have ZONE_HIGHMEM

如果你稍微了解过Linux内核的内存管理,那么对内存分区的概念一定不陌生,Linux内核把物理内存分成了3个区,
0 – 16M 为ZONE_DMA区,
16M – 896M 为ZONE_NORMAL区,
高于896M 为ZONE_HIGHMEM区

我没有去考证过为什么要取896这个数字,但是可以肯定的是这样的划分在当时看来是合理的,然而计算机行业的发展今非昔比,现在4G的物理内存已经成为PC的标配了,CPU也进入了64位时代,很多事情都发生着改变。

在CPU还是32位的时代,CPU最大的物理寻址范围是0-4G, 在这里为了方便讨论,我们不考虑物理地址扩展(PAE)。进程的虚拟地址空间也是 4G,Linux内核把 0-3G虚拟地址空间作为用户空间,3G-4G虚拟地址空间作为内核空间。

目前几乎所有介绍Linux内存管理的书籍还是停留在32位寻址的时代,所以大家对下面这张图一定很熟悉!

(这个图画得非常详细,本篇文章我们关注的重点是 3个分区 以及最右边的线性地址空间,也就是虚拟地址空间之间的关系,另外,应该是ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM, 图中把ZONE 写成了ZUNE


然而,现在是64位的时代了!同志!醒一醒! 64位CPU的寻址空间是多大呢? 16EB! 1EB = 1024TB = 1024*1024GB,我想很多人这辈子还没见过大于1TB的内存吧,事实上也是这样,几乎没有哪个服务器能有16EB的内存,实现64位长的地址只会增加系统的复杂度和地址转换的成本,所以目前的x86_64架构CPU都遵循AMD的Canonical Form, 即只有虚拟地址的最低48位才会在地址转换时被使用, 且任何虚拟地址的48位至63位必须与47位一致, 也就是说总的虚拟地址空间为256TB。

那么在64位架构下,如何分配虚拟地址空间的呢?
0000000000000000 – 00007fffffffffff(128TB)为用户空间,
ffff800000000000 – ffffffffffffffff(128TB)为内核空间。

而且内核空间中有很多空洞, 越过第一个空洞后, ffff880000000000 – ffffc7ffffffffff(64TB)才是直接映射物理内存的区域, 也就是说默认的PAGE_OFFSET为ffff880000000000.

请关注下图的最左边,这就是目前64位的虚拟地址布局。


在本文的一开头提到的物理内存分区 ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM 就是与内核虚拟地址的直接映射有关的,如果读者不了解 内核直接映射物理地址这个概念的话,建议你去google一下,这个很简单的一一映射的概念。

既然现在内核直接映射的物理内存区域有64TB, 而且一般情况下,极少有计算机的内存能达到64TB(别说64TB了,1TB内存的也很少很少),所以整个内核虚拟地址空间都能够一一映射到计算机的物理内存上,因此,不再需要 ZONE_HIGHMEM这个分区了,现在对物理内存的划分,只有ZONE_DMA, ZONE_NORMAL,这就是本文想说的重点!

对于本文说的这些,如果您想有个更加直观的了解的话,请打开 /boot/config*** 文件,例如我的是  /boot/config-3.11.0-031100-generic  ,如果您现在用的CPU是64位,并且Linux发行版也是64位的,那么 在这个配置文件中找不到CONFIG_HIGHMEM 这个选项,而如果您的CPU是32位的,则一定会有 CONFIG_HIGHMEM 这个选项。

 

参考资料:

【1】http://adam8157.info/blog/2012/07/linux-x86-64-vm

【2】https://en.wikipedia.org/wiki/X86-64#cite_note-dfly-amd64-soc2008-43




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值