本教程内容整理自 王旭凯 - RV58: RISC-V 16KB原生页面的探索-20250910 的演讲视频,属于 PLCT 实验室内部报告,仅供技术交流使用。本文在原始报告基础上进行了结构化整理,旨在为希望深入了解 RISC-V 内核底层原理和性能优化的开发者提供一份参考指南。报告详细探讨了在 QEMU、OpenSBI 和 Linux 内核上实现原生 16KB 页面的技术细节与步骤,并分享了相关的性能测试结果。
如有疏漏或错误之处,欢迎批评指正,共同完善。如需转载或引用本文内容,请注明出处,尊重原作者的劳动成果。
项目背景与目标
- 背景:RISC-V 架构因其开放性和灵活性吸引了众多开发者。然而,其原生只支持 4KB 的页面,这限制了性能优化的空间,促使社区探索对更大页面的支持
- 现有方案的不足:此前,字节跳动的开发者曾通过软件方式,将 16 个 4KB 的页面合并以支持 64KB 的大页面 。尽管这种方式可以实现功能,但会带来额外的性能开销,无法达到理想的性能预期
- 项目目标:实现一个真正的原生 16KB 页面支持方案(SV58),以获得更优的性能表现
- 项目地址: GitHub - linux-develop/riscv-mkkernel: Support for riscv 16kb page size(opensbi, qemu, linux,buildroot/busybox)
第一步:理论设计(SV58)
- 修改 SATP 寄存器:在 RISC-V 的 SATP 寄存器中,
mode字段定义了分页模式。本项目新增了一个value等于 12 的值来代表 SV58,即四级 16KB 页表 - 设计虚拟地址和物理地址结构:假设页表项(PTE)大小不变为 8 字节,16KB 的页面可以容纳 2048 个页表项,页号长度为 11 位 。最终设计出四级页表结构,每级页号长度均为 11 位,页内位移为 14 位
第二步:技术实现与调整
1. 修改 QEMU 平台
- 扩展 QEMU 的 RISC-V 架构支持:
- 新增 SV58 模式识别
- 支持四级页表结构
- 页号长度调整为 11 位
- 页表项大小保持为 8 字节
2. 修改 OpenSBI 与 Linux 内核
OpenSBI 调整
- 修改
FW_JUMP等跳转逻辑,确保跳转地址对齐至 16KB 或更高(如 32MB)
Linux 内核适配
- 页表初始化:修改启动流程中的页表构建逻辑,支持 SV58 四级页表
- 地址对齐检查:更新对齐函数,确保地址按 16KB 对齐
- 宏定义调整:修改
PAGE_OFFSET、KERNEL_START等宏,适配新页面大小 - ELF 加载逻辑:确保段加载地址与页大小一致
3. 软件层面调整
- 编译 BusyBox、Buildroot 等工具时:
- 修改链接脚本,设置段对齐为 16KB
- 确保生成的程序在 16KB 页面上能正确运行
第三步:性能测试与分析
- 多进程性能测试(使用
perf)
- 关注指标:TLB Miss、Page Fault 等
- 结果:在 CPU 密集型任务中,16KB 页面的 TLB Miss 显著减少,性能提升明显
- 内存读写测试(使用
memtest)
- 顺序读写场景下,16KB 页面性能接近理论上的 4 倍提升
- 文件 I/O 测试(使用 iozone)
- 在随机写和缓存复用场景下,16KB 页面吞吐量显著优于 4KB 页面


