使用内存保护单元的优势

FreeRTOS 202012 LTS 支持结束

目前你用来阅读这篇文章的设备依赖处理器的内存管理单元 (MMU) 对每个运行中的应用程序执行沙箱处理。如果用户设备不具备防止错误访问甚至恶意访问错误内存的能力(无论是操作系统数据还是其他任务数据),则用户设备将成为漏洞和安全漏洞的雷区。

涉及嵌入式项目时,您所用的内存保护单元 (MPU) 可以提供许多同等优势。通过MPU,用户通常可以特权模式或非特权模式运行,并使用一组“区域”来确定当前执行的代码是否有权限访问代码和数据。每个区域都是一个连续的内存块,具有该内存的一组权限;既有特权访问权限,也有非特权访问权限。特权代码通常可访问设备的大部分(如果并非全部)内存,而非特权代码则只能访问小得多的子集。

这些区域在应用程序的整个运行期间不必相同。MPU可以根据每项任务修改区域;当任务变为运行状态时,每个任务都可配置其独特的区域集。这允许您只授权有需要的任务访问代码和数据。在每次上下文切换期间,使用 MPU 的嵌入式操作系统将对各任务的区域和特权级别进行管理。

图 1:全局区域和任务 MPU 区域示例。 点击放大。

图 1 显示了两个不同任务在使用 MPU 时如何查看系统内存。共有两个全局 MPU 区域,其中一个在闪存开始时,另一个在 RAM 开始时。任务 1 获授权执行访问任务 2 无法访问的部分闪存代码。相反,任务2则获授权执行访问闪存内的不同代码集。如果任务 1 试图在此处执行任务 2 的任何代码,则会生成 MPU 错误,反之亦然。

虽然任务 1 和任务 2 均含有 MPU 覆盖 RAM 中相同内存范围的区域,但二者并未获得相同权限。任务 1 只能读取区域内的数据,而任务 2 可以读取和写入。在任务 2 作为特定数据源而任务 1 使用这些数据但绝无数据修改权限的情境中,这种方式可能行之有效。

FreeRTOS 在其多个 ARM Cortex 端口(M3、M4、M23 和 M33)以及其 Aurix MPU 和 Xtensa ESP32 端口中提供 Tricore 支持。与 FreeRTOS 类似的安全关键系统 SAFE RTOS 在所有可用的平台上都支持 MPU。

为什么使用 MPU?

在嵌入式项目中使用 MPU 可降低顿挫感、省时省钱。对于开发人员而言,MPU 的最大好处在于开发初期便能够捕获漏洞。及早发现漏洞可显著缩短开发时间。在项目后期修复代码漏洞可以减少文档及测试代码所需的返工。另一方面,尽早修复漏洞将减少项目后期阶段代码中的错误数量。由于不太可能同时存在多个漏洞,所以此举将简化识别修复剩余漏洞的过程。这样帮助您把握和跟上进度,防止发生意外延误。

MPU 是如何实现这一点的?保护与当前执行代码无关联的所有数据是最为行之有效的方法。可以仅使用两个 RTOS 任务(任务 A 和任务 B)来举一个简单的例子。任务 A 和任务 B 不应彼此交互,但存在一个漏洞 ,其中任务 A 可能意外写入任务 B 偶尔使用的某些数据。覆盖此数据对任务 A 的正确操作无影响。但任务 B 尝试使用损坏的数据时,任务 B 可能出现异常故障。如果并未配置 MPU 来防止任务 A 写入任务 B 的数据 ,则开发人员可能需要很长时间才能跟踪到此错误。如果该错误细微不易察觉,或者任务 B 很少使用该数据,那么这一问题将会极难解决。但如果使用 MPU ,错误写入操作即刻出现异常,进而可以确定哪一行代码导致故障

由于用户可以设置 MPU 区域,防止非特权代码访问 0x0 内存,因此, MPU 甚至可以在某些架构上帮助用户检测空指针偏移。

在您的应用程序中,一组设计良好的 MPU 区域可以显式保护重要的内存区域,以防止特定的问题。例如将缓冲区定位在 MPU 区域的末端来防止缓冲区溢出。用户还可以将任务栈放置在任何非特权代码无法访问的区域。设置完成后,每个任务必须使用它们自己的某个 MPU 区域,明确通过自行授权获得对其堆栈的访问权限。如果使用 MPU,用户须真正思考应用程序的结构,以便在任务之间明确分离数据,形成稳健性强且可维护的代码库。

何时不必使用 MPU?

以下两种情况下, 您不会在处理器上使用MPU :简单项目和性能关键项目。第一种情况比较直观:使用 MPU 复杂性增加,可能不利于极简应用程序。您无需设置覆盖您的闪存、MPU 和外围设备的 RAM 区域,您的 blinky 演示也可能成功。

如果用户需要处理器中的各项性能发挥到极致,那么因使用 MPU 而产生的系统开销,可能会影响用户使用。由于每项任务均需要多个待编程的 FreeRTOS 区域,因此,MPU 的 MPU 端口中的任务上下文切换例程更长。当正在切换上下文时,RTOS 必须对各项任务 MPU 区域进行编程,同时执行例如堆叠使用过的寄存器等常规任务。此外,由于内核代码和数据受 MPU 保护,因此所有内核函数调用均须受包装函数保护。此包装函数仅在调用内核函数之前,提高处理器的权限级别,随即还原权限并返回。这一过程不仅会增加运行代码所需时间,还可能增加任务所需堆栈大小。任务的控制块还须在其 MPU 区域存储信息,并且在某些安全关键 RTOS 的情况下例如 SAFERTOS,则也将存储此数据的镜像。

用户还应注意,使用 MPU 可能会比较难,有时甚至会令人很沮丧。应用程序设计需要更多时间,因为设计人员必须为每项任务考虑 MPU 区域。这些区域中的错误(例如区域长度不正确、权限不正确或未正确链接应用程序的数据)可能会令调试变得困难。

了解有关 MPU 使用方法的更多信息

虽然短期内学习使用 MPU 可能困难重重,并且在用户代码中添加了少量虚耗,但这些优势较为明显。FreeRTOS 在 ARMv7-M(Cortex-M3、Cortex-M4 和 Cortex-M7 微控制器)和 MPU(Cortex-M23 和 Cortex-M33 微控制器)核心上提供官方 ARMv8-M 支持。请参阅更多有关 FreeRTOS 内存保护支持 https://freertos.org/zh-cn-cmn-s/FreeRTOS-MPU-memory-protection-unit.html的信息。

如欲了解有关 MPU 的更多信息,WITTENSTEIN 高完整性系统通过其 YouTube 频道,提供极有帮助的 “内存保护”应用说明https://www.highintegritysystems.com/rtos/rtos-tutorials/以及丰富的辅助视频 https://www.youtube.com/user/HighIntegritySystems/videos

本博客由 高完整性系统 SAFERTOSWITTENSTEIN 项目工程师供稿。SAFE RTOS 是一个安全关键的预先认证的实时操作系统,与 FreeRTOS 共享功能模型。您可访问 SAFE 查阅RTOS各类白皮书,包括如何从 FreeRTOS 升级到 SAFERTOS 的详细示例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值