4. TrustZone 地址空间控制器(TZASC)
TZASC(TrustZone Address Space Controller)是 ARM TrustZone 硬件架构中负责物理内存隔离的关键组件。它位于系统总线与内存控制器之间,对来自总线主设备(如 CPU、DMA)的访问请求进行安全属性检查,决定该请求能否访问目标物理内存区域。
核心作用:TZASC 将物理内存划分为安全区域(Secure World)和非安全区域(Normal World),确保非安全世界无法读取或写入安全世界的内存数据,即使通过 DMA 等外设也无法绕过。
4.1 TZASC 的工作原理
TZASC 本质上是一个可编程的地址过滤器。它内部维护一组区域描述符(Region Descriptor),每个描述符定义了一段物理地址范围及其安全属性。当总线事务发起时,TZASC 按以下流程工作:
- 地址匹配:将事务的目标物理地址与所有已配置的区域描述符进行优先级比较。
- 安全属性检查:根据匹配到的区域描述符中的安全位(NS 位)判断该区域属于安全还是非安全。
- 访问控制决策:结合事务发起者的安全状态(Secure/Non-Secure),决定是否允许该访问。
- 响应处理:若允许,正常转发事务;若拒绝,返回错误响应(DECERR/SLVERR)。
关键规则:安全世界可以访问安全区域和非安全区域;非安全世界只能访问非安全区域。任何非安全世界对安全区域的访问都会被 TZASC 硬件阻断。
4.2 安全与非安全内存区域的配置
TZASC 的配置通过内存映射寄存器完成,通常在系统启动早期由安全世界固件(如 ARM Trusted Firmware)进行初始化。每个 TZASC 实例支持多个区域,典型配置步骤如下:
| 步骤 | 寄存器操作 | 说明 |
|---|---|---|
| 1 | REGION_SETUP_LOCK | 锁定区域配置寄存器,防止非安全世界篡改 |
| 2 | REGION_BASE_LOW/HIGH | 设置区域起始物理地址(64位对齐) |
| 3 | REGION_TOP_LOW/HIGH | 设置区域结束物理地址 |
| 4 | REGION_ATTRIBUTES | 配置安全属性(NS=0 安全,NS=1 非安全) |
| 5 | REGION_ID | 使能该区域,并设置优先级 |
安全注意事项:区域配置必须在安全世界完成,且配置完成后应锁定寄存器。非安全世界任何对 TZASC 寄存器的写入都会被忽略或触发安全异常。
/* TZASC 区域配置示例(伪代码) */
void tzasc_configure_region(uint32_t region_id,
uint64_t base,
uint64_t top,
uint8_t ns_bit)
{
/* 1. 写入区域基地址 */
write_reg(TZASC_REGION_BASE_LOW(region_id), (uint32_t)(base & 0xFFFFFFFF));
write_reg(TZASC_REGION_BASE_HIGH(region_id), (uint32_t)(base >> 32));
/* 2. 写入区域结束地址 */
write_reg(TZASC_REGION_TOP_LOW(region_id), (uint32_t)(top & 0xFFFFFFFF));
write_reg(TZASC_REGION_TOP_HIGH(region_id), (uint32_t)(top >> 32));
/* 3. 配置属性:NS 位决定安全/非安全 */
uint32_t attr = (ns_bit & 0x1) << TZASC_ATTR_NS_SHIFT;
attr |= (1 << TZASC_ATTR_EN_SHIFT); /* 使能区域 */
write_reg(TZASC_REGION_ATTRIBUTES(region_id), attr);
/* 4. 锁定配置(可选) */
write_reg(TZASC_REGION_LOCK(region_id), 0x1);
}
4.3 多区域保护策略
实际系统中,物理内存通常需要划分为多个安全区域,每个区域服务于不同的安全需求。典型的多区域划分策略如下:
多区域保护策略的核心原则:
- 最小权限原则:每个安全区域只包含必要的数据和代码,避免安全世界内部不同组件互相影响。
- 区域隔离:不同安全区域之间通过 TZASC 的独立区域描述符进行隔离,即使同属安全世界,一个区域的溢出也不会影响另一个区域。
- 共享内存管理:非安全世界与安全世界之间的数据交换通过显式配置的共享内存区域(NS=1)完成,该区域对双方都可读写。
- 动态重配置:在系统运行过程中,安全世界可以根据需要动态调整区域属性,但必须保证操作原子性和一致性。
实战建议:在驱动开发中,TZASC 的配置通常由 BootROM 或 ATF(ARM Trusted Firmware)完成。驱动开发者需要理解当前系统的区域划分,确保 DMA 缓冲区位于正确的安全区域,避免因地址越界导致系统挂死或安全漏洞。
4.4 TZASC 与系统其他组件的协作
TZASC 并非孤立工作,它与 TZMA(TrustZone Memory Adapter)、TZC(TrustZone Controller)以及系统 MMU 协同完成完整的内存保护:
| 组件 | 保护层级 | 作用范围 | 配置时机 |
|---|---|---|---|
| TZASC | 物理内存区域 | 整个系统总线 | 启动时由安全固件配置 |
| TZMA | 片上 SRAM 区域 | 特定内存控制器 | 硬件静态配置或 BootROM |
| TZC | 外设访问控制 | 特定外设总线 | 运行时动态配置 |
| MMU/SMMU | 虚拟地址映射 | CPU/DMA 视角 | 操作系统运行时 |
在驱动开发中,理解 TZASC 的配置和限制是编写安全驱动的前提。例如,当驱动需要分配 DMA 缓冲区时,必须确保该缓冲区位于非安全区域(如果驱动运行在非安全世界),否则 DMA 操作会触发 TZASC 拒绝访问,导致数据传输失败。
调试技巧:如果系统在访问特定内存地址时返回 DECERR(解码错误),首先检查 TZASC 的区域配置。使用 JTAG 或安全监控模式读取 TZASC 寄存器,确认目标地址是否被正确配置为允许当前安全状态访问。