Linux内核高端内存(High Memory)简介

Linux 内核中的高端内存(High Memory)是 32 位系统(如 x86)中特有的概念,用于解决物理内存超过内核线性地址空间限制的问题。由于 32 位系统的虚拟地址空间最大为 4GB(默认内核空间占用 1GB,用户空间 3GB),当物理内存超过内核可直接映射的范围(通常是 896MB)时,剩余的内存需要通过特殊机制进行管理,这就是高端内存的由来。64 位系统因虚拟地址空间极大(如 64TB),无需高端内存机制。

一、高端内存的背景
1. 32 位系统的地址空间限制
   - 内核默认将虚拟地址空间的 `0xC0000000`(3GB)到 `0xFFFFFFFF`(4GB)划分为内核空间(共 1GB)。
   - 内核需要直接映射部分物理内存(称为低端内存,ZONE_NORMAL和ZONE_DMA),以便快速访问。这通常限制为 896MB(剩余的 128MB 用于其他内核映射)。
   - 当物理内存超过 896MB 时,剩余的部分称为高端内存(`ZONE_HIGHMEM`),无法直接通过线性映射访问。

2. 为什么需要高端内存
   若物理内存超过 1GB,内核必须通过动态映射机制访问超出 896MB 的部分,否则无法利用全部物理内存。

 

二、高端内存的分配方式
内核通过以下三种主要机制管理高端内存:

1. vmalloc 分配
- 用途:分配虚拟地址连续但物理地址不连续的内存块。
- 适用场景:需要大块内存但无需物理连续性的场景(如模块加载)。
- 特点:
  - 通过 `vmalloc()` 函数分配。
  - 内存来自高端内存区域。
  - 需要建立页表映射,可能引发 TLB 刷新,效率较低。

2. 持久映射(kmap)
- 用途:将高端内存的物理页临时映射到内核的虚拟地址空间。
- 适用场景:需要长时间访问高端内存页(如文件系统缓存)。
- 特点:
  - 使用 `kmap(struct page *)` 和 `kunmap()` 函数。
  - 映射关系保存在内核的持久映射区(`PKMAP_BASE` 到 `PKMAP_BASE + 4MB`)。
  - 映射数量有限(默认 1024 个页),可能导致竞争,需睡眠等待空闲项。

3. 固定映射(kmap_atomic)
- 用途:临时快速映射高端内存页,适用于原子上下文(如中断处理)。
- 适用场景:短时间访问高端内存(如网络数据包处理)。
特点:
  - 使用 `kmap_atomic(struct page *)` 和 `kunmap_atomic()`。
  - 映射到固定映射区(`FIXADDR_START` 到 `FIXADDR_TOP`),每个 CPU 有独立映射槽。
  - 无需加锁,但映射在进程切换时可能失效(依赖上下文)。

三、高端内存分配流程
1. 物理页分配
   通过伙伴系统(Buddy System)从 `ZONE_HIGHMEM` 分配物理页(`alloc_pages()`)。
2. 建立临时映射  
   使用 `kmap()` 或 `kmap_atomic()` 将物理页映射到内核虚拟地址空间。
3. 访问内存 
   通过返回的虚拟地址直接读写数据。
4. 解除映射
   使用 `kunmap()` 或 `kunmap_atomic()` 释放映射,物理页可被回收。

 

四、代码示例

 

#include <linux/highmem.h>

void example_highmem_access(void) {
    struct page *highmem_page;
    void *vaddr;

    // 1. 分配高端内存页
    highmem_page = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
    if (!highmem_page) return;

    // 2. 映射到内核虚拟地址
    vaddr = kmap(highmem_page);

    // 3. 读写数据
    memset(vaddr, 0, PAGE_SIZE);
    printk("Data: %d\n", *(int *)vaddr);

    // 4. 解除映射
    kunmap(highmem_page);
    __free_pages(highmem_page, 0);
}

 

五、高端内存的优缺点
 优点: 

  • 支持 32 位系统使用大内存
  • 灵活管理物理内存
  • 避免浪费线性地址空间 

缺点

  • 映射/解除映射增加开销   
  • 持久映射区容量有限,可能阻塞  
  • 固定映射的上下文依赖性        |

六、64 位系统的变化
在 64 位架构(如 x86_64)中,内核虚拟地址空间极大(如 128TB),可直接线性映射所有物理内存(`phys_base` 偏移),因此不再需要高端内存机制。所有物理内存属于 `ZONE_NORMAL`,内核可直接访问。

总结
高端内存是 32 位 Linux 内核为突破地址空间限制而设计的动态映射机制,通过 `vmalloc`、`kmap` 和 `kmap_atomic` 实现灵活的内存管理。尽管在 64 位系统中已过时,理解其原理仍对深入掌握内核内存管理至关重要。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灿烂的贝壳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值