毕设18 - WAMR 内存模型
参考资料:https://wamr.gitbook.io/document/wamr-in-practice/advance-tutorial/memory_tune
有两种可能:
- OPTEE的TA最多只能使用64KB的内存,需要想办法增加TA可使用的内存。
- 调用wasm的时候,错误设置了wasm最大允许使用的内存为64KB。
先在非TA环境中,使用wamr运行wasm,测试结果。
结论:
- 在非TA环境中,wasm 的内存限制由编译时的参数
-Wl,--max-memory=n1决定。 - 而在TA环境中,无论编译时设计 max-memory 为多大,都最多只能分配 64KB 的空间。
所以,下一步验证 TA 的内存。
编写 TA ,发现可以 TEE_Malloc 的最大内存不能超过 TA_DATA_SIZE。
然后修改 watz 的 TA_DATA_SIZE,但是运行 wasm 时仍然报一样的错,os_mmap 最多只有 64KB。
突然意识到,发现 TA_Malloc 和 mmap 本质上可能是不同的。
os_mmap 会调用 tee_map_zi 而不会调用 TA_Malloc 。
编写 TA,测试 tee_map_zi 能映射的最大空间,发现可以达到 12.57MB。
这很奇怪了,watz 分配大约 64KB 就分配失败了。并且 12.57MB 这个参数是哪里来的?
刚刚测试 TA 的 TA_DATA_SIZE = 32KB ,下面换成 4MB 测试一下能映射多少。8.60 MB!!!!
减少了约4MB。
所以,TA_DATA_SIZE 和 tee_map_zi 能映射的空间(再加上系统占用的部分内存)总共约为 13MB !
减小 watz 的 TA_DATA_SIZE 从 12MB 到 4MB:
# optee_wamr 1000000 test-c.aot
内存分配失败,当前已分配: 2766 KB
total: 2766
如果后续还有内存分配不足的情况,需要考虑如何增加 qemu 的可分配内存大小。
那下一步应该是什么。
- 开始写 DID 的合约!在写合约的过程中,遇到需要更新的函数就更新TA。
- 最终逐步重写 Rust 的 WAMR,实现秘钥管理、秘钥传播等,实现智能合约的安全原语。
附录
TEE_Malloc 和 tee_map_zi 的区别
1. 功能定位不同
-
TEE_Malloc:
- 是一个标准的内存分配函数,类似于 C 语言中的
malloc - 用于在 TA (Trusted Application) 的堆上分配内存
- 属于 TEE 内部 API 的一部分,供 TA 开发者使用
- 是一个标准的内存分配函数,类似于 C 语言中的
-
tee_map_zi:
- 是一个底层内存映射函数,用于映射零初始化的内存区域
- “zi” 表示 “Zero Initialized”
- 通过调用系统 PTA (Pseudo Trusted Application) 来实现内存映射
- 是一个扩展 API,主要用于特殊场景
2. 实现机制不同
-
TEE_Malloc:
- 基于传统的堆内存管理,使用
calloc、malloc等底层函数 - 根据不同的 hint 参数选择不同的分配策略
- 可以选择是否进行零初始化(通过
TEE_MALLOC_FILL_ZERO标志) - 可以选择是否使用不共享的内存区域(通过
TEE_MALLOC_NO_SHARE标志)
- 基于传统的堆内存管理,使用
-
tee_map_zi:
- 通过调用
invoke_system_pta函数与系统 PTA 通信 - 使用
PTA_SYSTEM_MAP_ZI命令请求内核映射内存 - 可以创建可共享的内存区域(通过
TEE_MEMORY_ACCESS_ANY_OWNER标志) - 总是返回零初始化的内存
- 通过调用
3. 使用场景不同
-
TEE_Malloc:
- 适用于常规的内存分配需求
- TA 开发者直接使用的 API
- 用于分配相对较小的内存块
- 内存归属于当前 TA 的堆
-
tee_map_zi:
- 用于需要共享内存的场景,特别是在 TA 之间共享内存
- 用于需要映射大块内存的场景
- 在系统级别操作,如临时缓冲区的创建
- 在代码中主要用于创建临时缓冲区,以便在 TA 之间安全地传递数据
4. 内存特性不同
-
TEE_Malloc:
- 分配的内存在 TA 的虚拟地址空间内
- 内存可以是私有的或共享的(取决于 hint 参数)
- 可以使用
TEE_Free释放
-
tee_map_zi:
- 映射的内存可以在 TA 之间共享
- 总是零初始化的
- 需要使用
tee_unmap来解除映射
5. 实际应用示例
从代码中可以看到,tee_map_zi 在 map_tmp_param 函数中被用来创建临时缓冲区,这些缓冲区用于在 TA 之间安全地传递数据,特别是当参数指向 TA 私有内存时。
总结
TEE_Malloc 和 tee_map_zi 的主要区别在于:
TEE_Malloc是一个标准的内存分配函数,用于在 TA 的堆上分配内存tee_map_zi是一个底层内存映射函数,用于映射零初始化的内存区域,特别适用于需要共享内存的场景TEE_Malloc提供更多的内存分配选项,而tee_map_zi专注于创建可共享的零初始化内存tee_map_zi通过系统 PTA 实现,而TEE_Malloc使用传统的堆内存管理
在 OP-TEE 系统中,这两个函数在不同的层次和场景下提供内存管理功能,共同支持安全可靠的可信应用程序执行环境。