Skip to content

RISC-V 的分页机制

RISC-V 目前有 Sv32, Sv39, Sv48 和 Sv57 四种分页机制,Sv64 目前被保留使用。几种分页机制均采用了多级页表的映射方式。

Sv32

Sv32 下的地址布局如下:

                            +----------+----------+------------+
  Virtual Address           |  VPN[1]  |  VPN[0]  |   offset   |  -----> 32 bits
                            +----------+----------+------------+
                             (10 bits)  (10 bits)    (12 bits)

  Physical Address        +------------+----------+------------+
                          |   PPN[1]   |  PPN[0]  |   offset   |  -----> 34 bits
                          +------------+----------+------------+
                             (12 bits)   (10 bits)    (12 bits)

                    +------------+----------+--+-+-+-+-+-+-+-+-+
  Page Table Entry  |   PPN[1]   |  PPN[0]  |  |D|A|G|U|X|W|R|V|  -----> 32 bits
                    +------------+----------+--+-+-+-+-+-+-+-+-+
                       (12 bits)   (10 bits) |
                                             `- RSW (2 bits)

Sv32 下每一个页表项大小为四字节,每一个页表共有 \(2^{10}\) 个页表项,于是每个页表的大小为 \(2^{15}\) 个比特,即 \(2^{12}\) 字节,也就是 4 KiB。而每个页号对应的页内偏移共有 12 位,也是 4 KiB 的空间,一个页表可以刚好放入一个页内。

在使用虚拟地址时(将 satp 寄存器的 MODE 域设置为对应虚拟内存的选项)时,内存管理单元会首先从 satp 中读取页表根节点的基址,之后根据页表项后的标志位判断是否需要进行二级页表的查找。若不再向下查找,则将虚拟地址中的偏移量作为物理地址偏移量,将尚未访问的级别的页号直接从虚拟地址中获取到物理地址,已经访问的级别则从页表项中获取。整个地址翻译过程的细节可以见 RISC-V Privileged Spec 中的 4.3.2 节。

Sv39, Sv47, Sv57

Sv39 使用 39 位的虚拟地址,每一级页号为 9 位,页表项大小为 64 位,从而保证一个页表可以被保存在一个页内。Sv39 下的物理地址为 56 位,期中 PPN[2] 为 26 位。 Sv48 与 Sv39 类似,但是使用了四级页表,虚拟地址中每一级页号仍然是 9 位,物理地址为 56 位,最高一级 PPN[3] 为 17 位。 Sv57 使用五级页表并且将 PPN[4] 都设置为了 8 位,物理地址仍然为 56 位。

Sv39, Sv48, Sv57 中所有 PPN 位数总和均为 44 位,与 satp 寄存器中的 PPN 保持一致。

Comments