0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用Cortex-M MPU来提高嵌入式设备的安全性

星星科技指导员 来源:嵌入式计算设计 作者:Jean Labrosse 2022-06-10 07:36 次阅读

ARM Cortex-M 架构于 2004 年推出,是目前市场上最流行的 32 位架构,被大多数(如果不是所有)主要 MCU 制造商采用。Cortex-M 从一开始就设计为对 RTOS 内核友好:专用的 RTOS 滴答计时器、上下文切换处理程序、用 C 编写的中断服务例程、尾链、简单的临界区管理等等。许多 Cortex-M MCU 实施都辅以浮点单元 (FPU)、DSP 扩展、高度通用的调试端口和内存保护单元 (MPU)。

在这个四部分系列的第 2 部分中,让我们看看如何使用 Cortex-M MPU 来提高嵌入式设备的安全性。在此处阅读其他三个部分:第 1部分、第 3部分和第 4 部分。

ARM Cortex-M

2004 年,Arm 推出了基于精简指令集计算机 (RISC) 架构的新系列 CPU 内核,称为 Cortex-M(M 代表微控制器)。第一个 Cortex-M 被称为 Cortex-M3,该系列已经发展到包括许多衍生内核:Cortex-M0/M0+、Cortex-M4、高性能 Cortex-M7,以及最近推出的 Cortex-M23 和M33 采用 TrustZone 安全技术。

Cortex-M 处理器系列的程序员模型(见图 1)高度一致。例如,R0 到 R15、PSR、CONTROL 和 PRIMASK 可用于所有 Cortex-M 处理器。两个特殊寄存器 - FAULTMASK 和 BASEPRI - 仅在 Cortex-M3、Cortex-M4、Cortex-M7 和 Cortex-M33 上可用,浮点寄存器组和浮点状态和控制寄存器 (FPSCR) 在可选浮点内的 Cortex-M4、Cortex-M7 和 Cortex-M33。一些 Cortex-M 实现还配备了内存保护单元 (MPU)。

pYYBAGKgbeqAIaujAACpysk-Vkg540.png

【图1 | 基于 Armv7-M 的 CPU 寄存器模型。]

在上下文切换期间,RTOS 会保存和恢复 CPU 寄存器和 FPU 寄存器(假设处理器配备了一个)。因为 MPU 配置是从表格中获取的,所以我们只需要在任务切换时加载 MPU 寄存器。换句话说,不需要为被切换的任务保存MPU配置。详细信息将在下一节中描述。

Cortex-M 特权级别

上电时,Cortex-M 以特权模式启动,使其能够访问 CPU 的所有功能。它可以访问任何内存或 I/O 位置,启用/禁用中断,设置嵌套向量中断控制器 (NVIC),以及配置 FPU 和 MPU,等等。

为了保证系统的安全和可靠,特权模式代码必须保留给经过充分测试且已知可信的代码。由于大多数 RTOS 都经过了彻底的测试,因此 RTOS 通常被认为是受信任的,而大多数应用程序代码则不是。这种做法很少有例外。例如,通常假定 ISR 是受信任的,因此也可以在特权模式下运行,只要这些 ISR 不被滥用并尽可能短。这是大多数 RTOS 供应商的典型建议。

可以使应用程序代码以非特权模式在 Cortex-M 上运行,从而限制代码可以执行的操作。具体来说,非特权模式会阻止代码禁用中断、更改嵌套向量中断控制器 (NVIC) 的设置、将模式改回特权模式以及更改 MPU 设置以及其他一些事情。这是一个理想的特性,因为我们不希望不受信任的代码赋予自己特权,从而改变系统设计者实施的保护。

由于 CPU 总是以特权模式启动,因此需要从一开始就创建任务以在非特权模式下运行,或者在启动后不久切换到非特权模式(通过调用 API)。一旦进入非特权模式,CPU 只能在服务中断或异常时切换回特权模式。

SVC 处理程序

由于非特权代码无法通过 CPU 或 NVIC 禁用中断,因此应用程序代码被迫使用 RTOS 服务来访问共享资源。因为 RTOS 服务需要在特权模式下运行(在关键部分禁用中断),非特权任务必须通过 Cortex-M 上称为 SuperVisor Call (SVC) 的特殊机制才能切换回特权模式。SVC 的行为类似于中断,但由一条名为 SVC 的 CPU 指令调用。这也称为软件中断。

在 Cortex-M 上,SVC 指令使用一个 8 位参数来指定调用者想要执行的 256 个可能的 RTOS 函数(或服务)中的哪一个。系统设计者决定哪些 RTOS 服务应该对非特权代码可用。例如,您可能不希望允许非特权任务终止另一个任务(或它本身)。此外,这些服务都不允许禁用中断,因为这会破坏在非特权模式下运行代码的原因之一。一旦被调用,SVC 指令将引导至称为 SVC 处理程序的异常处理程序。

这个过程如图 2 所示。 (1) 一些非特权代码执行 SVC #5 以等待互斥体。(2) SVC指令强制SVC异常处理程序执行。该行为与生成中断时相同。SVC 处理程序提取参数(即值 5)并使用该参数将 (3) 索引到 SVC 跳转表中。(4) 执行所需的 RTOS 服务(特权模式),完成后,RTOS 返回到非特权代码。

SVC 处理程序是 RTOS 的一部分,因此您不必担心实现它。事实上,无论您的任务是在特权模式还是非特权模式下运行,您的应用程序代码都会调用相同的 RTOS API。

通过 SVC 处理程序需要付出代价:额外的代码和 CPU 周期。在 Cortex-M3 上,SVC 处理程序添加了大约 1 KB 的代码并执行 75 到 125 条 CPU 指令来执行。因此,与从特权模式调用相同的 RTOS 服务相比,由非特权模式调用的任何 RTOS 服务都需要更多的处理时间。

poYBAGKgbfSAFpUTAADk1S2duE8595.png

【图2 | 限制来自非特权代码的 CPU、NVIC 和 MPU 访问。]

在非特权模式下运行代码还可以防止用户代码禁用中断,从而减少锁定系统的机会。当然,如果用户代码进入无限循环,锁定仍然可能发生,尤其是在高优先级任务或 ISR 中发生这种情况时。但是,在这种情况下,可以通过使用看门狗来恢复锁定。

附带说明一下,如果非特权任务尝试通过 NVIC 禁用中断,Cortex-M 会生成故障(总线故障)。您的应用程序代码需要考虑到这一点。

在非特权模式下运行仍然不会阻止应用程序代码访问任何内存位置和外围设备或阻止代码在 RAM 之外执行。这就是 MPU 的用武之地。

Armv7-M 架构中的 Cortex-M MPU

Cortex-M(假设为 Armv7-M)上的 MPU 是一种设备,它允许进程访问多达八 (8) 或十六 (16) 个内存或外围区域(取决于 MCU 实现)。每个区域的位置和大小是可配置的。每个区域的大小必须是 2 的幂的倍数,但不能小于 32 字节。此外,区域的基地址必须与区域大小的整数倍值对齐。因此,如果该区域为 8K 字节,则该区域必须在 8K 边界上对齐。由于 MPU 中可用的区域相对较少,因此区域通常用于限制对 RAM 和外围设备的访问,而不是太多代码。但是,必须使用至少一个区域来提供对代码空间的访问。

组织内存的一种方便方法是将进程所需的 RAM 分组到一个连续的块中,如图 3 所示。每个进程都将以类似的方式设置。进程 A 的扩展视图显示它由四个任务组成,每个任务都有自己的堆栈。进程 A 还管理一个外围设备。空白代表可能由于 MPU 的对齐限制而未使用的内存或 I/O 空间。

pYYBAGKgbfyAbzlSAACqERP9ej8090.png

【图3 | 按进程对区域进行分组。]

F3(1) 需要一个 MPU 区域来提供对代码空间的访问。该区域可以设置为只允许访问与进程关联的代码,但是当一个进程与其他进程共享代码(即库)时,有时可能会出现问题。

F3(2) 需要一个 MPU 区域来允许进程内的所有任务访问分配给进程的外围设备。例如,如果进程 A 管理一个以太网控制器,则该区域必须允许访问与该设备关联的所有寄存器。

F3(3) MPU 区域用于访问分配给进程的所有 RAM。这里假设进程全局变量和进程堆由进程内的所有任务共享。附带说明一下,不可能使用所有进程都可以使用的全局堆,因为您无法设置 MPU 表来将一个进程的动态分配内存与另一个进程的动态分配内存分开。

F3(4) MPU 区域用于 RedZone 堆栈检查。事实上,我们只需要一个区域来覆盖一个进程中的所有任务堆栈,因为我们只需要在上下文切换期间移动 RedZone。然而,这意味着每个任务将需要一个稍微不同的 MPU 进程表。话虽如此,这在很大程度上取决于 RTOS 在上下文切换期间如何管理 MPU。例如,RTOS 可能决定只加载 MPU 进程表中的前七个区域,并使用堆栈的基地址加载最后一个区域以设置 RedZone。大多数时候,RTOS 将任务堆栈的基地址存储在任务的控制块 (TCB) 中。使用这种方案,一个进程中的所有任务可以共享完全相同的进程表,同时为任务堆栈正确设置 RedZone。

F3(5) 这表示由于 Cortex-M 的 MPU 要求所有区域的大小必须是 2 的二进制幂而导致的未使用 RAM。因此,如果进程 A 需要 7 KB 或 RAM,则由于进程 A 需要 8 K,因此会丢失 1K。您可能只想增加某些堆栈的大小,而不是浪费该空间在进程中减少堆栈溢出的机会。但是,这样做的缺点是,如果您需要向进程添加功能,那么您可能不记得可以回收多少内存。事实上,从安全关键的角度来看,如果您使用内存配置来限定您的系统,那么您可能无法收回它。因此,最好分配进程所需的堆栈并忍受浪费的空间。

从程序员的角度来看,Cortex-M MPU 是一个相当简单的设备,它由 19 个 32 位寄存器组成,如图 4 所示。您会注意到,该模型与图 1 中的模型不同,因为一些寄存器实际上是存储的,因此可以间接寻址,但在内部,它们就是这样出现的。

pYYBAGKgbgaAIPhCAAIScKmq7Yo791.png

【图4 | Cortex-M MPU 寄存器。]

TYPE寄存器用于决定MPU支持的MPU区域数量,该寄存器的DREGION字段会一直读为0、8或16。CTRL寄存器用于配置MPU的某些方面,但实际上,该寄存器用于启用或禁用 MPU。事实上,在更改任何或所有区域的配置之前,应禁用 MPU。RNR编号允许您寻址特定的 MPU 区域。

参考图 4,您会注意到 RBAR 的低五位具有固定值。当设置为 1 时,“V 位”表示低 4 位用于指定区域编号。RBAR 的高位用于指定区域的基地址。基地址必须在与区域大小匹配的边界上对齐;例如,1 KB 区域必须在 1 KB 边界上对齐。

在大多数情况下,为给定区域设置属性非常简单:

RASR.XN 当区域覆盖 RAM 并且您不希望在该区域之外执行代码时,强烈建议您将此位设置为 1。这将捕获来自黑客的代码注入攻击。

RASR.AP: 如果该区域覆盖了 RAM 区域,那么您将这些位设置为“011”,如果该区域覆盖 ROM,则将该字段设置为“110”。

RASR.TEX SCB 图 4 显示了基于内存区域所在位置的这些位的典型值。

RASR.SRD 此字段允许您将区域细分为八个相等的部分。此功能可以大大减少内存浪费。例如,一个 16 KB 的区域有八个 2 KB 的子区域,因此如果一个进程只需要 5 KB(3 个子区域),那么您可以禁用其中的五个子区域并将它们分配给不同的进程。

RASR.SIZE 这个字段设置起来有点复杂,因为它需要一些人工干预,并专门查看链接器映射文件以确定两个大小属性的编码二进制幂。

RASR.EN 该位启用 (1) 或禁用 (0) 区域。如果您不需要所有八个区域,则必须禁用该区域,以免无意中启用来自不同进程的区域。

清单 1 显示了加载所有八个 MPU 区域的优化函数的汇编语言代码。我将此作为一个示例,说明我们可以如何有效地更改 MPU 配置,但这不是您必须担心的事情。确定管理 MPU 的最佳方式确实是 RTOS 的责任。但是,您需要遵循 RTOS 指南,了解如何为每个任务设置 MPU 进程表。对于这个特定的实现,您需要创建一个 MPU 进程表来分配所有八个区域,即使使用的区域更少。该函数的原型是:

void OS_MPU_ProcessSet (ARM_MPU_Region_t *p_process);

p_process 是指向包含八对 RBAR 和 RASR 值的 MPU 进程表的指针。ARM_MPU_Region_t 是 ARM 的 Cortex 微控制器软件接口标准 (CMSIS) 3定义的数据类型,声明如下:

typedef struct

{

uint32_t RBAR; // Region base address

uint32_t RASR; // Region attributes (type, region size, enable, etc.)

} ARM_MPU_Region_t;

因此,对于每个任务,您需要声明一个包含八个条目的 ARM_MPU_Region_t 数组,如下所示:

poYBAGKgbhuAd6LIAAWkSHFkHa4454.png

请注意,最后一个条目包含任务堆栈的基地址,并且还假定 RedZone 大小为 32 字节。

pYYBAGKgbjeANHZiAASK-0WZ1GQ512.png

[清单 1 | 配置所有 8 个 MPU 区域。]

概括

Cortex-M 中的 MPU 是一个相当简单的设备。RTOS 负责在每次上下文切换时配置 MPU。但是,为应用程序设置 MPU 进程表是应用程序开发人员的责任。如果 RTOS 为每个任务设置了 RedZone,则一个进程中的任务可以共享同一个 MPU 进程表。

要让应用程序在 MPU 上运行,仍然需要注意一些事项。具体来说,如何按进程对 RAM 进行分组?一个进程如何与另一个进程通信?如果任务访问其分配的内存空间之外的内存或外围设备会发生什么?除了任务栈,内核对象是否应该分配在进程内存空间中?我们将在第 3 部分解决这些问题。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    30

    文章

    4995

    浏览量

    117424
  • RAM
    RAM
    +关注

    关注

    7

    文章

    1307

    浏览量

    113644
  • MPU
    MPU
    +关注

    关注

    0

    文章

    290

    浏览量

    48299
收藏 人收藏

    评论

    相关推荐

    嵌入式会越来越卷吗?

    嵌入式系统能够实现更快速、更稳定的通信。 这使得嵌入式系统能够更好地与其他设备或系统进行交互和协作。 安全性增强:随着网络安全问题的日益严
    发表于 03-18 16:41

    基于简化Cortex-M核微控制器嵌入式软件的开发步骤

    电子发烧友网站提供《基于简化Cortex-M核微控制器嵌入式软件的开发步骤.pdf》资料免费下载
    发表于 10-24 09:02 0次下载
    基于简化<b class='flag-5'>Cortex-M</b>核微控制器<b class='flag-5'>嵌入式</b>软件的开发步骤

    MCU是怎么为物联网端点设备提高安全性的?

    MCU 是怎么为物联网端点设备提高安全性的?
    发表于 10-17 08:53

    Cortex™-M0+设备通用用户指南

    。 ·卓越的代码密度。 ·确定性、高性能中断处理。 ·向上兼容Cortex-M处理器系列。 ·平台安全稳健,可选的集成内存保护单元(MPU)。
    发表于 08-29 07:18

    ARM Cortex-M处理器对比表

    Cortex-M处理器系列针对低成本、高能效的微控制器进行了优化。 这些处理器可以在各种应用中找到,包括物联网、工业和日常消费设备。 该处理器系列基于M-Profile架构,可为深度嵌入式
    发表于 08-29 07:00

    新唐工业计算机/服务器安全智联升级方案

    和用户同样首重安全性,将工业设备连接到网络,网络安全的议题是最重要的考虑,必须兼具安全与高互联的连网需求。 系统整合:
    发表于 08-25 08:07

    Arm Cortex-M23处理器产品介绍

    应用程序的安全性是关键要求。 用于ARMv8-M的TrustZone在Cortex-M23设备上的可信和不可信资源之间提供硬件强制隔离,同时保持所有
    发表于 08-25 06:19

    Cortex™-M0设备通用用户指南

    Cortex™-M0处理器是一款入门级32位ARM Cortex处理器,专为各种嵌入式应用而设计。 它为开发人员提供了显著的好处,包括: ·简单易用的程序员模型·高效超低功耗操作·卓越
    发表于 08-23 08:12

    ARM Cortex-M23设备通用用户指南

    Cortex-M23处理器是一款入门级32位ARM Cortex处理器,专为各种嵌入式应用而设计。 它为开发人员提供了显著的好处,包括: ·简单的架构,易于学习和编程。 ·超低功耗、高能效运行
    发表于 08-23 07:35

    ARM Cortex-M7处理器参考手册

    Cortex-M7处理器是一款高效、高性能的嵌入式处理器,具有低中断延迟、低成本调试的特点,并具有与现有Cortex-M Profile处理器的向后兼容。 该处理器具有有序的超标量流
    发表于 08-17 07:55

    ARM Cortex-M23处理器技术参考手册

    Cortex-M23处理器是一款低门数、两级和高能效处理器。 它适用于微控制器和深度嵌入式应用,这些应用需要在安全性是重要考虑因素的环境中使用区域优化的低功耗处理器。
    发表于 08-17 07:28

    Arm Cortex®-M33处理器技术参考手册

    Cortex®-M33处理器是一款低门数、高能效的处理器,适用于微控制器和深度嵌入式应用。 该处理器基于ARM®V8-M架构,主要用于安全性
    发表于 08-17 07:23

    使用MPU监控创建安全可靠的嵌入式系统 使用MPU监控的原因和好处

    在当今快节奏的世界中,嵌入式系统在各个行业中发挥着至关重要的作用,涵盖汽车和航空航天到医疗和工业自动化领域。随着嵌入式系统的日益复杂和关键性,确保其安全性和可靠性变得更加重要。开发人员采用
    的头像 发表于 07-21 11:04 533次阅读

    什么是MPUMPU在哪些方面保护内存安全

    内存保护单元(MPU)是一种硬件机制,通过只允许代码访问需要的内存和外设来提高嵌入式设备安全性
    的头像 发表于 06-12 09:06 6663次阅读
    什么是<b class='flag-5'>MPU</b>?<b class='flag-5'>MPU</b>在哪些方面保护内存<b class='flag-5'>安全</b>?

    PX5的ARM TrustZone支持让嵌入式系统变得更加安全

    产品安全性。PX5 RTOS对ARM TrustZone的支持让嵌入式开发者能够从物理层降低网络安全风险。 PX5的CEO William Lamie表示:“基于MCU的产品如今已是生活中不可缺少的一部分
    发表于 05-18 13:44