问题一:cpu 怎么知道自己用的是那种分页方式呢? 靠MODE字段
问题二:PNN怎么设计的呢?
问题三:多个虚拟地址对应一个物理地址怎么办呢?

satp(Supervisor Address Translation and Protection)寄存器用于管理地址转换和保护机制。satp 寄存器的具体格式取决于 RISC-V 的地址空间宽度(如 32 位或 64 位)。

image.png

64位的satp 寄存器的格式:
截屏2024-07-07 09.09.41.png

MODE 字段用于指定地址转换模式。
MODE 字段位于 satp 寄存器的高 4 位(即位 60 到 63)。
MODE 字段的值决定了地址转换模式,如 Sv32、Sv39、Sv48 等。
截屏2024-07-07 09.11.58.png

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

截屏2024-07-07 12.27.12.png

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 也确保了它们的地址映射不会混淆。


putao
5 声望0 粉丝

推动世界向前发展,改善民生。