毕设18 - WAMR 内存模型

| 笔记 | 2216 | 6分钟 | 毕设WAMR

参考资料:https://wamr.gitbook.io/document/wamr-in-practice/advance-tutorial/memory_tune

有两种可能:

  1. OPTEE的TA最多只能使用64KB的内存,需要想办法增加TA可使用的内存。
  2. 调用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_SIZEtee_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_Malloctee_map_zi 的区别

1. 功能定位不同

  • TEE_Malloc

    • 是一个标准的内存分配函数,类似于 C 语言中的 malloc
    • 用于在 TA (Trusted Application) 的堆上分配内存
    • 属于 TEE 内部 API 的一部分,供 TA 开发者使用
  • tee_map_zi

    • 是一个底层内存映射函数,用于映射零初始化的内存区域
    • “zi” 表示 “Zero Initialized”
    • 通过调用系统 PTA (Pseudo Trusted Application) 来实现内存映射
    • 是一个扩展 API,主要用于特殊场景

2. 实现机制不同

  • TEE_Malloc

    • 基于传统的堆内存管理,使用 callocmalloc 等底层函数
    • 根据不同的 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_zimap_tmp_param 函数中被用来创建临时缓冲区,这些缓冲区用于在 TA 之间安全地传递数据,特别是当参数指向 TA 私有内存时。

总结

TEE_Malloctee_map_zi 的主要区别在于:

  1. TEE_Malloc 是一个标准的内存分配函数,用于在 TA 的堆上分配内存
  2. tee_map_zi 是一个底层内存映射函数,用于映射零初始化的内存区域,特别适用于需要共享内存的场景
  3. TEE_Malloc 提供更多的内存分配选项,而 tee_map_zi 专注于创建可共享的零初始化内存
  4. tee_map_zi 通过系统 PTA 实现,而 TEE_Malloc 使用传统的堆内存管理

在 OP-TEE 系统中,这两个函数在不同的层次和场景下提供内存管理功能,共同支持安全可靠的可信应用程序执行环境。