我已经阅读了 Robert Love 的 Linux Kernel Development 以及其他资料。它到处都提到,在 32 位 x86 系统上,内核拥有虚拟地址空间的顶部 1 GB,其中最多 896 MB 连续映射到物理内存(称为 ZONE_NORMAL),其余部分映射到剩余的 128 MB 空间根据需要,并且可能不连续 (ZONE_HIGHMEM)。
在64位上,消除了没有足够虚拟地址空间的问题。内存映射被描述为,
0xffffffffffffffff +-----------+
| |
| | Kernelspace
| |
0xffff800000000000 +-----------+
| |
| |
| hole |
| |
| |
0x00007fffffffffff +-----------+
| |
| | Userspace
| |
0x0000000000000000 +———————————+
但是,尚不清楚在此映射中需要多少内核空间在物理上是连续的(如 ZONE_NORMAL 中所定义)。以及根据需要映射多少。
64位内核中的ZONE_HIGHMEM总是0吗?既然所有内存都在虚拟地址空间的范围内?
但是内核的固定连续内存(不可分页)也需要很小,因为该物理内存块永远无法供其他用户进程使用。因此,内核需要根据需要使用不需要连续的内存(如 ZONE_HIGHMEM)。这与 64 位内核上的 ZONE_HIGHMEM 为空相冲突。
因此,我对 64 位内核的情况下有多少内核空间是固定物理连续的以及有多少是非连续的感到困惑。
答案1
HIGHMEM
64 位 x86 上没有—CONFIG_HIGHMEM
依赖于取决于X86_32
。
物理内存有两种固定映射在 64 位 x86 上:
ffff888000000000 | -119.5 TB | ffffc87fffffffff | 64 TB | direct mapping of all physical memory (page_offset_base)
以及起始于的区域
ffffffff80000000 | -2 GB | ffffffff9fffffff | 512 MB | kernel text mapping, mapped to physical address 0
(负地址是距地址空间末尾的偏移量)。
据我所知,后者符合你的想法,而且往往很小;查看启动过程中显示的“Memory”行:
Memory: 20144992K/20660008K available (14339K kernel code, 2406K rwdata, 8340K rodata, 2488K init, 5116K bss, 515016K reserved, 0K cma-reserved)
(略低于 30MiB)以及稍后加载的模块锁定的任何内存。