ARM Linux 上的内核内存布局

Russell King <rmk@arm.linux.org.uk>

2005年11月17日 (2.6.15)

本文描述了 Linux 内核在 ARM 处理器上使用的虚拟内存布局。它指出了哪些区域可供平台自由使用,哪些区域被通用代码占用。

ARM CPU 最大能够寻址 4GB 的虚拟内存空间,该空间必须在用户空间进程、内核和硬件设备之间共享。

随着 ARM 架构的成熟,有必要为新功能预留虚拟内存空间的某些区域;因此,随着时间推移,本文档可能会预留更多的虚拟内存空间。

起始

结束

用途

ffff8000

ffffffff

供 copy_user_page / clear_user_page 使用。对于 SA11xx 和 Xscale,这用于设置微缓存(minicache)映射。

ffff4000

ffffffff

ARMv6 及更高版本 CPU 上的缓存别名(cache aliasing)。

ffff1000

ffff7fff

保留。平台不得使用此地址范围。

ffff0000

ffff0fff

CPU 向量页。如果 CPU 支持向量重定位(控制寄存器 V 位),CPU 向量将映射到此处。

fffe0000

fffeffff

XScale 缓存刷新区。这在 proc-xscale.S 中用于刷新整个数据缓存。(XScale 没有 TCM。)

fffe8000

fffeffff

针对 CPU 内部装有 DTCM 的平台的 DTCM 映射区域。

fffe0000

fffe7fff

针对 CPU 内部装有 ITCM 的平台的 ITCM 映射区域。

ffc80000

ffefffff

固定映射(Fixmap)映射区域。由 fix_to_virt() 提供的地址将位于此处。

ffc00000

ffc7ffff

保护区(Guard region)

ff800000

ffbfffff

固件提供的 DT blob 的永久固定只读映射

fee00000

feffffff

PCI I/O 空间的映射。这是 vmalloc 空间内的静态映射。

VMALLOC_START

VMALLOC_END-1

vmalloc() / ioremap() 空间。由 vmalloc/ioremap 返回的内存将动态放置在该区域中。特定于机器的静态映射也通过 iotable_init() 位于此处。VMALLOC_START 基于 high_memory 变量的值,VMALLOC_END 等于 0xff800000。

PAGE_OFFSET

high_memory-1

内核直接映射的 RAM 区域。该区域映射平台的 RAM,通常以 1:1 的关系映射所有平台 RAM。

PKMAP_BASE

PAGE_OFFSET-1

永久内核映射。将 HIGHMEM 页映射到内核空间的一种方法。

MODULES_VADDR

MODULES_END-1

内核模块空间。通过 insmod 插入的内核模块使用动态映射放置在此处。

TASK_SIZE

MODULES_VADDR-1

当启用 KASan 时的 KASan 影子内存。从 MODULES_VADDR 到内存顶部的范围在此处被映射为每字节内存对应 1 位的影子空间。

00001000

TASK_SIZE-1

用户空间映射。线程级映射通过 mmap() 系统调用放置在此处。

00000000

00000fff

CPU 向量页 / 空指针陷阱。不支持向量重映射的 CPU 将其向量页放置在此处。内核和用户空间的空指针解引用也通过此映射捕获。

请注意,与上述区域冲突的映射可能会导致内核无法启动,或者可能导致内核在运行时(最终)发生 panic。

由于未来的 CPU 可能会影响内核映射布局,用户程序绝不能访问未在其 0x0001000 到 TASK_SIZE 地址范围内映射的任何内存。如果它们希望访问这些区域,必须使用 open() 和 mmap() 建立自己的映射。