内存管理
内存管理
使用4级页表完成虚拟内存映射
注意:
负地址(比如
-23 TB
)是从64位地址空间顶部向下计算的以字节为单位的绝对地址。当看到绝对地址和从顶部到顶部的距离时,更容易理解布局。例如
0xffffe90000000000 = =-23TB
,它比64位地址空间的低23TB
(ffffffffffffffff
)。
请注意,当我们接近地址空间的顶部时,符号将从TB
变为GB
,然后是MB/KB
。
16M TB
乍一看可能很奇怪,但它比16eb
更容易可视化大小记号,很少有人一眼就能认出16eb。它还很好地展示了64位地址空间有多大。
========================================================================================================================
Start addr | Offset | End addr | Size | 虚拟地址区域说明
========================================================================================================================
| | | |
0000000000000000 | 0 | 00007fffffffffff | 128 TB | 用户空间的虚拟内存, different per mm
__________________|____________|__________________|_________|___________________________________________________________
| | | |
0000800000000000 | +128 TB | ffff7fffffffffff | ~16M TB | ... 巨大的区域,几乎64位宽的非规范虚拟内存地址,
| | | | 内核映射的起始偏移量高达-128 TB。
__________________|____________|__________________|_________|___________________________________________________________
|
| 内核空间虚拟内存,在所有进程之间共享:
____________________________________________________________|___________________________________________________________
| | | |
ffff800000000000 | -128 TB | ffff87ffffffffff | 8 TB | ... 防护孔,也保留用于管理程序
ffff880000000000 | -120 TB | ffff887fffffffff | 0.5 TB | LDT remap for PTI
ffff888000000000 | -119.5 TB | ffffc87fffffffff | 64 TB | 直接映射所有物理内存 (page_offset_base)
ffffc88000000000 | -55.5 TB | ffffc8ffffffffff | 0.5 TB | ... 未使用的地址
ffffc90000000000 | -55 TB | ffffe8ffffffffff | 32 TB | vmalloc/ioremap 空间 (vmalloc_base)
ffffe90000000000 | -23 TB | ffffe9ffffffffff | 1 TB | ... 未使用
ffffea0000000000 | -22 TB | ffffeaffffffffff | 1 TB | 虚拟内存映射(vmemmap_base)
ffffeb0000000000 | -21 TB | ffffebffffffffff | 1 TB | ... 未使用
ffffec0000000000 | -20 TB | fffffbffffffffff | 16 TB | KASAN(动态内存检测) 影子内存
__________________|____________|__________________|_________|____________________________________________________________
|
| 从现在开始,它的布局和56位的一模一样:
____________________________________________________________|____________________________________________________________
| | | |
fffffc0000000000 | -4 TB | fffffdffffffffff | 2 TB | ... 未使用
| | | | vaddr_end for KASLR
fffffe0000000000 | -2 TB | fffffe7fffffffff | 0.5 TB | cpu_entry_area 映射
fffffe8000000000 | -1.5 TB | fffffeffffffffff | 0.5 TB | ... 未使用
ffffff0000000000 | -1 TB | ffffff7fffffffff | 0.5 TB | %esp 固定栈
ffffff8000000000 | -512 GB | ffffffeeffffffff | 444 GB | ... 未使用
ffffffef00000000 | -68 GB | fffffffeffffffff | 64 GB | EFI 区域映射空间
ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | ... 未使用
ffffffff80000000 | -2 GB | ffffffff9fffffff | 512 MB | 内核文本映射,映射到物理地址0
ffffffff80000000 |-2048 MB | | |
ffffffffa0000000 |-1536 MB | fffffffffeffffff | 1520 MB | 模块映射空间
ffffffffff000000 | -16 MB | | |
FIXADDR_START | ~-11 MB | ffffffffff5fffff | ~0.5 MB | 内核-内部定位图范围,可变大小和偏移量
ffffffffff600000 | -10 MB | ffffffffff600fff | 4 kB | 旧的vsyscall ABI
ffffffffffe00000 | -2 MB | ffffffffffffffff | 2 MB | ... 未使用
__________________|____________|__________________|_________|___________________________________________________________
使用5级页表完成虚拟内存映射
注意:
使用56位地址,用户空间内存扩展倍数为512x
,从0.125 PB
扩展到64 PB
。所有内核映射都转移到-64 PB
的起始偏移量,许多区域扩展以支持更大的物理内存。
========================================================================================================================
Start addr | Offset | End addr | Size |虚拟地址区域说明
========================================================================================================================
| | | |
0000000000000000 | 0 | 00ffffffffffffff | 64 PB | 用户空间的虚拟内存, different per mm
__________________|____________|__________________|_________|___________________________________________________________
| | | |
0100000000000000 | +64 PB | feffffffffffffff | ~16K PB | ... 巨大的,仍接近64位宽的非规范虚拟内存地址,
| | | | 直至内核映射的-64 PB起始偏移量。
__________________|____________|__________________|_________|___________________________________________________________
|
| 内核空间虚拟内存,在所有进程之间共享:
____________________________________________________________|___________________________________________________________
| | | |
ff00000000000000 | -64 PB | ff0fffffffffffff | 4 PB | ... 防护孔,也保留用于管理程序
ff10000000000000 | -60 PB | ff10ffffffffffff | 0.25 PB | LDT remap for PTI
ff11000000000000 | -59.75 PB | ff90ffffffffffff | 32 PB | 直接映射所有物理内存 (page_offset_base)
ff91000000000000 | -27.75 PB | ff9fffffffffffff | 3.75 PB | ... 未使用
ffa0000000000000 | -24 PB | ffd1ffffffffffff | 12.5 PB | vmalloc/ioremap 空间 (vmalloc_base)
ffd2000000000000 | -11.5 PB | ffd3ffffffffffff | 0.5 PB | ... 未使用
ffd4000000000000 | -11 PB | ffd5ffffffffffff | 0.5 PB | 虚拟内存映射 (vmemmap_base)
ffd6000000000000 | -10.5 PB | ffdeffffffffffff | 2.25 PB | ... 未使用
ffdf000000000000 | -8.25 PB | fffffbffffffffff | ~8 PB | KASAN 影子内存
__________________|____________|__________________|_________|____________________________________________________________
|
| 从现在开始,它的布局和47位的一模一样:
____________________________________________________________|____________________________________________________________
| | | |
fffffc0000000000 | -4 TB | fffffdffffffffff | 2 TB | ... 未使用
| | | | vaddr_end for KASLR
fffffe0000000000 | -2 TB | fffffe7fffffffff | 0.5 TB | cpu_entry_area 映射
fffffe8000000000 | -1.5 TB | fffffeffffffffff | 0.5 TB | ... 未使用
ffffff0000000000 | -1 TB | ffffff7fffffffff | 0.5 TB | %esp 固定栈
ffffff8000000000 | -512 GB | ffffffeeffffffff | 444 GB | ... 未使用
ffffffef00000000 | -68 GB | fffffffeffffffff | 64 GB | EFI region mapping space
ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | ... 未使用
ffffffff80000000 | -2 GB | ffffffff9fffffff | 512 MB | 内核文本映射,映射到物理地址0
ffffffff80000000 |-2048 MB | | |
ffffffffa0000000 |-1536 MB | fffffffffeffffff | 1520 MB | 模块映射空间
ffffffffff000000 | -16 MB | | |
FIXADDR_START | ~-11 MB | ffffffffff5fffff | ~0.5 MB | 内核-内部定位图范围,可变大小和偏移量
ffffffffff600000 | -10 MB | ffffffffff600fff | 4 kB | 旧版vsyscall ABI
ffffffffffe00000 | -2 MB | ffffffffffffffff | 2 MB | ... 未使用
__________________|____________|__________________|_________|___________________________________________________________
体系结构定义一个64位的虚拟地址。实现可以支持更少的。目前支持的是48位和57位虚拟地址。从第63位到最高有效位的实现都是符号扩展。如果您将用户空间和内核地址解释为无符号,这将导致它们之间出现漏洞。
直接映射覆盖了系统中直到最高内存地址的所有内存(这意味着在某些情况下它还可以包括 PCI 内存洞)。
vmalloc
空间使用 page fault
处理程序延迟地同步到进程的不同 PML4/PML5
页面,并且使用 init_top_pgt
作为引用。
我们将 EFI
运行时服务映射到一个64Gb
的大型虚拟内存窗口中的efi_pgd
PGD
中(这个大小是任意的,如果需要可以在以后提高)。映射不是任何其他内核PGD
的一部分,只在EFI
运行时调用期间可用。
注意,如果启用 CONFIG_RANDOMIZE_MEMORY
,则所有物理内存、vmalloc/ioremap
空间和虚拟内存映射的直接映射都是随机的。它们的顺序被保留,但是它们的基数在启动时会被提前抵消。
在更改这里的任何内容时,要非常小心对付KASLR
。的KASLR
地址范围不能重叠,除了KASAN
影子区域,这是正确的,因为KASAN
禁用 KASLR
。
对于4级和5级布局,最后2MB
洞中的 STACKLEAK_POISON
值: ffffffffffff4111
以下图表是我试图展示页面表在各种体系结构上的排列方式。每个图表都显示基本页面大小的布局以及大页大小的布局。
不同架构的页表结构
启用 PAE 的 i386
x86_64
powerpc with 4k base pages
powerpc with 64k base pages
安利一门Python超级好课!
扫码下单输优惠码【csdnfxzs】再减5元,比官网还便宜!