问题一:cpu 怎么知道自己用的是那种分页方式呢? 靠MODE字段
问题二:PNN怎么设计的呢?
问题三:多个虚拟地址对应一个物理地址怎么办呢?
satp(Supervisor Address Translation and Protection)寄存器用于管理地址转换和保护机制。satp 寄存器的具体格式取决于 RISC-V 的地址空间宽度(如 32 位或 64 位)。
64位的satp 寄存器的格式:
MODE 字段用于指定地址转换模式。
MODE 字段位于 satp 寄存器的高 4 位(即位 60 到 63)。
MODE 字段的值决定了地址转换模式,如 Sv32、Sv39、Sv48 等。
mode 怎么用呢?
# 启用 MMU
la a0, page_table_base
call enable_mmu
# 函数:启用 MMU
enable_mmu:
# 设置 satp 寄存器
srli a2, a0, 12 # 将页表基地址右移12位
li t0, 8 # Sv39 模式
slli t0, t0, 60 # 左移60位,放置到 MODE 字段
or a2, a2, t0 # 合并 MODE 和 PPN
csrw satp, a2 # 写入 satp 寄存器
sfence.vma # 刷新 TLB
ret
PPN(Physical Page Number,物理页号)
在 RISC-V 的 satp(Supervisor Address Translation and Protection)寄存器中存储的是页表基地址的物理页号,但具体放的是哪个级别的页表基地址取决于所使用的地址转换模式(如 Sv32、Sv39、Sv48 等)。
一般是一级页面的基地址
严格来讲:PPN 只是一个物理地址编号,不是真正的物理地址。 那么什么是一个真正的地址呢?
物理地址=PPN×页大小
4KB的页大小PPN<<12
2MB的页大小PPN<<21
ASID(地址空间标识符)
通过在地址转换过程中引入一个额外的标识符来确保不同进程的虚拟地址空间不会混淆。
假设有两个进程,进程 A 和进程 B,它们的虚拟地址空间可能有重叠。进程 A 的 ASID 为 1,进程 B 的 ASID 为 2。
进程 A:
虚拟地址 0x1000 映射到物理地址 0x2000,TLB 条目为 (0x1000, 0x2000, ASID=1)。
进程 B:
虚拟地址 0x1000 映射到物理地址 0x3000,TLB 条目为 (0x1000, 0x3000, ASID=2)。
当进程 A 切换到进程 B 时,操作系统会更新 satp 寄存器中的 ASID:
进程 A 运行时,satp.ASID = 1,TLB 查找 (0x1000, ASID=1),命中 (0x1000, 0x2000, ASID=1)。
进程 B 运行时,satp.ASID = 2,TLB 查找 (0x1000, ASID=2),命中 (0x1000, 0x3000, ASID=2)。
这样,即使两个进程的虚拟地址空间有重叠,ASID 也确保了它们的地址映射不会混淆。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。