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

相关推荐
Bert.Cai13 分钟前
Linux let命令详解
linux·运维·服务器
枕星而眠17 分钟前
Linux 线程:原理、属性、实战与面试避坑
linux·运维·c语言·面试
不脱发的程序猿17 分钟前
嵌入式软件工程师,怎么把 AI 工具用顺手?
人工智能·单片机·嵌入式硬件·嵌入式
晚风予卿云月22 分钟前
【Linux】环境变量概念、作用、配置与修改详解
linux·运维·服务器·环境变量
r-t-H29 分钟前
从零开始搭建CDH-第十二章
linux·hive·spark·centos·hbase
平凡灵感码头33 分钟前
芯片合封是个嘛?
单片机·嵌入式硬件
~黄夫人~41 分钟前
零基础速通|Windows&Linux 常用命令行对照表大全
linux·运维·windows·笔记·备忘录·整理表格
benjiangliu44 分钟前
LINUX系统-17-EXT系列文件系统(二)
linux·运维·服务器
杨云龙UP1 小时前
Linux 根分区被日志吃满?一次 58G Broker 日志清理实战_2026-05-20
linux·运维·服务器·数据库·hdfs·apache
络合白泽1 小时前
Debian 13 + NVIDIA Optimus 笔记本:从零配置 Wayland Explicit Sync 完整指南
运维·debian