rCore
教程第三版第四章(#1)介绍了 rCore
内核地址空间的布局:
依此设计,内核的四个全局逻辑段 .text/.rodata/.data/.bss
恒等映射到物理地址,其他部分也按确定的方式分布。这样做的好处有:
-
结构清晰
内核常驻部分直接占用的物理地址空间、内核为支持用户进程额外需要的内核栈空间和供用户进程自由使用的物理页帧空间在内核地址空间中的位置和大小都是固定的。
-
虚拟空间可用范围大
内核和每个用户进程都能使用除一个 4KiB 的跳板页以外完整的
512GiB - 4KiB
Sv39 虚拟地址空间。内核恒等映射的物理地址在虚拟地址空间中也是复用的。 -
启动平滑
内核在启用虚拟内存前后访问全局逻辑段的方式不变。因此在
init
应用初始化之前的任何时候启动虚拟内存都是一样的。 -
内核与用户进程全隔离
内核空间在用户态看来完全不存在,因此即使硬件存在旁路漏洞也无法从用户态窥探内核内存布局。#3 介绍了隔离带来的安全性好处。
然而,隔离的内核页表也带来一个重大的缺点,就是每次陷入内核都需要切换整个页表,性能比较差。因此,zCore
采用不隔离的内核页表,即用户进程的页表中包含整个内核页表的映射,通过页表项上的标志位保护访问。这样陷入内核时自然可以访问内核的地址空间,不需要刷新页表,具有更好的性能。这个设计来源于 rCore
教程第二版,#2 介绍了细节。
zCore
在 riscv64 架构 + Sv39 方案下采取的具体措施是将内核的物理地址映射到偏移 0xffff_ffff_0000_0000 (根据具体硬件,可能调整)的虚拟地址,或者说将通常程序加载的位置映射到虚地址空间的最后两个 1GiB 巨页。内核需要的空间本来就不大,这样设计不会导致什么问题。应用程序可以知道内核的内存布局,只靠页表标志位实现访问保护。
-
本节介绍了全隔离的内核页表设计。
-
本节介绍了不隔离的内核页表设计。
-
本词条介绍了用于防止旁路攻击的内核页表隔离技术。