5.3 MPU、MMU 与虚拟内存支持


文档摘要

5.3 MPU、MMU 与虚拟内存支持 本节摘要:内存保护单元用少量硬件区域给任务划出围栏,是资源受限芯片上性价比最高的隔离手段;内存管理单元提供完整虚拟内存,但实时系统只取其隔离、舍其按需调页。本节讲两者在 RTOS 里的受限用法,以及无保护芯片上的软件兜底。 给本节定一个容易记住的立场:实时系统引入内存管理硬件,买的不是「虚拟内存」这个大件,而是「隔离」这个小件——让一个失控组件的越界访问当场被拦截,而不是踩坏别人后延时爆炸。桌面世界的用法(每进程独立地址空间、按需调页、交换分区)在这里大部分被舍弃,理由在第一章就埋下了:调页意味着毫秒级的不确定延迟,与截止期防守不共戴天。

5.3 MPU、MMU 与虚拟内存支持

本节摘要:内存保护单元用少量硬件区域给任务划出围栏,是资源受限芯片上性价比最高的隔离手段;内存管理单元提供完整虚拟内存,但实时系统只取其隔离、舍其按需调页。本节讲两者在 RTOS 里的受限用法,以及无保护芯片上的软件兜底。

给本节定一个容易记住的立场:实时系统引入内存管理硬件,买的不是「虚拟内存」这个大件,而是「隔离」这个小件——让一个失控组件的越界访问当场被拦截,而不是踩坏别人后延时爆炸。桌面世界的用法(每进程独立地址空间、按需调页、交换分区)在这里大部分被舍弃,理由在第一章就埋下了:调页意味着毫秒级的不确定延迟,与截止期防守不共戴天。

MPU:几条区域的粗粒度围栏

内存保护单元(MPU)的模型极简:处理器内置若干「区域」寄存器(Cortex-M 上典型八个),每个区域声明一段地址范围的起止、访问权限(特权或用户态可否读写、能否执行)与缓存属性。访问发生时硬件逐区域比对,命中禁令立即触发异常。它没有页表、没有地址重映射、没有缺页处理——正因为什么都不做,它也什么都不拖累:权限判断在流水线内完成,对时序的干扰可以忽略。

对 RTOS 的价值在两处。其一,内核自保:把内核关键数据划为特权态可写,应用任务跑在用户态,应用的野指针再也写不进调度器的就绪表——过去这类越界的表现是系统莫名崩,现在是被当场拦截并进入你自己写的错误钩子。其二,任务隔离:每个任务的栈单独成区,任务 A 越界写任务 B 的栈,硬件立即抛异常,故障现场与真凶第一次做到了同帧出现。

MPU 版 RTOS 怎么用

主流内核都提供 MPU 变体。以 FreeRTOS 的 MPU 版为例,任务分「特权」与「受限」两类创建,受限任务只能访问自己被授权的区域:

/* 受限任务:栈单独成区,仅授权其自身栈与指定外设区 */ static const TaskParameters_t xRestrictedTask = { vParserTask, "parser", 256, NULL, PRIVILEGE_BITS_USER_MODE | REGION_STACK_ATTR, &xParserTaskParameters /* 内含 MPU 区域模板 */ }; xTaskCreateRestricted(&xRestrictedTask, NULL);

解析外部报文的任务、运行第三方组件的任务,是受限化的首选对象——它们消费不可信输入,出事概率最高。经验法则是「最小授权」:每个任务只拿到完成职责所需的区域,宁可加区域也不要开特权。Zephyr 的用户态模式、SafeRTOS 的分区配置,思路与命名不同,模型一致。

MMU 与虚拟内存:取隔离、舍调页

带 MMU 的高端芯片(应用处理器、部分工业 SoC)提供完整虚拟内存:进程拥有独立地址空间,页表由内核维护。RTOS 世界的用法有三条纪律。第一条,锁定物理页:所有在线页一经映射即锁定,禁用按需调页与页换出——让缺页中断这个毫秒级不确定性来源在运行期绝迹。QNX 与 seL4 这类以确定性著称的内核都把这条做成默认行为。第二条,映射静态化:地址映射在启动阶段一次配好,运行期不做动态重映射;需要新映射的外设,宁可预映射备用,也不在任务路径上现场建页表。第三条,进程按需启用:微内核架构(第七章的功能安全一节会展开)里,驱动与文件系统作为独立进程各享地址空间,一颗驱动崩溃只损失一个进程;这是 MMU 隔离能力兑现价值的场景,代价是进程间通信的额外开销,值不值取决于失效预算。

一句话总结取舍:虚拟内存的地址翻译与调页机制是实时性的敌人,而它的隔离能力是安全性的朋友——RTOS 的做法是留着朋友、送走敌人的武器

没有 MPU 的芯片:软件兜底

大量低成本芯片既无 MPU 也无 MMU,隔离只能靠软件手段近似。可行的兜底有四样:栈水印检查常态化(3.1 节的三步法),把「踩穿栈」从事后玄学变成有数据的体检项;关键结构加特征字段,读取时校验,被踩时能察觉;把配置与只读数据放进闪存段,物理上杜绝误写;任务栈之间留隔离带(填充区),越界踩中的是填充而不是邻居,配合周期巡检可以定位到肇事任务。这些手段的防护强度当然不及硬件围栏,但成本几乎为零,在任何正式固件里都值得全开。

本节要点回顾

  • 买的是隔离不是虚拟内存:拦截越界的价值在于故障现场与真凶同帧;
  • MPU 区域模型极简,权限判断不影响时序,是受限芯片的最优隔离解;
  • 受限任务按最小授权创建,外部输入消费者优先受限化;
  • MMU 三纪律:锁页、映射静态化、进程按需启用,调页与实时不共戴天;
  • 无 MPU 芯片用软件兜底:水印、特征字段、闪存段、栈隔离带;
  • 隔离强度与失效预算挂钩,第七章的功能安全流程会给出量化标准。

常见问题

问:MPU 区域数量少不够用怎么办? 优先级排序:内核保护区、每个受限任务的栈区、外设关键区。不够用时合并同类(相邻任务栈连续布局成一大区)或减少受限任务数量——MPU 预算本身就是一层架构约束,逼你认真挑选「谁值得隔离」。

问:开了 MPU 之后性能会掉吗? 权限检查在流水线内完成,常规访问几乎无感;可感知的开销来自受限任务的系统调用路径(跨特权态要多走一趟)。把跨态调用的频率控制在设计期,开销就可预算。

问:怎么验证 MPU 配置真的生效? 故意写坏它:在受限任务里安排一段越界写测试代码(仅测试构建启用),确认触发的是你自己的错误钩子而不是静默破坏。「防线要试爆」是第九章验证原则在内存保护上的应用。

问:锁页内存会不会浪费容量? 会留下一些「预映射但未用」的页,这是用空间换确定性的直接付款。按实际峰值映射加少量余量,可以把账控制在可接受范围;省到按需调页,就把毫秒级黑箱请回来了。

问:没有 MPU 的项目还值得做共享梳理吗? 值得。梳理共享关系、改消息传递这两步与硬件无关,收益是并发关系从混沌变成显式;硬件隔离只是把显式的关系再交给硬件执法。

从裸机习惯到受控并发的迁移

很多团队从裸机直接迁移到带 MPU 的 RTOS,踩的第一道坎是心态而非技术:过去全局变量随便写,现在跨任务共享都要过保护。迁移的路径建议分三步走:第一步先不改代码,把所有全局变量的读写关系梳理成表(谁读、谁写、各在哪个任务);第二步按表把「单写多读」的数据改为消息传递(4.2 节管线),把「多写」的数据收进互斥量保护;第三步把解析外部输入的任务受限化,享受隔离收益。三步走完,代码量变化很小,系统的故障可解释性会上一个台阶——这正是本节开头那句话的完整含义:买的是隔离。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U