测试
optee整体架构如下图
(图片来源:https://zhuanlan.zhihu.com/p/553611279 )
从以下示例代码中(tab:example-hello_world)我们可以看到,在CA(client application)端调用tee client API的流程如下:
- TEEC_InitializeContext()
- TEEC_OpenSession()
- TEEC_InvokeCommand()
- TEEC_CloseSession();
- TEEC_FinalizeContext();
这些API都有一个共同的特点(tab:tee_client_api): 通过ioctl()这一系统调用执行相应指令(open()和close()打开/关闭了/dev/tee0这一tee设备,该设备相关信息仍待研究,先按下不表)。
TEEC_InitializeContext() -> ioctl(fd, TEE_IOC_VERSION, &vers)
TEEC_OpenSession() -> ioctl(ctx->fd, TEE_IOC_OPEN_SESSION, &buf_data)
TEEC_CloseSession() -> ioctl(session->ctx->fd, TEE_IOC_CLOSE_SESSION, &arg)
TEEC_InvokeCommand() -> ioctl(session->ctx->fd, TEE_IOC_INVOKE, &buf_data)
可见TEE_IOC_xxx这些ioctl命令定义了CA希望通过ioctl让TA实现的操作,其定义在optee_client/libteec/include/linux/tee.h中(tab:ioctl_cmd)。那么这些命令在linux kernel中是如何进行处理的呢?
从以下代码中我们可以看到,tee_core.c中定义了tee的file_operations结构体类型变量tee_fops,其中.unlocked_ioctl和.compat_ioctl方法都指向tee_ioctl()函数。(具体的ioctl系统调用流程不在本文讨论的范围内,留待以后进一步分析,参阅 https://zhuanlan.zhihu.com/p/267353577 )
tee_ioctl()函数中,根据用户空间传入的cmd进行相应的处理。以TEE_IOC_VERSION为例,tee_ioctl_version()会被调用。而该函数则会去调用tee_driver_ops结构体类型变量的.get_version函数optee_get_version(),最终获取版本相关信息。