07 TrustZone
TrustZone
概述
ARM TrustZone技术是所有Cortex-A系列CPU的基本功能,是通过ARM的安全扩展引入的。TrustZone从硬件层面提供安全机制,将CPU的工作状态分为Normal World(非安全世界)和Secure World(安全世界),涉及到安全相关的操作比如指纹、密码等都要在安全世界中进行,其他操作在非安全世界中运行
系统架构
ARM提供了一套TrustZone技术的开源解决方案TF-A,他是一套底层固件,由于不同芯片原厂的SoC各不相同,芯片原厂一般会基于这个开源的TF-A针对自己的芯片再做一些修改,我们直接用芯片原厂修改好的就行了
前面提到了启用了ARM TrustZone后,CPU被分为2个世界,而这2个世界交互的桥梁就是ARM Trusted Firmware(通过ARM的SMC硬件指令),此时CPU会陷入EL3特权等级
ARMv8特权等级
ARMv8架构有32位的和64位的CPU,分别是AArch64和AArch32,他们都有4个特权等级:EL0~EL3(数字越高、特权越高)
其中根据CPU所处的世界又可以分为安全EL0、安全EL1和非安全EL0、非安全EL1
1 | ELO:一般的应用程序 |
AArch32模式下,EL0~EL3对应ARMv7的不同工作模式
Trusted OS一般指的是OP-TEE,它和Linux内核同时运行,前者负责可信APP,后者负责一般APP
启动流程
传统的ARM架构CPU比如i.MX6ULL的启动流程大致如下:
1 | BootROM => uboot => kernel => rootfs |
ARM TrustZone体系架构讲系统的启动流程定义为以下阶段(AArch64):BL1、BL2、BL31、BL32、BL33如果把这些阶段的定义映射到RK平台上,对应关系如下:BootROM(BL1)、MiniLoader(BL2)、Trust(BL31[ARM Trust Firmware] + BL32[OP-TEE OS])、U-Boot(BL33)
他们的功能如下:
BL1
- 它是 TF-A 的第一个启动阶段,芯片复位以后就会运行 b1 镜像,TF-A 提供了 b1 源码。但是,实际上 bl1 一般是半导体厂商自己编写的内部 Boot ROM 代码,并没有使用 TF-A 提供的 b1 镜像。因此 bl1 部分的实现就千差万别,不同的半导体厂商有不同的实现方法
- 一般 bl1 要做的就是初始化 CPU,如果芯片支持不同的启动设备,那么还需要初始化不同的启动设备,比如NAND.EMMC、SD、USB 或串口等,然后根据 BOOT 引脚的高低电平来判断当前所选择的启动设备,从对应的启动设备中加载 bl2 镜像,并放到对应的内存中,最后跳转到 bl2 镜像并运行
BL2
- 进一步的初始化芯片,比如初始化 DDR、MMU、串口等。bl2 会将剩下三个阶段(bl31、bl32 和 bl33)对应的镜像加载到指定的内存中,最后根据实际情况来启动剩下三个阶段的镜像
BL31
- 在 AArch64 中,bl31 主要是 EL3 的 Runtime 固件
BL32
- bl32 一般为安全系统(TEE OS)固件,比如 OP-TEE。TF-A为 AArch32 提供了 EL3 的 Runtime 软件,这个Runtime 软件就是 bl32 固件,sp_min 就是这个 Runtime 软件。大家可以打开 TF-A 的 bl32 源码文件夹,其下就有一个名为“sp_min”的子文件夹,这个就是 bl32 的 sp_min 源码,如图所示:
- bl32 提供运行时安全服务,在 TF-A 中默认使用 sp_min。sp_min 是一个最小的 AArch32 安全负载(SecurePayload),整合了 PSCI 库以及 AArch32 的 EL3 运行时软件。sp_min 可以替代可信系统(TEE OS)或者可信执行环境(TEE),比如 OP-TEE。用户可以自行选择 bl32 使用哪个软件包
- bl32 充当安全监控(secure monitor),因此它向非安全系统(non-secure os,比如 linux)提供了一些安全服务。非安全的应用软件可以通过安全监控调用(secure monitor calls)来使用这些安全服务,这些代码支持标准的服务调用比如 PSCI
BL33
- Normal世界下的镜像文件,比如u-boot
对于AArch32来说,以上过程会被简化,只有以下几步:
1 | BL1:第1个阶段,一般为芯片内部 ROM 代码 |
ARM Trust Firmware其实本身包含了BL1、BL2、BL31的功能,但是RK仅使用了它BL31的功能
RK 安卓系统的启动流程如下
1 | BOOTROM => Loader(ddr.bin + mini-loader) => Trust => kernel => Android |
