在我的一些书中,我在笔记中提到 Linux 内核驻留在0xc00000000
32 位系统上,并且出于性能原因被映射到用户空间。
这准确吗?我如何验证这一点?
另外,64 位系统上的内核驻留在哪里?还在吗0xc00000000
,还是别的地方?
答案1
物理内存
在物理内存中,内核通常驻留在上面的随机偏移处0x1000000
。这取决于内核配置选项和CONFIG_PHYSICAL_START
内核命令行选项/ ,如中所述CONFIG_PHYSICAL_ALIGN
CONFIG_RANDOMIZE_BASE
kaslr
nokaslr
Linux 内部书籍。
虚拟内存(32 位)
在 32 位架构上,虚拟地址空间分割取决于内核配置选项CONFIG_PAGE_OFFSET
在许多架构上,这是由CONFIG_VMSPLIT_*
选项隐式设置的。内核的配置通常与内核映像一起放入/boot/config-<version>
,因此您可以检查虚拟内存中内核区域开始的偏移量grep PAGE_OFFSET "/boot/config-$(uname -r)"
。 x86 的通常配置是CONFIG_VMSPLIT_3G
将 0xC0000000 设置PAGE_OFFSET
为 0xC0000000,为内核保留地址空间的高 1 GiB。出于性能原因,此映射在所有虚拟地址空间(包括所有用户空间进程)中保持相同。
内核代码开始的确切地址位于该区域的某个位置,并且可能在启动时被随机化。这取决于与物理地址随机化相同的配置和内核命令行设置。
虚拟内存(64 位)
在 64 位架构上,情况有所不同,因为地址空间大得多。
细节取决于体系结构,但按照惯例,内核驻留在地址空间顶部的内存范围内。
x86-64
在 x86-64(又名 AMD64)上,内存布局是记录得很好。根据硬件支持和配置选项,有两种可能的配置CONFIG_X86_5LEVEL
:
开始(4级分页) | 尺寸(4 级页) | 开始(5级分页) | 尺寸(5级页) | 描述 |
---|---|---|---|---|
0xFFFF800000000000 |
8钛硼 | 0xFF00000000000000 |
4个PiB | 保护孔,也为管理程序保留 |
0xFFFF880000000000 |
0.5TiB | 0xFF10000000000000 |
0.25PiB | PTI 的 LDT 重新映射 |
0xFFFF888000000000 |
64钛硼 | 0xFF11000000000000 |
32 皮B | 所有物理内存的直接映射 |
0xFFFFC90000000000 |
32TB | 0xFFA0000000000000 |
12.5 皮B | vmalloc/ioremap空间 |
0xFFFFEA0000000000 |
1TB | 0xFFD4000000000000 |
0.5PiB | 虚拟内存映射 |
0xFFFFEC0000000000 |
16TB | 0xFFDF000000000000 |
8个PiB | KASAN 影子内存 |
从这里开始相同的布局 | ||||
0xFFFFFE0000000000 |
0.5TB | cpu_entry_area映射 | ||
0xFFFFFF0000000000 |
0.5TB | %esp 修复堆栈 | ||
0xFFFFFFEF00000000 |
64GB | EFI区域映射空间 | ||
0xFFFFFFFF80000000 |
512MB | 内核文本映射,映射到物理地址0 | ||
0xFFFFFFFFA0000000 |
1520MB | 模块映射空间 | ||
FIXADDR_START |
〜0.5MB | 内核内部修复映射范围、可变大小和偏移量 | ||
0xFFFFFFFFFF600000 |
4 KB | 旧版 vsyscall ABI |
因此,内核区域从0xFFFF800000000000
或开始0xFF00000000000000
,内核代码驻留在(通常以随机偏移量)从 开始的区域中0xFFFFFFFF80000000
。
ARM64
在 64 位 ARM 上内存布局有点类似于 x86-64 上的布局。确切的分割取决于内核配置(4kB/64kB 页,2/3/4 级分页):
页面大小 | 寻呼级别 | 内核区起始地址 |
---|---|---|
4 KB | 3 | 0xFFFFFF8000000000 |
4 KB | 4 | 0xFFFF000000000000 |
64 KB | 2 | 0xFFFFFC0000000000 |
64 KB | 3 | 0xFFFF000000000000 |
答案2
现在,由于 aslr,它驻留在半随机位置(假设您已在 64 位系统中编译了该文件,则没有理由不这样做,因为现在是 2016 年,您应该运行 64 位系统......如果您的系统水平较低)在内存上只运行 64 位内核 + 32 位用户区)