<OPTEE>Trusted Application结构分析

最近又开始和Trusted Zone打起了交道,需要把Linaro开发的开源安全系统optee os移植到实验室的老板子上。不过导师要求我先开发一个应用,在普通环境和安全环境分别有一个程序,称为host与trusted application(简称TA)。让我在这个过程中了解一下这个系统。

  optee os的github地址:https://github.com/OP-TEE/optee_os,一天几个commit,那几个大神真是勤劳。

  不管怎么说,我要先搞清楚这个应用的结构,幸好这个项目还带有一个测试工具集optee test ,这个测试肯定包含host和TA两端,所以可以从这里入手学习。

  host就是一个普通的可执行文件,除了调用了TEE的Api,没什么特别的。

  TA端是OPTEE中运行的程序,有他的要求,下面以一个简单的测试存储的TA——storage为例介绍他的基本结构。

  程序文件

  

  include目录下的头文件  

  

  可以看到所需的文件并不多。简要介绍一下,makefile和sub.mk自不必说,storage.c写的是一些简单的调用TEE存储API的逻辑。

  ta_entry.c比较重要,是TA的入口,里面主要是

  TA_CreateEntryPoint,

  TA_DestroyEntryPoint,

  TA_OpenSessionEntryPoint,

  TA_CloseSessionEntryPoint,

  TA_InvokeCommandEntryPoint

  几个函数,是作用通过名字即可看出,在<tee_ta_api.h>中早有定义,每一个TA都要各自实现这几个函数,不过代码量很小,一般不需要写逻辑,声明出来,处理参数不要报错就行。其中的TA_InvokeCommandEntryPoint主体是一个switch,用传入的命令ID判断和分发。

  Ta_storage.h

复制代码
#ifndef TA_STORAGE_H
#define TA_STORAGE_H
#define TA_STORAGE_UUID { 0xb689f2a7, 0x8adf, 0x477a, \
    { 0x9f, 0x99, 0x32, 0xe9, 0x0c, 0x0a, 0xd0, 0xa2 } }

#define TA_STORAGE_CMD_OPEN           0
#define TA_STORAGE_CMD_CLOSE          1
#define TA_STORAGE_CMD_READ           2
#define TA_STORAGE_CMD_WRITE          3
#define TA_STORAGE_CMD_CREATE         4
#define TA_STORAGE_CMD_SEEK           5
#define TA_STORAGE_CMD_UNLINK         6
#define TA_STORAGE_CMD_RENAME         7
#define TA_STORAGE_CMD_TRUNC          8
#define TA_STORAGE_CMD_ALLOC_ENUM     9
#define TA_STORAGE_CMD_FREE_ENUM      10
#define TA_STORAGE_CMD_RESET_ENUM     11
#define TA_STORAGE_CMD_START_ENUM     12
#define TA_STORAGE_CMD_NEXT_ENUM      13

#endif /*TA_SKELETON_H */
复制代码

  上面定义了该TA的UUID, 以及各个命令的宏。OPTEE通过UUID唯一标识系统里的TA,因此这个UUID不能重复,这里建议的是通过网站ITU-T UUID generator

http://www.itu.int/ITU-T/asn1/uuid.html)来创建唯一的ID,而且生成的数据长度和OPTEE的要求是一致的,只要按格式拆分就可以了。

 

  上述命令在TA_InvokeCommandEntryPoint函数中用switch分发命令调用,处理请求的实现写在storage.c中。

复制代码
TEE_Result TA_InvokeCommandEntryPoint(void *pSessionContext,
                      uint32_t nCommandID, uint32_t nParamTypes,
                      TEE_Param pParams[4])
{
    (void)pSessionContext;

    switch (nCommandID) {
    case TA_STORAGE_CMD_OPEN:
        return ta_storage_cmd_open(nParamTypes, pParams);

    case TA_STORAGE_CMD_CLOSE:
        return ta_storage_cmd_close(nParamTypes, pParams)

        //......
}        
复制代码

  

  user_ta_header_defines.h,TA的头部信息,主要是UUID和一些空间信息。 

复制代码
#ifndef USER_TA_HEADER_DEFINES_H
#define USER_TA_HEADER_DEFINES_H

#include <ta_storage.h>

#define TA_UUID TA_STORAGE_UUID

/*
 * This is important to have TA_FLAG_SINGLE_INSTANCE && !TA_FLAG_MULTI_SESSION
 * as it is used by the ytest
 */
#define TA_FLAGS        (TA_FLAG_USER_MODE | TA_FLAG_EXEC_DDR | \
                TA_FLAG_SINGLE_INSTANCE)
#define TA_STACK_SIZE        (2 * 1024)
#define TA_DATA_SIZE        (32 * 1024)  
复制代码

  

  在optee_os/../kernel tee_ta_Manager.c里面,tee_ta_init_static_ta_session函数中定义TA头部结构体类型,在OPTEE收到Host端的请求,准备初始化会话,加载对应的TA时,会创建一个TA指针,在循环中从内存中定义的start到stop移动,依次比对UUID,从而获取所需的TA头部指针,然后调用tee_ta_load函数,检查签名,加载待运行的TA。

复制代码
static TEE_Result tee_ta_init_static_ta_session(const TEE_UUID *uuid,
                struct tee_ta_session *s)
{
    struct tee_ta_ctx *ctx = NULL;
    ta_static_head_t *ta = NULL;

    DMSG("   Lookup for Static TA %08x-%04x-%04x",
         uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion);

    ta = &__start_ta_head_section;
    while (true) {
        if (ta >= &__stop_ta_head_section)
            return TEE_ERROR_ITEM_NOT_FOUND;
        if (memcmp(&ta->uuid, uuid, sizeof(TEE_UUID)) == 0)
            break;
        ta++;
    }
        //......
}
复制代码

 

  所以新增的TA应该预先把自己的头部结构体放在区间内,经过分析,只要在编译完成后,把.ta文件预先放在rootfs下的lib/optee_armtz/目录内即可,运行时,系统将把这个目录下的TA的头部都加载到内存中以供查找。至于如何打包,最好的方式还是通过修改makefile中Root FS部分内容,这样每次编译完都会把.ta打包入镜像。
  以上就是一个简单的TA项目基本的结构介绍和分析,更详细的代码请自行到github查看。

  optee_os

  optee test

 


原文地址: http://www.cnblogs.com/aureate-sunshine/p/5341967.html

### 解析XML配置文件中 `appSettings`、`startup` 和 `runtime` 节点的作用及参数含义 #### 一、`appSettings` 节点 `appSettings` 是 XML 配置文件中的一个重要部分,主要用于存储应用程序的自定义设置。这些设置通常是一些键值对形式的数据,可以在运行时通过代码访问。 - **作用**: 存储应用程序所需的全局变量或常量数据,例如数据库连接字符串、API 密钥或其他环境特定的信息[^3]。 - **参数含义**: - `<add key="KeyName" value="KeyValue"/>`: 定义一个键值对,其中 `key` 表示名称,`value` 表示对应的值。 ```xml <appSettings> <add key="DatabaseConnectionString" value="Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;" /> <add key="ApiEndpoint" value="https://api.example.com/v1/" /> </appSettings> ``` --- #### 二、`startup` 节点 `startup` 节点主要存在于 ASP.NET Core 应用程序的 JSON 或 XML 配置文件中,用于指定应用启动时的核心组件和服务注册逻辑。 - **作用**: 配置应用程序的入口点和依赖注入容器的服务集合。它决定了哪些中间件会被加载以及如何初始化服务[^4]。 - **参数含义**: - `assembly`: 指定包含 `Startup` 类的程序集名称。 - `main`: 如果需要调用其他方法作为主入口,则可以通过此属性指定。 - `type`: 明确指出 `Startup` 类所在的命名空间及其全名。 ```json { "startup": { "assembly": "MyApplication", "type": "MyApplication.Startup" } } ``` 在某些场景下,可能还会涉及额外的选项,比如调试模式下的行为调整。 --- #### 三、`runtime` 节点 `runtime` 节点一般出现在 `.NET Framework` 或 `.NET Core` 的项目配置文件中,负责管理运行时的行为和兼容性策略。 - **作用**: 控制应用程序在不同版本框架之间的互操作性和优化性能的方式[^1]。 - **参数含义**: - `legacyUnhandledExceptionPolicy`: 启用旧版未处理异常策略(仅适用于 .NET Framework)。当启用时 (`true`),即使线程上抛出了无法捕获的异常也不会终止整个进程;反之则立即崩溃退出。 ```xml <runtime> <legacyUnhandledExceptionPolicy enabled="1"/> </runtime> ``` - `EnableHotKey`: 这是一个假设性的功能开关,在实际开发环境中并不常见。如果是定制化需求实现热键支持的话,这里可能是用来激活相关模块的功能标志位。 - `ClearLogDays`: 设置日志清理周期天数,超过设定时间的日志将会被自动删除以节省磁盘空间资源消耗。 --- ### 示例代码片段展示 以下是综合上述三个节点的一个完整示例: ```xml <configuration> <!-- appSettings --> <appSettings> <add key="DatabaseConnectionString" value="Server=.;Database=testdb;Trusted_Connection=True;" /> <add key="LoggingLevel" value="Information" /> </appSettings> <!-- runtime --> <runtime> <legacyUnhandledExceptionPolicy enabled="1" /> <gcAllowVeryLargeObjects enabled="true" /> </runtime> <!-- startup (JSON format for ASP.NET Core) --> </configuration> ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值