Linux内高端内存

高端内存(High Memory)是 32 位 CPU 架构下的产物,是"虚拟地址空间不足"导致的妥协。而在 AArch64(64 位)架构下,虚拟地址空间巨大,不再存在这个问题,因此不需要高端内存。

下面详细展开讲解。


一、 什么是"高端内存"?为什么会有它?

要理解高端内存,必须回到 32 位 Linux 系统 的背景下。

1. 32 位系统的地址空间限制

在 32 位系统中,CPU 的寻址范围是 232=4GB2^{32} = 4GB232=4GB。Linux 内核通常将这 4GB 的虚拟地址空间 按照 3:1 的比例进行划分:

  • 0 ~ 3GB (User Space):给用户态进程使用。
  • 3GB ~ 4GB (Kernel Space) :给内核态使用,只有 1GB 的大小。
2. 问题的产生:物理内存 > 内核虚拟空间

内核为了管理物理内存,需要将物理内存映射到自己的虚拟地址空间中。

  • 理想情况 :内核采用线性映射 (直接偏移),即 虚拟地址 = 物理地址 + 偏移量。这样访问效率最高。
  • 现实困境 :内核的虚拟地址空间只有 1GB
    • 如果物理内存只有 512MB,内核可以把这 512MB 全部映射到那 1GB 的空间里,绰绰有余。
    • 但是,如果物理内存有 2GB、4GB 甚至更多呢? 内核那区区 1GB 的虚拟窗口,根本无法一次性"看全"所有的物理内存。
3. 解决方案:高端内存 (HighMem)

为了解决这个问题,Linux 内核将那 1GB 的内核虚拟空间分成了两部分:

  1. 低端内存 (Low Memory / ZONE_NORMAL)

    • 大约前 896MB 的物理内存。
    • 这部分内存被永久、线性地映射到内核虚拟空间。内核可以直接通过指针访问,效率极高。
    • 用于存放内核代码、页表、关键数据结构(如 task_struct)。
  2. 高端内存 (High Memory / ZONE_HIGHMEM)

    • 物理内存中超过 896MB 的部分。
    • 内核不能直接访问这部分内存,因为没有固定的虚拟地址映射。
    • 访问方式 :当内核需要读写这部分物理内存时,必须使用 kmap() 等函数,在内核虚拟空间的最后 128MB(专门留出的动态映射区)中临时借用 一个虚拟地址,建立映射,用完后再用 kunmap() 解除映射。

比喻

这就好比你只有一扇很小的窗户(1GB 的内核空间),而外面的风景(物理内存)很大。

  • 窗户正对着的风景(低端内存),你随时都能看到。
  • 窗户两边的风景(高端内存),你必须探出头去,或者用镜子折射(动态映射)才能看到,看完还得把头缩回来,非常麻烦且慢。

二、 为什么 AArch64 (ARM64) 上没有高端内存?

到了 64 位时代(x86_64 或 AArch64),情况发生了根本性的变化。

1. 巨大的虚拟地址空间

在 64 位架构下,理论寻址范围是 2642^{64}264。虽然实际硬件通常只实现了 48 位或 52 位,但这依然是一个天文数字:

  • 48 位地址空间 = 256 TB
  • Linux 内核通常将这巨大的空间对半切分,内核空间拥有 128 TB 的虚拟地址范围。
2. 物理内存 < 内核虚拟空间

现在的服务器或手机,物理内存通常是 8GB、16GB,哪怕是顶配服务器也就几 TB。
128 TB 的内核虚拟地址空间 >>> 实际的物理内存大小。

3. 结果:全员"低端内存"

因为内核的虚拟地址空间太大了,大到可以把所有的物理内存(哪怕你有 100TB)都一次性、永久地进行线性映射(Direct Mapping)。

  • 内核不再需要"临时借用窗口"这种蹩脚的操作。
  • 所有的物理内存都可以通过简单的线性偏移直接访问。
  • 因此,ZONE_HIGHMEM 这个内存管理区在 64 位内核配置中默认是关闭的,或者根本不存在。

比喻

在 64 位系统里,你的"窗户"变成了一整面巨大的落地玻璃墙(128TB)。无论外面的风景(物理内存)有多大,你都能一眼看全,根本不需要探头探脑。


三、 总结对比

特性 32 位 (ARM32/x86) 64 位 (AArch64/x86_64)
内核虚拟空间 只有 1GB (通常) 128 TB 或更大
物理内存瓶颈 物理内存很容易超过 1GB 物理内存远小于虚拟空间
映射方式 LowMem : 线性映射 HighMem: 动态映射 (kmap) 全部物理内存均为线性映射 (Phys-to-Virt)
性能影响 访问高端内存需要建立/解除页表映射, 直接访问,
是否存在 HighMem 存在 (ZONE_HIGHMEM) 不存在 (所有内存都是 ZONE_NORMAL)

补充:AArch64 上的内存区域 (Zones)

虽然没有了 ZONE_HIGHMEM,但 AArch64 Linux 内核中通常还有以下 Zone:

  1. ZONE_DMA / ZONE_DMA32:用于旧式硬件 DMA 寻址限制(例如只能访问低 4GB 物理内存的设备)。
  2. ZONE_NORMAL:覆盖了剩余的所有物理内存。

所以在 AArch64 上,你所有的内存条,在内核眼里都是 ZONE_NORMAL,都可以直接访问。

相关推荐
云宏信息2 小时前
运维效率提升实战:如何用轻量化云管平台统一纳管与自动化日常资源操作
运维·服务器·网络·架构·云计算
XINERTEL2 小时前
自动化测试的「千里眼」:当RTSM远程控制遇上自动化,测试效率直接拉满
运维·功能测试·自动化·以太网测试
猫豆~2 小时前
nginx实战-PHP——day2
linux·centos·云计算
杨云龙UP2 小时前
MySQL 自动备份与覆盖恢复实战:一套脚本搞定全库/按库备份恢复
linux·运维·数据库·sql·mysql
三小尛2 小时前
Linux的常见指令
linux
starvapour3 小时前
Ubuntu下sudo的免密操作
linux·ubuntu
sjg200104143 小时前
Deepin 20.9 误装gcc-8-base_8.4.0-1ubuntu1~16.04.1_amd64 后卸载
linux·运维·服务器
一帘忧梦3 小时前
linux 系统rcs脚本启动
linux·运维·lua
jerryinwuhan3 小时前
1210_1 Linux
linux·运维·服务器