📺 B站视频讲解(Bilibili):https://www.bilibili.com/video/BV1k1C9BYEAB/
📘 《Yocto项目实战教程》京东购买链接:Yocto项目实战教程
Jetson OP-TEE 源代码结构全景解析:从目录树到 Hello TA 的工程路径
适用对象:刚接触 OP-TEE 的初学者、希望在 Jetson 上做安全能力落地的中级工程师。
本文目标:围绕 Jetson 平台的
nvidia-jetson-optee-source目录树,讲清楚 每一类代码属于哪个世界(Normal/Secure/Monitor)、在系统里扮演什么角色、最终如何被构建与部署(烧录/安装),并给出 Hello TA 的最小实践路线,帮助读者从“看懂结构”走到“能动手验证”。
1. 先立住最重要的认知:OP-TEE 是“多工程 + 多世界”的组合体
很多初学者第一次接触 OP-TEE,会误以为它是一个单一项目:make 一下就能跑。
在 Jetson 上,OP-TEE 更接近一种“系统能力”,它分布在多个世界与多个组件中:
- Normal World(Linux 世界):负责业务功能与控制流,攻击面大,默认不可信。
- Secure World(OP-TEE 世界):负责密钥与安全逻辑执行,攻击面小,权限更高。
- Monitor / Boot World(切换与信任链):负责世界切换与启动阶段的信任传递。
因此,阅读源代码的第一步不是看函数,而是问:
这段代码属于哪个 World?它的输入从哪里来?输出回到哪里?它最后会被放进哪个镜像或分区?
把这个问题想清楚,目录树就会“自带结构图”。
2. 目录树总览:一眼看懂各目录的“世界归属”与职责
你当前的目录结构如下:
nvidia-jetson-optee-source/
├── nvcommon_build.sh
├── optee
│ ├── atf_and_optee_README.txt
│ ├── optee_client
│ ├── optee_os
│ ├── optee_test
│ ├── samples
│ └── tegra234-optee.dts
└── optee_src_build.sh
2.1 世界归属一览表

| 目录/文件 | 归属 World | 作用定位(一句话) | 典型产物(输出) |
|---|---|---|---|
optee/optee_os | Secure World | OP-TEE OS:Secure World 的“安全内核” | tee.elf、*.bin、内嵌 TA 等 |
optee/samples | Secure World | Jetson/NVIDIA 的示例 TA 与安全服务 | TA 二进制(按 UUID 组织) |
optee/optee_client | Normal World | Client API + tee-supplicant:Linux 侧访问入口 | libteec.so、tee-supplicant |
optee/optee_test | Normal+Secure | 官方测试套件:验证 CA↔TA 通路 | host 测试程序 + 测试 TA |
optee/tegra234-optee.dts | 系统描述 | Jetson 平台 OP-TEE 的设备树契约 | DT 节点(内存/tee reserved/入口) |
nvcommon_build.sh / optee_src_build.sh | 构建工具 | 统一构建脚本:把多个工程串起来 | 可直接部署的产物集合 |
初学者建议:先把这张表背下来(或打印出来)。之后你在任何 log 里看到
libteec、tee-supplicant、tee.elf、TA UUID,都能立刻定位到它在系统中的位置。
3. OP-TEE 的“请求链路”是理解源码结构的主线
不管你最终做磁盘加密、密钥派生还是可信存储,OP-TEE 的交互主线都类似:
CA(Linux 用户态)
↓ libteec(TEEC_* API)
TEE Driver(Linux 内核 /dev/tee*)
↓ SMC(Secure Monitor Call)
ATF / Secure Monitor(世界切换)
↓
OP-TEE OS(Secure World)
↓
TA(Trusted Application 执行安全逻辑)
↑
返回结果(不返回密钥,只返回“结果/句柄/证明”)
3.1 为什么这条主线很重要?
- 目录树的每一个子工程,几乎都能在这条链路上找到“自己的位置”。
- 初学者只要掌握“链路”,就能避免把时间浪费在不该动的地方(例如:一上来就改 OP-TEE OS 核心)。
- 中级工程师可以基于链路定位性能瓶颈、权限问题、部署问题。
4. optee_os/:Secure World 的核心——OP-TEE OS 应该怎么看
optee_os 是 Secure World 的核心,它不是“库”,而是一个运行环境。它负责:
- Secure World 的线程、调度与系统调用
- 内存隔离与共享内存管理
- TA 的装载、验证、生命周期管理
- 平台适配(Jetson/tegra234)与安全服务接口
4.1 初学者看 optee_os 的正确姿势
初学者建议遵循“从边界到内部”的阅读顺序:
- 先看它输出什么产物(
tee.elf、*.bin、embedded TA) - 再看它如何与外部交互(SMC、RPC、shared memory)
- 最后才看内部实现细节(core、mm、ta loader)
这样不会被“安全内核”级别的复杂度劝退。
4.2 optee_os 内的几个关键子目录(概念级)
下面以“你需要知道它负责什么”为主,不要求初学者立刻深入实现。
| 子目录 | 你应当理解的职责 | 读到什么程度算合格 |
|---|---|---|
core/ | Secure World 核心:线程、调度、SMC 入口、内存管理 | 能说清“请求如何进入 OP-TEE OS” |
ta/ | TA 框架、示例 TA 模板、用户 TA 支持 | 能解释“TA 为什么不是 Linux 程序” |
ldelf/ | TA 装载相关的组件(概念上类似加载器) | 知道它存在即可 |
lib/ | OP-TEE OS 内部库 | 不必深入 |
keys/ | 与密钥相关的构建/示例内容(视平台配置) | 知道“密钥不在 Linux” |
中级工程师建议:在你要做“自研 TA + 受控密钥使用”时,再深入
core/与ta/的生命周期与权限模型。
5. optee_client/:Normal World 的入口——libteec 与 tee-supplicant
optee_client 是 Linux 用户态访问 OP-TEE 的标准路径,通常包含:
libteec:Client API(TEEC_InitializeContext、TEEC_OpenSession、TEEC_InvokeCommand…)tee-supplicant:辅助进程,负责处理 OP-TEE OS 发起的 RPC(如访问文件系统、RPMB、或其他需要 Normal World 协助的事情)
5.1 初学者为什么应当从这里入手
- 你能直接
printf,能看到返回值 - 你能快速验证“OP-TEE 是否跑起来”
- 你不会因为改错 Secure World 导致板子起不来
5.2 一个“CA 最小调用骨架”应当理解哪些点
初学者无需背 API 参数细节,但应理解以下逻辑:
| 概念 | 作用 | 常见误区 |
|---|---|---|
| Context | 与 TEE 子系统的连接上下文 | 以为它等同于 session |
| Session | 与某个 TA 的会话 | 以为 session 就是进程 |
| UUID | 标识 TA | 以为 UUID 随便写 |
| Operation | 入参/出参描述 | 混淆临时内存与共享内存 |
| Command ID | TA 内部命令分发 | 以为每个 TA 只有一个功能 |
6. samples/:NVIDIA/Jetson 的示例 TA——用“功能分类”理解它
你看到的 samples/ 往往代表“可落地的安全服务”,例如:
luks-srv:为磁盘加密提供安全服务(常与 EKB/派生密钥结合)hwkey-agent:硬件密钥代理(把设备唯一性引入密钥体系)pkcs11-sample:PKCS#11 风格接口示例(更贴近应用层使用)
6.1 初学者如何利用 samples 提升实践兴趣
建议采用“先跑起来 → 再改一行 → 再加一个命令”的渐进策略。
- 第一步:编译并部署现有 sample,确认 CA 能调用 TA。
- 第二步:修改 TA 的一个返回字符串或版本号,验证更改生效。
- 第三步:新增一个 Command ID(例如
CMD_HELLO_V2),体会 session + command 的模型。
这比让初学者一上来写完整 TA 更有效,因为它能在 1~2 小时内获得正反馈。
7. optee_test/:用它做“通路验收”和“回归测试”
optee_test 的价值在于“验证链路”,尤其当你做了以下事情后:
- 更换了 OP-TEE OS 版本
- 修改了设备树 reserved memory
- 调整了 TA 的部署方式
- 迁移到 Yocto/定制 rootfs
7.1 初学者的使用建议
把 optee_test 当成“诊断工具”,而不是“学习项目”。
- 能跑通测试 → 证明你的链路 OK
- 跑不通 → 回到本文第 3 节的请求链路逐段定位
8. tegra234-optee.dts:设备树是“系统契约”,不是 Linux 配置
Jetson(tegra234)平台上,OP-TEE 的设备树往往承担以下信息:
- Secure reserved memory:Secure World 使用的受保护内存
- OP-TEE 节点:让 Linux TEE 驱动识别 TEE 的存在与入口
- 共享内存相关描述(视平台方案)
8.1 初学者最常见的坑
- 把 OP-TEE 的 reserved memory 当成 CMA 或普通内存
- 修改 DTS 后忘了同步到最终使用的 DTB/boot config
- 只改了 Linux 侧,却没考虑 Secure World 对内存布局的依赖
实战建议:第一次实践尽量不改 DTS,先跑通
optee_test与 hello sample。
9. 构建与部署:这些代码最终“去到哪里”
为了帮助读者把“源代码 → 设备上的东西”对齐,建议用“产物去向表”统一解释:
9.1 产物去向表(烧录/安装视角)
| 组件 | 产物(示例) | 最终位置(概念) | 由谁加载/使用 |
|---|---|---|---|
| OP-TEE OS | tee.elf / *.bin | Secure OS 镜像/分区 | ATF/boot chain |
| TA(sample/自研) | *.ta(按 UUID) | Secure 可访问存储或内嵌 | OP-TEE OS |
| libteec | libteec.so | rootfs /usr/lib | CA |
| tee-supplicant | tee-supplicant | rootfs /usr/sbin | OP-TEE OS 的 RPC |
| optee_test host | xtest 等 | rootfs /usr/bin | 测试/验收 |
注:不同 Jetson BSP/发行方式(Ubuntu L4T / Yocto / 自研镜像)在“分区名/路径”上会不同,但“去向逻辑”一致。
10. Hello OP-TEE:最小实践路线(适合初学者)
本节给出“低风险、高反馈”的 Hello TA 实践路线。
10.1 目标
- 在 Linux 上运行一个 CA
- CA 通过 libteec 调用 Secure World 的 TA
- TA 返回一个可见结果(字符串/整数)
10.2 推荐的实践路径(不碰 fuse,不碰 secure boot)
步骤 A:确认运行环境具备 OP-TEE 通路
- 确认系统已包含
tee-supplicant、libteec - 能看到
/dev/tee*(具体节点名依 BSP 方案不同)
步骤 B:先跑 optee_test 或 sample
- 先跑官方的测试或 sample
- 成功后再进入下一步
步骤 C:改一个最小 TA(基于 sample 模板)
- 改返回字符串(比如
Hello from TA→Hello from Jetson TA) - 重新编译部署
步骤 D:写一个最小 CA
- 使用
TEEC_OpenSession连接 TA UUID - 使用
TEEC_InvokeCommand调用CMD_HELLO - 打印返回值
10.3 Hello 的“链路定位口诀”(遇到问题时)
CA 不通 → 看 libteec
libteec 失败 → 看 tee-supplicant 是否运行
驱动失败 → 看 /dev/tee* 与内核配置
SMC 不通 → 看 ATF/启动链(中级阶段再动)
TA 找不到 → 看 UUID 与部署路径
11. 中级工程师:如何在 Jetson 上“进一步运用”这些代码
当你完成 Hello TA 后,接下来往往会进入“工程落地”阶段。建议按优先级推进:
11.1 运用方向一:把安全能力包装成“可被业务调用的服务”
- 以 TA 形式提供服务
- 在 CA/daemon 侧提供统一接口给业务层
- 关键原则:业务层永远拿不到密钥,只能拿到“结果/证明”
11.2 运用方向二:把设备唯一性引入密钥体系(与 EKB/派生结合)
- 核心思想:EKB/硬件派生密钥让密钥与设备绑定
- 工程收益:镜像被拷走也难以在别的设备上使用
11.3 运用方向三:把“验收”工程化
- 把
optee_test/ 自研健康检查纳入 CI 或产线测试 - 在 OTA/升级后跑一轮关键用例
12. 常见问题与经验提炼
12.1 初学者最容易踩的坑(Top 6)
- 一上来改
optee_os/core,导致系统不可用 - UUID 不一致:CA 调 TA 找不到
- 误把 TA 当普通 Linux 程序
- 忽略
tee-supplicant,导致 RPC 失败 - 改了 DTS 但没有应用到最终 DTB
- 忘记用测试套件做回归
12.2 工程化建议
- 学习路线:结构 → 路径 → Hello → 服务化 → 密钥体系/量产
- 文档习惯:把“链路图 + 产物去向表”放在项目 README 顶部
13. 总结:从“看懂目录树”到“能稳定落地 OP-TEE”
本文围绕 Jetson 的 nvidia-jetson-optee-source 目录结构,给出了一条清晰的学习路径:
- 用 World 划分定位每个工程
- 以请求链路作为理解主线
- 通过“产物去向表”理解构建与部署
- 用 Hello TA 建立最小实践闭环
- 中级阶段再逐步进入密钥体系与工程化验收
如果你已经能跑通 Hello,并能说清楚:
optee_os属于 Secure Worldoptee_client属于 Normal World- CA 通过
libteec调用 TA - 密钥不在 Linux
那么你就已经具备继续深入(EKB、可信存储、磁盘加密服务化)的基础。
14. 关键问答(用于巩固)
Q1:为什么初学者不建议直接改 optee_os/core?
A:因为它属于 Secure World 核心,修改风险高,错误可能导致系统无法完成启动或 OP-TEE 不可用。更好的入手点是 samples/ 的 TA 与 Normal World 的 CA,反馈快且风险低。
Q2:Hello TA 的最小闭环是什么?
A:CA 能通过 libteec 打开 session 并 invoke command;TA 在 Secure World 执行并返回可见结果;整个链路可被 optee_test 或 sample 复现与回归。
📺 B站视频讲解(Bilibili):https://www.bilibili.com/video/BV1k1C9BYEAB/
📘 《Yocto项目实战教程》京东购买链接:Yocto项目实战教程
6万+

被折叠的 条评论
为什么被折叠?



