0%

linux riscv mmu 地址翻译调试

sv39

satp: 0x8000000000087fff
va: 0x80000fac

求 pa

sv39
38…30 9bit
29…21 9bit
20…12 9bit
11…0 12bit

64bit 中一个页表项占 64bit,一个 double word

  • satp.PPN 给出了一级页表的基址, VA[38:30]给出了一级页号, 因此处理器会读取位于地址(satp.PPN × 4096 + VA[38:30] × 8)的页目录项 (此处的 8 为 8字节,即一个页表项占 64bit)
  • 该 PTE 包含二级页表的基址, VA[29:21]给出了二级页号, 因此处理器读取位于地址(PTE.PPN × 4096 + VA[29:21] × 8)的页目录项
  • 该 PTE 包含了三级页表的基址, VA[20:12] 给出了三级页号, 处理器读取位于地址(PTE.PPN × 4096 + VA[20:12] × 8)的页目录项
  • 该页表项的 PTE. PPN 就是物理地址对应的 PPN * 4096 + offset 得到物理地址

va: 0x80000fac

1
2
3
4
5
bit:   1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 
index: 31| 30| 29| 28| 27| 26| 25| 24| 23| 22| 21| 20| 19| 18| 17| 16|
----------------------------------------------------------------------
bit: 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 |
index: 15| 14| 13| 12| 11| 10| 09| 08| 07| 06| 05| 04| 03| 02| 01| 00|

satp.ppn = 0x87fff << 12 = 0x87fff000

  • satp.PPN × 4096 + VA[38:30] × 8 = 0x87fff000+0b10*8 = 0x87fff010 @地址存放的值为 (0x21ffe801)
  • PTE.PPN × 4096 + VA[29:21] × 8 = 0x21ffe801>>10<<12 + 0*8 = 0x87ffa000 @地址存放的值为 (0x21ffe401)
  • PTE.PPN × 4096 + VA[20:12] × 8 = 0x21ffe401>>10<<12 + 0*8 = 0x87ff9000 @地址存放的值为 (0x2000004b)
  • PPN x 4096 + offset = 0x2000004b>>10<<12 + 0xfac = 0x80000fac

最终取得 pa 为 0x80000fac