Linux 内核驻留在内存中的什么位置?

Linux 内核驻留在内存中的什么位置?

在我的一些书中,我在笔记中提到 Linux 内核驻留在0xc0000000032 位系统上,并且出于性能原因被映射到用户空间。

这准确吗?我如何验证这一点?

另外,64 位系统上的内核驻留在哪里?还在吗0xc00000000,还是别的地方?

答案1

物理内存

在物理内存中,内核通常驻留在上面的随机偏移处0x1000000。这取决于内核配置选项和CONFIG_PHYSICAL_START内核命令行选项/ ,如中所述CONFIG_PHYSICAL_ALIGNCONFIG_RANDOMIZE_BASEkaslrnokaslrLinux 内部书籍

虚拟内存(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 位用户区)

相关内容