| Zone | 物理地址范围 | 虚拟地址范围 | 用途 | |—————-|———————–|———————–|—————————–| | ZONE_DMA
| 0x00000000 - 0x00FFFFFF
| 0xC0000000 - 0xC0FFFFFF
| DMA 设备专用内存(16MB) | | ZONE_NORMAL
| 0x01000000 - 0x37FFFFFF
| 0xC1000000 - 0xF7FFFFFF
| 常规内核和用户内存(880MB) | | ZONE_HIGHMEM
| 0x38000000 - 物理内存末尾
| 动态映射(kmap
) | 超出 896MB 的物理内存 |
ZONE_HIGHMEM
:所有物理内存通过直接映射区(0xFFFF800000000000
起)线性映射。ZONE_DMA
和 ZONE_DMA32
:保留用于兼容 DMA 设备。alloc_pages
2^order
个整数页(如 order=2
分配 4 页)。struct page *page = alloc_pages(GFP_KERNEL, 2); // 分配 4 页(16KB)
vmalloc
与 kmap
| 机制 | 虚拟地址范围 | 物理内存来源 | 用途 | |—————-|——————————-|———————–|—————————–| | vmalloc
| 0xF8000000 - 0xFFFFFFFF
(32 位) | 非连续物理页 | 大块非连续内存分配 | | kmap
| 0xFFC00000 - 0xFFE00000
(Fixmap) | ZONE_HIGHMEM
| 临时映射高端内存 |
0xFFFF800000000000
)线性映射。页表项数 = 物理内存大小 / 页大小
)。| 层级 | 覆盖范围 | 条目数 | 作用 | |—————-|——————-|———–|—————————–| | PML4 | 512GB | 512 | 顶级页表 | | PDPT | 1GB | 512 | 二级页表 | | PD | 2MB | 512 | 三级页表 | | PT | 4KB | 512 | 四级页表(最终映射到物理页) |
| 字段 | 作用 | |———-|————————————————————————-| | esp0
| 内核栈指针,用户态→内核态切换时更新栈。 | | ss0
| 内核栈段寄存器(通常为 __KERNEL_DS
)。 | | cr3
| 页目录基址,任务切换时更新以实现地址空间隔离。 |
cr3
(切换页表)。esp0
和 ss0
(切换内核栈)。mmap
匿名页分配ZONE_NORMAL
分配,不足时使用 ZONE_HIGHMEM
。ZONE_DMA
、ZONE_NORMAL
等均有独立的 Buddy Allocator 管理空闲页。ZONE_DMA → ZONE_NORMAL → ZONE_HIGHMEM
(32 位)。ZONE_HIGHMEM
用于访问超出 896MB 的内存,需动态映射。ZONE_HIGHMEM
,所有物理内存直接映射。esp0
、ss0
和 cr3
是实现内核栈和地址空间隔离的核心。附录:常用命令
# 查看内存区域信息
cat /proc/zoneinfo
# 查看内核虚拟地址映射
cat /proc/vmallocinfo
# 查看页表统计
grep "DirectMap" /proc/meminfo
本文档可作为 Linux 内存管理和内核机制的快速参考指南。