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,都可以直接访问。

相关推荐
切糕师学AI21 小时前
ARM 中的 SVC 监管调用(Supervisor Call)
linux·c语言·汇编·arm开发
陌上花开缓缓归以21 小时前
linux jiffies 初始化不为0问题分析
linux·arm开发
霖霖总总21 小时前
[小技巧39]Linux 文件与命令查找工具(which、whereis、locate、find)全面解析
linux·运维
xlq2232221 小时前
6.Linux权限
linux
ayaya_mana1 天前
在 CentOS 7/RHEL 7 上安装并切换至新版内核
linux·运维·centos
三不原则1 天前
故障案例:数据库慢查询导致交易延迟,AIOps 如何自动定位?
运维·数据库
gzxx2007sddx1 天前
ubuntu挂载访问windows的共享文件夹
linux·运维·ubuntu·挂载·共享
市安1 天前
基于 LVS+Keepalived+NFS 的高可用 Web 集群构建与验证
运维·服务器·网络·lvs·keepalived·ipvsadm
AC赳赳老秦1 天前
Dify工作流+DeepSeek:运维自动化闭环(数据采集→报告生成)
android·大数据·运维·数据库·人工智能·golang·deepseek
真的想上岸啊1 天前
4、修改开发板内核启动日志级别
linux