嵌入式开发论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 151|回复: 0

26. OP-TEE驱动篇----libteec和tee_supplicant调用驱动流程和重要结...

[复制链接]

59

主题

64

帖子

255

积分

版主

Rank: 7Rank: 7Rank: 7

积分
255
发表于 2018-11-24 10:52:48 | 显示全部楼层 |阅读模式
驱动挂载完成之后,CA程序通过调用libteec中的接口调用到OP-TEE驱动来穿透到secure world中调用对应的TA程序。OP-TEE的驱动挂载后会在/dev目录下分别创建两个设备接待,分别为/dev/tee0和/dev/teepriv,libteec和tee_supplicant分别对上述两个文件进行相关操作就能够穿透到secure world中。
1. userspace对使用驱动时的执行过程  在userspace层面对文件系统中的文件执行打卡,关闭,读写以及ioctl操作的时候,最终将会穿透到kernel space层面执行具体的操作。而从userspace陷入到kernespace是通过系统调用(systemcall)来实现的(关于syscall的实现请自行查阅资料了解,网上一大堆),进入到kernelspace后会调用相应的驱动获取对应的file_operations变量,该结构体变量中成员存放了对文件进行各种操作的具体函数指针。所以从userspace层面对文件进行操作的时候,其整个过程大致如下图所示:

  调用libteec中按照GP标准定义的API或者tee_supplicant执行具体操作的时候都会经历上图中的流程。所以在后续章节中该流程就不再反复赘述了。
2. OP-TEE驱动中的重要结构体变量  要了解OP-TEE驱动中具体做了哪些操作,首先需要了解在OP-TEE驱动中存在的四个重要的结构体,libteec和tee_supplicanty以及dma操作使用驱动时会使用到这四个结构体,这四个结构体变量会在驱动挂载的时候被注册到系统设备模块或者是该设备的自由结构体中以便被userspace使用,而dma操作的时候会对共享内存进行注册。
2.1 OP-TEE驱动的file_operation结构体变量tee_fops  OP-TEE驱动的file_operation结构体变量定义在linux/drivers/tee/tee_core.c文件中,该变量中包含了OP-TEE驱动文件操作函数指针,其内容如下:

  1. <span class="hljs-keyword">static</span> <span class="hljs-keyword">const</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">file_operations</span> <span class="hljs-title">tee_fops</span> = {</span>
  2.         .owner = THIS_MODULE,        <span class="hljs-comment">//驱动属于哪儿谁</span>
  3.         .open = tee_open,        <span class="hljs-comment">//驱动文件的open操作的具体实现的函数指针</span>
  4.         .release = tee_release,        <span class="hljs-comment">//驱动文件的release操作的具体实现的函数指针</span>
  5.         .unlocked_ioctl = tee_ioctl,        <span class="hljs-comment">//驱动文件的ioctl操作的具体实现的函数指针</span>
  6.         .compat_ioctl = tee_ioctl,         <span class="hljs-comment">//驱动文件的ioctl操作的具体实现的函数指针,用户空间为32位,而内核为64位时使用</span>
  7. };
复制代码


  当在userspace层面调用open, release, ioctl函数操作驱动文件时就会调用到该结构体中的对应函数去执行具体操作。

2.2 OP-TEE驱动中/dev/tee0设备的tee_driver_ops结构体变量optee_ops  当用户调用libteec中的接口的时,操作的就是OP-TEE驱动的/dev/tee0设备,而optee_ops变量中存放的就是针对/dev/tee0设备的具体操作函数的指针,用户调用libteec接口时,首先会调用到tee_fops中的成员函数,tee_fops中的成员函数再会去调用到optee_ops中对应的成员函数来完成对/dev/tee0设备的实际操作。
  optee_ops变量定义在linux/drivers/tee/optee/core.c文件中。其内容如下:
  1. <pre class="has cke_widget_element" data-cke-widget-data="{&quot;lang&quot;:&quot;cpp&quot;,&quot;code&quot;:&quot;static struct tee_driver_ops optee_ops = {\n\t.get_version = optee_get_version,\t//获取OP-TEE版本信息的接口函数\n\t.open = optee_open,  //打开/dev/tee0设备的具体实现,初始化列表和互斥体,返context\n\t.release = optee_release, //释放掉打开的/dev/tee0设备资源,并通知secure world关闭session\n\t.open_session = optee_open_session, //打开session,以便CA于TA进行交互\n\t.close_session = optee_close_session, //关闭已经打开的session,断开CA与TA之间的交互\n\t.invoke_func = optee_invoke_func, \t//通过smc操作发送CA请求到对应TA\n\t.cancel_req = optee_cancel_req, //取消CA端已经发送的smc请求\n};&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"><code class="language-cpp hljs"><span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">tee_driver_ops</span> <span class="hljs-title">optee_ops</span> = {</span>
  2.         .get_version = optee_get_version,        <span class="hljs-comment">//获取OP-TEE版本信息的接口函数</span>
  3.         .open = optee_open,  <span class="hljs-comment">//打开/dev/tee0设备的具体实现,初始化列表和互斥体,返context</span>
  4.         .release = optee_release, <span class="hljs-comment">//释放掉打开的/dev/tee0设备资源,并通知secure world关闭session</span>
  5.         .open_session = optee_open_session, <span class="hljs-comment">//打开session,以便CA于TA进行交互</span>
  6.         .close_session = optee_close_session, <span class="hljs-comment">//关闭已经打开的session,断开CA与TA之间的交互</span>
  7.         .invoke_func = optee_invoke_func,         <span class="hljs-comment">//通过smc操作发送CA请求到对应TA</span>
  8.         .cancel_req = optee_cancel_req, <span class="hljs-comment">//取消CA端已经发送的smc请求</span>
  9. };</code></pre><span class="cke_reset cke_widget_drag_handler_container" style="background:rgba(220,220,220,0.5);background-image:url(https://csdnimg.cn/release/blog_editor_html/release1.3.3/ckeditor/plugins/widget/images/handle.png)"><img class="cke_reset cke_widget_drag_handler" data-cke-widget-drag-handler="1" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" width="15" title="点击并拖拽以移动" height="15" role="presentation"></span>
复制代码



2.3 OP-TEE驱动中/dev/teepriv0设备的tee_driver_ops结构体变量optee_supp_ops
  当tee_supplicant需要执行相关操作时,操作的就是OP-TEE驱动的/dev/teepriv0设备,而optee_supp_ops变量中存放的就是针对/dev/teepriv0设备的具体操作函数的指针,tee_supplicant执行相关操作时,首先会调用到tee_fops中的成员函数,tee_fops中的成员函数再会去调用到optee_supp_ops中对应的成员函数来完成对/dev/teepriv0设备的实际操作。
  optee_supp_ops变量定义在linux/drivers/tee/optee/core.c文件中。其内容如下:

  1. <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">tee_driver_ops</span> <span class="hljs-title">optee_supp_ops</span> = {</span>
  2.         .get_version = optee_get_version,        <span class="hljs-comment">//获取OP-TEE的版本信息</span>
  3.         .open = optee_open,        <span class="hljs-comment">//打开/dev/teepriv0设备的具体实现</span>
  4.         .release = optee_release, <span class="hljs-comment">//释放掉打开的/dev/teepriv0设备,并通知secure world关闭session</span>
  5.         .supp_recv = optee_supp_recv, <span class="hljs-comment">//接收从OP-TEE发送给tee_supplicant的请求</span>
  6.         .supp_send = optee_supp_send,  <span class="hljs-comment">//执行完OP-TEE请求的操作后将结果和数据发送给OP-TEE</span>
  7. };
复制代码



2.4 OP-TEE驱动中共享驱动缓存操作的dma_buf_ops结构体变量tee_shm_dma_buf_ops
  OP-TEE驱动也支持其他设备访问OP-TEE驱动的共享缓存,该部分的功能当前并不算太完全,有一些功能尚未实现。该变量定义在linux/drivers/tee/tee_shm.c文件中,当需要被分配dma缓存时就会调用到该变量中对应的函数。其内容如下:
  1. <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">dma_buf_ops</span> <span class="hljs-title">tee_shm_dma_buf_ops</span> = {</span>
  2.         .map_dma_buf = tee_shm_op_map_dma_buf,        <span class="hljs-comment">//暂未实现</span>
  3.         .unmap_dma_buf = tee_shm_op_unmap_dma_buf,        <span class="hljs-comment">//暂未实现</span>
  4.         .release = tee_shm_op_release,        <span class="hljs-comment">//释放掉指定的共享内存</span>
  5.         .kmap_atomic = tee_shm_op_kmap_atomic, <span class="hljs-comment">//暂未实现</span>
  6.         .kmap = tee_shm_op_kmap,        <span class="hljs-comment">//暂未实现</span>
  7.         .mmap = tee_shm_op_mmap,         <span class="hljs-comment">//dma共享内存进行地址映射</span>
  8. };
复制代码


NOTE:libteec中接口的执行和tee_supplicant功能的执行都会用上述四个结构体变量中的两个或者多个。而从libteec和tee_supplicant到驱动的kernelspace层面的过程都如第一小节大致相同,所以在后续章节中将不会对userspace如何到kernel space的过程进行赘述。










回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|TEE and Virtualization

GMT+8, 2019-5-25 18:53 , Processed in 0.083572 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表