問題一: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 也確保了它們的地址映射不會混淆。