为什么 x86_64 内核的内存布局中有这么大的虚拟地址
why there are such large virtual addresses in a x86_64 kernel's memory layout
内核的 Documentation/x86/x86_64/mm.txt 说:
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
所以我假设地址映射不应大于该区域中的实际物理 DRAM 大小。但是在具有 16GB DRAM 和内核 v4.2.8 的 x86_64 PC 上,我从 /sys/kernel/debug/kernel_page_tables:
得到了这个结果
---[ Low Kernel Mapping ]---
......
0xffff88008b3ff000-0xffff88008b400000 4K RW GLB NX pte
0xffff88008b400000-0xffff8800c0000000 844M pmd
0xffff8800c0000000-0xffff880100000000 1G pud
0xffff880100000000-0xffff880400000000 12G RW PSE GLB NX pud
0xffff880400000000-0xffff88043dc00000 988M RW PSE GLB NX pmd
0xffff88043dc00000-0xffff88043dc25000 148K RW GLB NX pte
0xffff88043dc25000-0xffff88043dc27000 8K ro GLB NX pte
.......
0xffff88045c200000-0xffff88046f000000 302M RW PSE GLB NX pmd
0xffff88046f000000-0xffff880480000000 272M pmd
0xffff880480000000-0xffff888000000000 494G pud
0xffff888000000000-0xffffc90000000000 66048G pgd
你看到有虚拟地址为 0xffff88043dc00000 的页面条目,使用
virt_to_phys() 在这样的虚拟地址上将得到 0x43dc00000,这是
显然是非法的,因为它大于实际的 DRAM 大小(16GB 只是
0x400000000).
这些大虚拟地址的规则是什么?我怎样才能获得正确的物理地址?
非常感谢!
您的 PC 不仅有 DRAM,还有 ROM(现在是闪存)和 I/O 内存。为了向后兼容,其中的一部分必须映射到 20 位和 32 位地址空间,因此 RAM 的最后一部分结束于 0x400000000 以上的某个地址。
物理地址不仅仅用于 RAM。连接到机器上的不同设备也有一些物理地址。处理器只需将物理地址放在地址总线上,一个或一个设备就会响应它。
所以在你的情况下,这些物理地址可能是一些 IO 设备,如 ROM(CD ROM 等)。
此外,RAM 的物理地址也可以大于 16GB。只看放在哪里。
内核的 Documentation/x86/x86_64/mm.txt 说:
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
所以我假设地址映射不应大于该区域中的实际物理 DRAM 大小。但是在具有 16GB DRAM 和内核 v4.2.8 的 x86_64 PC 上,我从 /sys/kernel/debug/kernel_page_tables:
得到了这个结果---[ Low Kernel Mapping ]---
......
0xffff88008b3ff000-0xffff88008b400000 4K RW GLB NX pte
0xffff88008b400000-0xffff8800c0000000 844M pmd
0xffff8800c0000000-0xffff880100000000 1G pud
0xffff880100000000-0xffff880400000000 12G RW PSE GLB NX pud
0xffff880400000000-0xffff88043dc00000 988M RW PSE GLB NX pmd
0xffff88043dc00000-0xffff88043dc25000 148K RW GLB NX pte
0xffff88043dc25000-0xffff88043dc27000 8K ro GLB NX pte
.......
0xffff88045c200000-0xffff88046f000000 302M RW PSE GLB NX pmd
0xffff88046f000000-0xffff880480000000 272M pmd
0xffff880480000000-0xffff888000000000 494G pud
0xffff888000000000-0xffffc90000000000 66048G pgd
你看到有虚拟地址为 0xffff88043dc00000 的页面条目,使用 virt_to_phys() 在这样的虚拟地址上将得到 0x43dc00000,这是 显然是非法的,因为它大于实际的 DRAM 大小(16GB 只是 0x400000000).
这些大虚拟地址的规则是什么?我怎样才能获得正确的物理地址?
非常感谢!
您的 PC 不仅有 DRAM,还有 ROM(现在是闪存)和 I/O 内存。为了向后兼容,其中的一部分必须映射到 20 位和 32 位地址空间,因此 RAM 的最后一部分结束于 0x400000000 以上的某个地址。
物理地址不仅仅用于 RAM。连接到机器上的不同设备也有一些物理地址。处理器只需将物理地址放在地址总线上,一个或一个设备就会响应它。
所以在你的情况下,这些物理地址可能是一些 IO 设备,如 ROM(CD ROM 等)。
此外,RAM 的物理地址也可以大于 16GB。只看放在哪里。