rCore-Tutorial-Book-v3
rCore-Tutorial-Book-v3 copied to clipboard
rCore-Tutorial-Book-v3/chapter4/3sv39-implementation-1
实现 SV39 多级页表机制(上) — rCore-Tutorial-Book-v3 0.1 文档
https://rcore-os.github.io/rCore-Tutorial-Book-v3/chapter4/3sv39-implementation-1.html
在《分析 SV39 多级页表的内存占用》有個疑問,強兩個假設有點晦澀,假定一種不是太普遍地址空間,反而第三種假設覺得會更普遍而且計算內存佔用方式也比較易懂,不太明白前兩種假設目的何在?
在《分析 SV39 多级页表的内存占用》有個疑問,強兩個假設有點晦澀,假定一種不是太普遍地址空間,反而第三種假設覺得會更普遍而且計算內存佔用方式也比較易懂,不太明白前兩種假設目的何在?
感谢反馈!前两种估算方式更加精确,事实上它们是从每次映射一个页面的角度出发的,比较自然。第三种估算方式思想不同,它实际上是单独考虑每个节点是否有必要存在。出于介绍的完整性就将两种思想都进行了介绍。另外,后面在映射 MMIO 的时候会映射很多个间隙很大的单个虚拟页面,确实观察到出现了比较大(接近前两种估算方式)的开销,因此前两种估算方式也是有现实意义的。但是可能确实应该将第三种估算方式放在更前面,因为它确实比较通用。
能不能大概说一下这个的意思,没有太看懂
impl From
懂了,保留56/39位。。。
A(Accessed):处理器记录自从页表项上的这一位被清零之后,页表项的对应虚拟页面是否被访问过;
D(Dirty):处理器记录自从页表项上的这一位被清零之后,页表项的对应虚拟页表是否被修改过。
应该都是对应的“页框”,而不是“虚拟页面”
@lindyang 根据RV特权级规范的原文:"Each leaf PTE contains an accessed (A) and dirty (D) bit. The A bit indicates the virtual page has been read, written, or fetched from since the last time the A bit was cleared. The D bit indicates the virtual page has been written since the last time the D bit was cleared." 这里应该是虚拟页面而非页框。
没看懂“对于不对齐的情况,物理地址不能通过 From/Into 转换为物理页号,而是需要通过它自己的 floor 或 ceil 方法来进行下取整或上取整的转换”这段的实现,不太明白floor的实现为什么是直接/page size,和ceil函数的实现是(self.0 - 1 + PAGE_SIZE) / PAGE_SIZE),有人能解释下嘛
请问PTE的RSW位是做什么的
@wei-huan spec中提到RSW是留给S特权级软件(也就是内核)自行决定如何使用的,比如可以用它实现一些页面置换算法。
@kidcats
没看懂“对于不对齐的情况,物理地址不能通过 From/Into 转换为物理页号,而是需要通过它自己的 floor 或 ceil 方法来进行下取整或上取整的转换”这段的实现,不太明白floor的实现为什么是直接/page size,和ceil函数的实现是(self.0 - 1 + PAGE_SIZE) / PAGE_SIZE),有人能解释下嘛
"单个页面的大小设置为4KiB,每个虚拟页面和物理页帧都对齐到这个页面大小,也就是说虚拟/物理地址区间[0.4KiB)为第0个虚拟页面/物理页帧,而[4KiB,8KiB)为第1个,以此类推."
@kidcats
没看懂“对于不对齐的情况,物理地址不能通过 From/Into 转换为物理页号,而是需要通过它自己的 floor 或 ceil 方法来进行下取整或上取整的转换”这段的实现,不太明白floor的实现为什么是直接/page size,和ceil函数的实现是(self.0 - 1 + PAGE_SIZE) / PAGE_SIZE),有人能解释下嘛
"单个页面的大小设置为4KiB,每个虚拟页面和物理页帧都对齐到这个页面大小,也就是说虚拟/物理地址区间[0.4KiB)为第0个虚拟页面/物理页帧,而[4KiB,8KiB)为第1个,以此类推." 明白了,感谢
页表项的U
位的描述不太完善, 在Risc-v
的特权级文档中U
位还有其他的补充描述,当sstatus
寄存器中的SUM
位置1,S
特权级可以访问U
位为1
的页,但是S
特权级的程序常运行在SUM
位清空的条件下,如果S
特权级直接访问会出现page fault
.
我就是遇到这个问题卡了两天。
@yfblock 因为目前的实现是内核和应用使用两个不同的页表,所以大概不会有在内核中直接通过虚拟地址访问应用数据的情况啊。除非你的实现是每个进程一个页表,包括内核态和用户态两部分,这个时候才需要考虑设置SUM位。
impl From
VirtAddr::from(TRAMPOLINE) 不就 变成0x7ffffff000的虚拟地址了,为什么会映射对了。
@Opadc 虚拟地址是64位,但是只有第63-39位均与第38位相同才是一个合法的虚拟地址,否则会直接触发page fault而不会进入到查页表的流程。VirtAddr
是假定传入的虚拟地址能够通过这个判断,那就可以将第63-39位省略仅保留低39位,它们已足够用于查询或设置页表项了。注意保留39位之后虽然变成了一个较低的地址,但其实是对应到整个64位地址空间最高的256GB的。
@wyfcyx 我明白了,0xFFFFFFFFFFFFF000 和 0x7ffffff000 查页表是等价的,非常感谢!
所以self.0是什么语法 没找到……
所以self.0是什么语法 没找到……
结构体PhysAddr
是一个元组结构体,self.0
就是元组中第一个元素。
例如:
struct A(i32, i32, i32)
那么 self.1
和 self.2
就对应第二个和第三个int值。
typo: 在 [注解] 分析 SV39 多级页表的内存占用 中,“……而后者(对应根页表,第三极页表)……”中“第三极”应为“第三级”。
默认情况下 MMU 未被使能
使能 二字是不是打错了?
默认情况下 MMU 未被使能
使能 二字是不是打错了?
@bluetianx 并没有打错。这里的“使能”和“启用”是一个意思。
@kidcats
没看懂“对于不对齐的情况,物理地址不能通过 From/Into 转换为物理页号,而是需要通过它自己的 floor 或 ceil 方法来进行下取整或上取整的转换”这段的实现,不太明白floor的实现为什么是直接/page size,和ceil函数的实现是(self.0 - 1 + PAGE_SIZE) / PAGE_SIZE),有人能解释下嘛
"单个页面的大小设置为4KiB,每个虚拟页面和物理页帧都对齐到这个页面大小,也就是说虚拟/物理地址区间[0.4KiB)为第0个虚拟页面/物理页帧,而[4KiB,8KiB)为第1个,以此类推."
原来如此,类似计算数组下标的意思。
这是因为,括号中的两项分别对应为了映射这段连续区间所需要新分配的最深层和次深层节点的数目,前者(对应第二级页表)每连续映射 2MiB 才会新分配一个 4Kib 的第一级页表,而后者(对应根页表,第三级页表)每连续映射 1GiB 才会新分配一个 4Kib 的第二级页表
请问,这里 4Kib
是不是打错了,是 4KiB
(页表512个页表项,每个页表项大小8B)
@CelestialMelody 确实打错了,多谢勘误。
关于《分析 SV39 多级页表的内存占用》,理论上的第一种上限:
每映射一个 4KiB 的虚拟页面,需要初始就有一个页表根节点,因为还需其它两级页表节点,故最多还需要新分配两个物理页帧来保存新的节点。
没有太理解:
- 为什么“最多还需要新分配 两个 物理页帧来保存新的节点”?
- 没有理解这里 'S / 4KiB' 的含义。这里的计算看起来就像是:每连续映射 4KB 新分配 2 个 4KB 的页表。
感觉一些概念的表述比较绕:
在 SV39 中:
- 如果使用了一级页索引就停下来,则它可以涵盖虚拟页号的高 9 位为某一固定值的所有虚拟地址,对应于一个 1GiB 的大页;
- 如果使用了二级页索引就停下来,则它可以涵盖虚拟页号的高 18 位为某一固定值的所有虚拟地址,对应于一个 2MiB 的大页;
- 如果使用了所有三级页索引才停下来,它可以涵盖虚拟页号的高 27 位为某一个固定值的所有虚拟地址,自然也就对应于一个大小为 4KiB 的虚拟页面。
这里的 一级索引 在使用上似乎用于映射 根页表(第三级页表)的页表项(不知道有没有理解出错)
括号中的两项分别对应为了映射这段连续区间所需要新分配的最深层和次深层节点的数目:
- 前者(对应 第二级页表)每连续映射 2MB 才会新分配一个 4KB 的第一级页表;
- 后者(对应 根页表,第三级页表)每连续映射 1GB 才会新分配一个 4KB 的第二级页表。
我的问题是:
- 是否第三级页表映射地址范围为 512 GB(第二级页表范围为 1 GB,第三级页表为 2KB)?
- 根页表(第三级页表)包含的是虚拟页号的高 9 位(一级索引)映射的页表项?
@CelestialMelody 目前姑且将根节点称为一级页表,于是从上到下应该是一级到二级再到三级,所有相关的表述也做了调整,应该能够做到一致了。不过,习惯上到底应该把根节点称为一级页表还是三级页表,这一点还需要跟老师讨论一下。
@CelestialMelody 多级页表内存占用那里目前的介绍也应该更加清晰了,之前的表述确实有些问题。
提问:sv39中每一级的page directory只有1<<9个PTE,但是每一个物理页的大小是1<<12;如果我理解正确的话,每次我们分配一个新的物理页时,我们只用了前1/8的内存来放置新的PTE,在剩下的7/8的page directory中都被浪费了? 还是说我的理解错误了