OP-TEE-OS:综述

OP-TEE-OS:综述

OP-TEE(Open Portable Trusted Execution Environment) 是基于 ARM TrustZone 的开源可信执行环境(TEE),由 Linaro 维护,遵循 GlobalPlatform TEE 标准,用于在安全世界(Secure World)隔离运行敏感代码与数据,与非安全世界(REE,如 Linux/Android)严格隔离。

项目链接:

一、整体架构(双世界模型)

OP-TEE 分为 安全世界(Secure World)非安全世界(Normal World/REE) ,通过 SMC 与 **ATF(BL31)**交互。

安全世界(Secure World)

核心组件:optee_os(本项目)

  • 特权层(Secure EL1):
    • 微内核调度器(事件驱动)
    • 内存管理(MMU/页表、安全内存池)
    • 中断管理(GICv2/v3 安全中断路由)
    • 安全世界驱动(UART、Crypto 引擎、RPMB、eMMC 等)
    • TA 加载/会话管理
    • GlobalPlatform TEE 核心服务实现
  • 用户层(Secure EL0):
    • Trusted Application(TA):实现具体安全业务(指纹/人脸模板保护、支付 Token、密钥管理、DRM 等)
    • 支持静态 TA(编译进 optee_os 镜像)和动态 TA(运行时从 REE 侧加载)

非安全世界(Normal World/REE)

核心组件:optee_client(独立项目)

  • 用户库:libteec.so,实现 GlobalPlatform TEE Client API,供 Client Application(CA)调用
  • 内核驱动:optee.ko(Linux 主线 4.12+),处理 SMC 代理、共享内存管理、中断转发、session 管理
  • 守护进程:tee-supplicant,提供 REE 侧辅助服务(动态 TA 加载、安全存储后端代理、网络代理等)
  • 应用:Client Application(CA),Android/Linux 用户态应用,通过 libteec 访问 TA

顶层目录/文件目录结构介绍

c 复制代码
- core/:OP-TEE 内核核心代码
  - core/arch/:架构相关代码(ARMv7-A/ARMv8-A/ARMv9-A),包含汇编入口、上下文切换、MMU/页表管理
  - core/drivers/:安全世界驱动
  - core/include/:内核头文件(数据结构、API、宏定义)
  - core/kernel/:内核核心逻辑(任务调度、中断处理、内存管理、TA 管理)
  - core/lib/:内核内部库(字符串处理、数学运算等)
  - core/tee/:TEE 核心服务(GlobalPlatform API 实现、会话管理、TA 加载/卸载)
  - core/pm/:电源管理相关代码
- keys/:示例签名/验签密钥(如 RSA 密钥对),用于开发测试阶段镜像签名
- ldelf/:安全世界中动态加载 ELF 格式 TA 的加载器代码
- lib/:通用库函数(libutils、libmpa 大数运算库、libtomcrypt 加密库等)
- mk/:构建系统核心 Makefile 片段(编译规则、平台配置、工具链选择)
- scripts/:辅助脚本(编译、打包、签名、调试、代码检查等)
- ta/:TA 开发模板、示例 TA(hello_world/、storage/、crypto/ 等)、链接脚本
- Makefile:顶层构建入口(编译整个 OP-TEE OS)
- LICENSE:开源许可证文件(BSD 3-Clause)
- README.md:项目说明文档

【OP-TEE OS 代码加载启动全流程梳理】

前置依赖:ATF BL1/BL2/BL31 的准备

  1. BL1(ROM):固化在芯片 ROM 中的信任根,初始化片内 SRAM,从外部存储(eMMC/SD/SPI Flash)加载并验签 BL2
  2. BL2(Secure EL1):初始化 DRAM,从外部存储加载并验签 BL31(ATF)、BL32(optee_os)、BL33(LK/U-Boot/UEFI),将 BL32 的加载地址、大小、设备树等信息通过 bl_params 结构体传递给 BL31
  3. BL31(EL3):初始化 EL3 环境、PSCI 电源管理服务、OP-TEE 的 SPD(opteed,Secure Payload Dispatcher)分发器,解析 bl_params 获取 BL32 信息

第一阶段:BL31 跳转到 optee_os(EL3→Secure EL1)

  1. BL31 调用 opteed 的 opteed_synchronous_sp_entry() 函数
  2. 配置 CPU 上下文:
    • SPSR_EL3:设置目标异常等级为 Secure EL1,禁用所有中断
    • ELR_EL3:设置为 BL2 传递的 optee_os 入口地址(通常是 optee_os/core/arch/arm/kernel/generic_entry_a64.S 的 _start 标签,AArch64 架构)
    • 保存/恢复必要的通用寄存器
  3. 执行 el3_exit() 汇编函数,触发 ERET(Exception Return)指令
  4. CPU 从 EL3 退出到 Secure EL1,PC 跳转到 optee_os 的 _start 标签
    通过链接脚本kern.ld.S 定义了 _start 为OPTEE-OS的启动入口
    文件路径:core\arch\arm\kernel\kern.ld.S
    _start是系统启动的入口点,主要功能包括:
  1. 保存启动参数:将寄存器x0-x3的值暂存到x19-x22。
  2. 初始化异常向量表:设置VBAR_EL1寄存器指向reset_vect_table。
  3. 内存初始化
    • 若启用分页器(CFG_WITH_PAGER),将初始化代码复制到正确位置。
    • 清除.bss段和.nex_bss段。
  4. 重定位处理:若支持物理地址重定位(CFG_CORE_PHYS_RELOCATABLE),计算并应用重定位偏移。
  5. 栈和线程本地存储初始化:设置SP_EL0/SP_EL1,初始化thread_core_local结构。
  6. MMU和缓存配置
    • 使缓存无效并启用MMU。
    • 初始化内存映射和ASLR(地址空间布局随机化)。
  7. 安全初始化
    • 初始化内存标签(MEMTAG)和指针认证(PAUTH)。
    • 注册控制台和处理重定位后的地址更新。
  8. 最终跳转
    • 调用主初始化函数boot_init_primary_*
    • 根据是否启用FFA(固件框架架构)决定跳转到cpu_on_handler或通过SMC返回。

整体流程为系统启动的核心初始化逻辑,涵盖硬件抽象、内存管理、安全特性和多核支持。


第二阶段:optee_os 自身初始化(Secure EL1→Secure EL0 准备)

2.1 汇编初始化
  1. 检查当前异常等级(必须是 Secure EL1)
  2. 禁用 MMU、Cache、分支预测
  3. 初始化栈指针(SP_EL1),指向预分配的 Secure EL1 栈
  4. 配置 SCTLR_EL1(系统控制寄存器):设置字节序、对齐检查等
  5. 跳转到 C 入口函数:init_tee_runtime()

    boot_init_primary_runtime 是OP-TEE启动过程中初始化主CPU的核心函数,
    文件路径:core\arch\arm\kernel\boot.c

    通过该函数调用init_tee_runtime

主要功能包括:

  1. 线程与版本信息初始化:初始化主线程并打印OP-TEE版本。
  2. 安全警告提示 :若启用不安全配置(CFG_INSECURE)则输出警告。
  3. 硬件特性检测与日志:根据编译选项(如ASLR、NS虚拟化、内存标记等)打印相关状态信息。
  4. 中断与浮点单元初始化:初始化主CPU中断控制器及非安全世界浮点单元。
  5. 运行时环境准备:若未启用NS虚拟化,则解除中断屏蔽并初始化TEE运行时;否则保留中断屏蔽以支持临时堆栈。
  6. 内存管理:若未启用分页机制,则释放临时分配的内存。

整体逻辑围绕系统启动阶段的关键组件初始化展开,确保运行环境就绪。

2.2 C 入口初始化(init_tee_runtime(),core\arch\arm\kernel\boot.c)
  1. 初始化核心子系统:
    • 内存管理:初始化 MMU、页表、安全内存池
    • 中断管理:初始化 GICv2/v3 中断控制器,配置安全中断路由
    • 驱动初始化:初始化 UART(调试输出)、Crypto 引擎、RPMB、eMMC 等安全世界驱动
    • 调度器:初始化事件驱动的微内核调度器
    • TA 管理:初始化 TA 加载器、TA 会话管理器
    • 加密服务:初始化 GlobalPlatform TEE Crypto API
    • 安全存储:初始化 RPMB/OTP/NVM 等安全存储后端
  2. 预加载静态 TA(如果配置了 CFG_TA_STATIC=y)
  3. 初始化 RPC(Remote Procedure Call)机制,用于 TA 调用 tee-supplicant 的 REE 侧服务
  4. 触发 SMC 调用(TEESMC_OPTEE_RETURN_FROM_INIT),主动陷回 EL3,将 CPU 控制权交还给 BL31

第三阶段:BL31 切换到非安全世界(EL3→Non-secure EL2/EL1)

  1. BL31 的 opteed_smc_handler() 函数处理 TEESMC_OPTEE_RETURN_FROM_INIT 请求
  2. BL31 配置非安全世界上下文:
    • SCR_EL3.NS=1:标记后续为非安全世界
    • SPSR_EL3:设置目标异常等级为 Non-secure EL2(如果支持虚拟化)或 Non-secure EL1
    • ELR_EL3:设置为 BL2 传递的 BL33 入口地址
  3. 执行 el3_exit() 汇编函数,触发 ERET 指令
  4. CPU 从 EL3 退出到 Non-secure EL2/EL1,PC 跳转到 BL33(LK/U-Boot/UEFI),后续启动 Linux/Android

第四阶段:运行时 CA-TA 通信(可选,系统启动后)

  1. CA(Android/Linux 应用)调用 libteec 的 TEEC_InitializeContext() 初始化上下文
  2. CA 调用 TEEC_OpenSession() 连接指定 TA(通过 TA UUID)
  3. libteec 通过 ioctl 调用 Linux 内核的 optee.ko 驱动
  4. optee.ko 驱动分配共享内存,触发 SMC 调用
  5. CPU 从 Non-secure EL0 陷入 EL3,BL31 的 opteed 分发器将请求路由到 optee_os
  6. optee_os 的 TA 会话管理器找到对应 TA,加载(如果是动态 TA)并调用 TA 的 TA_OpenSessionEntryPoint()
  7. CA 调用 TEEC_InvokeCommand() 发送具体请求
  8. 类似步骤 3-6,TA 的 TA_InvokeCommandEntryPoint() 处理请求,结果通过共享内存原路返回给 CA
  9. CA 调用 TEEC_CloseSession() 和 TEEC_FinalizeContext() 释放资源
相关推荐
哈哈浩丶2 小时前
ATF (ARM Trusted Firmware) -1:综述
linux·arm开发·驱动开发
小李独爱秋2 小时前
模拟面试:lvs常见的工作模式有哪些?各有什么特点?
linux·运维·面试·职场和发展·操作系统·职场发展·lvs
恋猫de小郭11 小时前
你是不是觉得 R8 很讨厌,但 Android 为什么选择 R8 ?也许你对 R8 还不够了解
android·前端·flutter
Codefengfeng11 小时前
分辨压缩包的真加密与伪加密
linux·运维·网络
暴力求解12 小时前
Linux---进程(五)进程调度
linux·运维·服务器
楼田莉子12 小时前
C++项目:日志&&线程池
linux·c++·学习·visual studio code
wsad053212 小时前
Linux 用户和组管理完整指南(中英文参数对照)
linux·运维·服务器
S-码农12 小时前
Linux进程通讯——共享内存
linux
EmbedLinX13 小时前
嵌入式Linux之U-Boot
linux·服务器·笔记·学习