以下是根据聊天内容整理的技术文档,涵盖 Linux 内存管理、内核页表、任务状态段(TSS)等核心机制:


Linux 内存管理与内核机制总结

1. 内存区域(Zones)

1.1 32 位系统的内存划分

| Zone | 物理地址范围 | 虚拟地址范围 | 用途 | |—————-|———————–|———————–|—————————–| | ZONE_DMA | 0x00000000 - 0x00FFFFFF | 0xC0000000 - 0xC0FFFFFF | DMA 设备专用内存(16MB) | | ZONE_NORMAL | 0x01000000 - 0x37FFFFFF | 0xC1000000 - 0xF7FFFFFF | 常规内核和用户内存(880MB) | | ZONE_HIGHMEM | 0x38000000 - 物理内存末尾 | 动态映射(kmap) | 超出 896MB 的物理内存 |

1.2 64 位系统的变化

  • ZONE_HIGHMEM:所有物理内存通过直接映射区(0xFFFF800000000000 起)线性映射。
  • ZONE_DMAZONE_DMA32:保留用于兼容 DMA 设备。

2. 物理内存分配

2.1 alloc_pages

  • 功能:分配连续的物理页。
  • 特性
    • 返回 2^order 个整数页(如 order=2 分配 4 页)。
    • 物理地址连续,通过 Buddy Allocator 实现。
  • 示例
    struct page *page = alloc_pages(GFP_KERNEL, 2); // 分配 4 页(16KB)
    

2.2 vmallockmap

| 机制 | 虚拟地址范围 | 物理内存来源 | 用途 | |—————-|——————————-|———————–|—————————–| | vmalloc | 0xF8000000 - 0xFFFFFFFF(32 位) | 非连续物理页 | 大块非连续内存分配 | | kmap | 0xFFC00000 - 0xFFE00000(Fixmap) | ZONE_HIGHMEM | 临时映射高端内存 |


3. 内核页表管理

3.1 直接映射区(Direct Map)

  • 64 位系统:所有物理内存通过固定偏移(如 0xFFFF800000000000)线性映射。
  • 页表项数量:与物理内存容量相关(页表项数 = 物理内存大小 / 页大小)。

3.2 页表层级(x86_64)

| 层级 | 覆盖范围 | 条目数 | 作用 | |—————-|——————-|———–|—————————–| | PML4 | 512GB | 512 | 顶级页表 | | PDPT | 1GB | 512 | 二级页表 | | PD | 2MB | 512 | 三级页表 | | PT | 4KB | 512 | 四级页表(最终映射到物理页) |


4. 任务状态段(TSS)

4.1 关键字段

| 字段 | 作用 | |———-|————————————————————————-| | esp0 | 内核栈指针,用户态→内核态切换时更新栈。 | | ss0 | 内核栈段寄存器(通常为 __KERNEL_DS)。 | | cr3 | 页目录基址,任务切换时更新以实现地址空间隔离。 |

4.2 任务切换流程

  1. 保存当前任务的寄存器状态到 TSS。
  2. 加载新任务的 cr3(切换页表)。
  3. 更新 esp0ss0(切换内核栈)。
  4. 恢复新任务的寄存器状态。

5. 用户态内存分配

5.1 mmap 匿名页分配

  • 物理内存来源:优先从 ZONE_NORMAL 分配,不足时使用 ZONE_HIGHMEM
  • 页表项:用户态虚拟地址必须通过页表映射到物理页(缺页异常触发分配)。

5.2 Buddy Allocator

  • 每个 Zone 独立ZONE_DMAZONE_NORMAL 等均有独立的 Buddy Allocator 管理空闲页。
  • 分配优先级ZONE_DMA → ZONE_NORMAL → ZONE_HIGHMEM(32 位)。

6. 关键结论

  1. 32 位系统ZONE_HIGHMEM 用于访问超出 896MB 的内存,需动态映射。
  2. 64 位系统:无 ZONE_HIGHMEM,所有物理内存直接映射。
  3. DMA Zone:前 4MB 可分配,除非被 BIOS 保留。
  4. 任务切换:TSS 的 esp0ss0cr3 是实现内核栈和地址空间隔离的核心。

附录:常用命令

# 查看内存区域信息
cat /proc/zoneinfo

# 查看内核虚拟地址映射
cat /proc/vmallocinfo

# 查看页表统计
grep "DirectMap" /proc/meminfo

本文档可作为 Linux 内存管理和内核机制的快速参考指南。