章节摘要:本章跟着一条线走——追踪一次"访问了不该访问的地址"从发起到被拦截、再到被翻译、最终在多核间同步可见性的完整旅程。页表、物理内存保护、一致性模型三套机制在这条线上依次接手,读完你会拥有一张完整的内存子系统作战地图。
让故事从一个 bug 开始:某多核板的驱动在压力测试中偶发数据错乱,崩溃现场读数显示程序访问了一个看起来完全合法的地址。这个 bug 的完整诊断要穿过内存子系统的三层防线——第一层判断"这个地址是谁想碰、有没有资格"(物理内存保护 PMP),第二层负责"程序眼里的地址与现实地址如何对上"(页表翻译),第三层裁决"多个 hart 同时看到的数据谁说了算"(一致性模型与内存屏障)。本章三节就是这三层,主线案例的答案要到第三节才揭晓:那不是硬件缺陷,而是一处缺失的内存屏障。
这张图值得反复回看:任何一次访存都要依次穿过翻译、保护、缓存、一致性四道关卡,每道关卡都可能改变请求的命运。排错时按图逐层排查,比漫无目的地看汇编高效得多。
第一站 4.1 节拆 Sv39 页表。四十八位虚拟地址、三级页表、每页四 KiB 的标准方案逐位手解:页表项里九个标志位各管什么、两级大页如何省表、地址翻译缓存如何加速。这节还是页错误家族的户口本——上一章陷入清单里编号十二到十五的常客,源头全在这里。
第二站 4.2 节讲物理内存保护。PMP 是机器特权级手中的物理地址关卡,条款数量有限但匹配模式灵活,固件用它划出安全区、把机器级私有内存从监督级的视野里挡掉。这节还有嵌入式读者的一个彩蛋:没有 MMU 的微控制器上,PMP 就是唯一的内存权限管理者。
第三站 4.3 节上升到多核视角。RISC-V 的弱内存模型允许硬件自由重排访存顺序,单核语义不受影响,但多核共享数据时必须靠 fence 与原子原语钉住顺序。开头那个压测 bug 的谜底在此揭晓,顺带把锁实现的完整正确性论证走一遍。

本章的认知转折在第三节:多数工程师的直觉是"写入即全局可见",这在单核世界成立,在多核世界只是幻觉。弱内存模型把"顺序"从硬件承诺降级为软件请求——你不明确要求顺序,硬件就有权为性能重排它。这个转折改变排错的世界观:数据错乱类 bug 的第一嫌疑人从"内存坏了"变成"屏障漏了"。本章的落点是一张三层安检图:翻译层决定地址的真假,保护层决定权限的有无,一致性层决定顺序的存亡——三层各答一问,内存问题就有了系统性的排查路径。
内存地基铺完,单核程序在隔离与保护下安全运行,多核程序在屏障与原子原语守护下共享数据。下一章我们进入扩展的深水区:当负载是成批数据而非单个变量,标量指令的低效催生了向量扩展——那是一套足以改变编程模型的全新指令家族。