TrustZone 布局配置

本章介绍 TrustZone 的地址映射机制,帮助开发者理解安全代码与非安全代码如何通过不同的地址窗口访问同一块物理内存。

了解 IDAU 和 SAU 的工作原理,有助于理解总线地址的划分方式。在大多数情况下,SDK 已根据芯片的内存布局自动配置好这些参数,开发者无需手动调整。

本章还会介绍一种实际场景:当安全固件体积增加导致编译报出 "region is full" 错误时,如何通过调整安全区域大小来解决问题。

SAU IDAU 联合仲裁

TrustZone 通过 IDAU 和 SAU 两个属性单元协同工作,为 Secure CPU 的总线地址空间设置安全属性。 SAU / IDAU 仅监控来自 CPU 的访问地址,不监控其他总线主设备(如 DMA)。本节介绍两者的工作机制及联合仲裁规则。

IDAU:硬件固化的基础映射

IDAU(Implementation-Defined Attribution Unit)由芯片厂商在硬件设计阶段固化,提供固定的安全属性映射。IDAU 使用地址 bit[28] 区分安全属性:

  • bit[28] = 0:非安全地址空间

  • bit[28] = 1:安全地址空间

以 SRAM 和 PSRAM 为例,地址空间划分如下:

  • SRAM

    • 0x2000_0000 ~ 0x2FFF_FFFF:非安全窗口(bit[28] = 0)

    • 0x3000_0000 ~ 0x3FFF_FFFF:安全窗口(bit[28] = 1)

  • PSRAM

    • 0x6000_0000 ~ 0x6FFF_FFFF:非安全窗口(bit[28] = 0)

    • 0x7000_0000 ~ 0x7FFF_FFFF:安全窗口(bit[28] = 1)

关键点:安全窗口和非安全窗口映射到同一块物理内存,但访问时携带的安全属性不同。

SAU:软件可配置的属性单元

SAU(Security Attribution Unit)可通过软件配置,为地址空间分配安全或非安全属性。

SAU 的特点:

  • 系统上电时,SAU 默认将整个地址空间设置为安全属性

  • SAU 提供多个 Entry,可将指定地址空间配置为非安全(NS)或非安全可调用(NSC)

  • 安全属性级别:S(安全,最高)> NSC(非安全可调用,中等)> NS(非安全,最低)

访问属性的判定规则

当 CPU 访问某个地址时,该访问是 Secure 还是 Non-Secure 的判定流程如下:

  1. IDAU 判定:根据地址 bit[28] 给出硬件固化的安全属性

  2. SAU 判定:根据软件配置给出安全属性

  3. 联合仲裁:取两者中较高的安全级别作为最终结果

安全属性级别:S(安全)> NSC(非安全可调用)> NS(非安全)

../../_images/idau_conj_with_sau.svg

IDAU 与 SAU 联合仲裁规则

备注

系统上电时,SAU 默认将整个地址空间设置为安全,因此启动阶段所有地址访问都是安全的。

SAU 配置文件位置

SAU 配置根据实际的内存布局(Layout)自动生成:

  • 配置数组位于 component/soc/usrcfg/amebaxxx/ameba_boot_trustzonecfg.c 文件中的 sau_config 数组

  • 不同芯片型号的 SAU Entry 数量可能不同

  • SAU 配置在 SDK 初始化阶段由 Bootloader 自动加载执行

在大多数应用场景下,开发者无需手动修改 SAU 配置。不同 IC 的默认 TrustZone 布局请参考 RAM 布局与配置

开发阶段:安全区域大小配置

业务场景:安全固件体积膨胀导致编译失败

随着业务演进,客户在开发过程中添加了大量的私钥处理逻辑和核心安全算法代码(存放在 image3 中)。这经常会导致编译阶段报出 Secure RAM 空间不足的链接错误(Linker Error: region is full)。此时,开发者需要从非安全区的配额中,划拨出更多的内存给安全区域。

底层机制与原理

TrustZone 使能后,安全固件(image3)的代码、数据和栈需要分配到安全内存区域。SDK 通过以下方式控制安全区域的大小:

  • TZ_S_SIZE:存放核心安全代码和数据区,通过 Kconfig 配置(单位为 KB),默认值为 44KB

  • TZ_NSC_SIZE:专门存放生成的 Secure Gateway Veneers(跳转指令表),定义于 linker 脚本

  • TZ_ENTRY_SIZE:存放使用 IMAGE3_ENTRY_SECTION 声明的 NSC 函数实体本身,定义于 linker 脚本

为确保 MPC 正确工作,上述三个区域的总大小须为 4KB 的整数倍。

备注

NSC 区域(TZ_NSC_SIZE)和 Entry 区域(TZ_ENTRY_SIZE)在正常业务场景下无需调整。NSC 区域仅用于跳转指令表,不应在此处存放大量安全业务代码。

配置方法

针对不同平台的具体修改文件及步骤如下:

RTL8721Dx:

配置步骤

  1. 选择安全固件运行位置

    执行 ameba.py menuconfig,按路径 CONFIG TrustZone > CONFIG Link Option > IMG3(SecureImage) running on PSRAM or SRAM? 选择 image3 的运行位置。

  2. 调整安全区域大小

    执行 ameba.py menuconfig,按路径 CONFIG TrustZone > TrustZone Secure Image Size (KB) 配置安全区域大小:

    配置项

    描述

    TZ_S_SIZE

    Secure 区域:存储安全函数实现,非安全代码只能通过 NSC 函数间接调用,默认值为 44KB

    配置完成后,需确保安全区域总大小为 4KB 的整数倍,以满足 MPC 的 4K 对齐要求。

    备注

    NSC 区域(TZ_NSC_SIZE)仅用于存储编译器生成的 Secure Gateway Veneers 跳转指令表,Entry 区域(TZ_ENTRY_SIZE)用于存储 NSC 函数实体。正常业务场景下无需修改这两个区域大小。如确需调整,可修改 component/soc/amebaxxx/project/ameba_layout.ld 文件中的对应宏定义。

备注

关于 NSC 与 ENTRY 的空间分布限制:

TZ_NSC_SIZE 区域中的每个 NSC Entry 由 sg 和 b.w 两条指令共同组成。b.w 指令的编码限制了目标跳转地址不能过远(例如 0x2XXX_XXXX 跳到 0x3XXX_XXXX 地址)。 因此需要在 TZ_NSC_SIZE 区域附近分配 TZ_ENTRY_SIZE 安全区域来存放 NSC 函数。更多细节请参考 Cortex-M 安全服务