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(),最終獲取版本相關資訊。