子 issue #5:内存管理与 TLB
描述
实现 LoongArch64 的页表管理和 TLB 操作,使内核能建立虚拟地址映射、创建用户态地址空间。
依赖
需要实现的文件
| 文件 |
说明 |
kernel/src/arch/loongarch64/paging.rs |
PageTableImpl 完整实现(实现 PageTable + PageTableExt trait)、PageEntry(实现 Entry trait) |
kernel/src/arch/loongarch64/memory.rs |
init()(物理内存探测与初始化)、set_page_table()(地址空间切换)、get_page_fault_addr()
|
kernel/src/arch/loongarch64/tlb.rs(可选) |
TLB 操作封装:重填、无效化、查询 |
关键技术点
LoongArch 页表格式
-
多级页表:通常配置为 4 级(PGD→PUD→PMD→PTE),也可 3 级
-
页大小:支持 4KB/16KB/64KB 等,建议使用 4KB 以与 riscv 保持一致
-
页表项格式(64 位):
| 位域 |
名称 |
说明 |
| [0] |
V |
有效位 |
| [1] |
D |
脏位 |
| [3:2] |
PLV |
特权等级(0=内核, 3=用户) |
| [5:4] |
MAT |
存储访问类型(0=强序非缓存, 1=一致可缓存) |
| [6] |
G |
全局位 |
| [7] |
P |
物理页存在位(用于 swap) |
| [8] |
W |
可写位 |
| [11] |
NR |
不可读位 |
| [12] |
NX |
不可执行位 |
| [13] |
RPLV |
限制性特权等级 |
| [63:12] |
PPN |
物理页号 |
TLB 管理(重点与难点)
-
LoongArch 使用软件管理 TLB,与 RISC-V 的硬件页表遍历不同
- TLB miss 触发
TLBR(0x3F) 异常,由内核软件负责查页表并填写 TLB
- 关键 TLB 操作指令:
-
TLBSRCH:搜索 TLB 条目
-
TLBRD:读 TLB 条目
-
TLBWR:写 TLB 条目(覆盖 TLBSRCH 命中的条目)
-
TLBFILL:随机写入 TLB 条目
-
INVTLB op, rj, rk:无效化 TLB(op 控制无效化范围)
- TLB 重填入口独立配置:
CSR.TLBRENTRY
关键 CSR 寄存器
| CSR |
说明 |
CSR.PGDL |
低半地址空间(用户态)页全局目录基址 |
CSR.PGDH |
高半地址空间(内核态)页全局目录基址 |
CSR.PWCL |
页表遍历配置低位(各级页表的位宽和起始位) |
CSR.PWCH |
页表遍历配置高位 |
CSR.STLBPS |
STLB 页大小(决定 TLB 条目对应的页面大小) |
CSR.TLBRENTRY |
TLB 重填异常入口地址 |
CSR.TLBREHI / CSR.TLBRELO0 / CSR.TLBRELO1
|
TLB 重填用临时寄存器 |
CSR.BADV |
缺页异常的错误虚拟地址 |
CSR.ASID |
地址空间标识符(进程切换时更换以减少 TLB flush) |
与 rcore-memory crate 对接
-
PageTableImpl 需实现 PageTable trait:map, unmap, get_entry, get_page_slice_mut, flush_cache_copy_user
-
PageTableImpl 需实现 PageTableExt trait:new_bare, map_kernel, token, set_token, active_token, flush_tlb
-
PageEntry 需实现 Entry trait 的所有方法(约 20+ 方法映射到 LoongArch PTE 格式)
DMW 与页表的关系
- 内核使用 DMW(直接映射窗口)进行固定映射,无需通过页表
- 用户地址空间通过 TLB + 页表映射
-
set_page_table() 实际设置 CSR.PGDL(用户地址空间的页表基址)
实现建议
- 先实现 DMW 配置(#3 (closed) 已部分完成),确保内核地址空间正常访问
- 再实现页表创建和映射(PageTableImpl)
- 最后实现 TLB 重填异常处理程序,接入 #4 (closed) 的异常分发框架
- 可以先用简单的 flush-all 策略(
INVTLB 0x0, $zero, $zero),后续优化为 ASID-based
完成标准
- 内核能创建用户态页表并映射页面
- TLB 重填异常能正确处理(用户态访存不 panic)
-
set_page_table() 能切换地址空间
- 缺页异常能正确报告故障地址(
get_page_fault_addr() 返回 CSR.BADV)
父任务:#1