我目前正在研究 Linux 内核对虚拟地址空间的使用。我了解拥有这些的好处、页表遍历在 x86 中如何工作以及虚拟的布局地址空间。
这是我不明白的部分:在我的一次演讲中,有人解释说Linux内核在内核空间中使用“身份映射”。含义:在内核空间中,您可以通过减去一个常量将任何虚拟地址转换为其物理地址。
这个数字通常被称为页偏移量并且根据 64 位与 32 位、4 层与 5 层地址转换而有所不同,也可能是配置好的。作为一项安全措施,kASLR 在每次启动时都会随机增加 PAGE_OFFSET。
我在很多地方都看到过这个解释,但大多数都有点旧了:
https://stackoverflow.com/a/36640733/15113903
https://stackoverflow.com/questions/24632905/mapping-of-kernel-virtual-address-directly?rq=1
最近的隐含解释是,volatility3 在计算出波动性时似乎依赖于这种恒等映射。内存转储的 kASLR 偏移量。
现在:(为什么)内核虚拟地址空间(仍然)是这样?有性能优势吗?出于某种原因有必要吗?这是早期的一些遗产吗?在不久的将来改变的可能性有多大?
谢谢
答案1
您可以通过减去一个常数将任何虚拟地址转换为其物理地址
不完全的;地址空间内核末端的任何虚拟地址。
某些体系结构(包括 x86)上的 Linux 内核仍然具有物理地址空间到虚拟地址空间的线性映射。有很多优点:
- 减少 TLB 压力(有助于处理大页面映射,内核在可能的情况下将其用于此映射)
- 近乎直接访问物理地址(请记住,使用 MMU,CPU 上运行的代码只能访问虚拟地址)
- 访问未映射的地址(因为它们用于当前进程以外的进程,或者因为它们根本没有映射)
这些都不是硬性要求,有些人希望在某个时候摆脱线性地图,但我不知道是否有人正在积极致力于它。