RISC-V Linux支持sv32、sv39、sv48等虚拟地址格式,分别代表32为虚拟地址、38位虚拟地址和48位虚拟地址。RISC-VLinux默认也是使用sv39格式,sv39的虚拟地址、物理地址、PTE格式如下:
虚拟地址格式:
物理地址格式:
PTE格式:
虚拟地址使用39位表示,其中低12位代表pageoffset,高位划分为了三部分:VPN[0]、VPN[1]和VPN[2],分别代表虚拟地址VA在PTE、PMD和PGD中的索引。
物理地址使用56位表示,低12位代表page offset,高位是物理页PPN[0]、PPN[1]和PPN[2]
PTE保存了物理页PPN[0]、PPN[1]和PPN[2],和物理地址中的PPN相对应;PTE的低10位代表物理地址的访问权限,当RWX全为0时,则代表该PTE存储的地址是下一级页表的物理地址,否则代表当前页表是最后一级页表。
再看看sv39 的页表格式,sv39使用的是三级页表,PGD、PMD和PTE,每一个级页表使用9bit表示,即每一级页表都有512个页表项。
在代码中,创建一个有512个元素的数组即代表一个页表。一个PTE有512个页表项,每一个页表项占用8字节,5128=4096字节,所以一个PTE代表4K。一个PMD也是512个页表项,每一项可代表一个PTE,5124 K=2M,所以一个PMD就代表2M。以此类推,一个PGD代表512 * 2M=1G。
重要结论:PGD代表1G、PMD代表2M、PTE代表4K。sv39默认的页大小是4K。
三级页表虚拟地址转为物理地址过程示意图:
sv39三级页表虚拟地址转为物理地址过程:
MMU通过satp寄存器得到PGD的物理地址,结合PGD index(即VPN[2])找到PMD;找到PMD后,再结合PMDindex(即VPN[1])找到PTE,然后结合PTE index(即VPN[0])得到VA在PTE索引中的值,从而得到物理地址。
最后在PTE中取出PPN[2]、PPN[1]和PPN[0],再和虚拟地址的低12位offset相加,得到最终的物理地址。
全部0条评论
快来发表一下你的评论吧 !