本文转载自:https://blog.csdn.net/hovan/article/details/42520879

从trust zone之我见知道,支持trustzone的芯片会跑在两个世界。

普通世界、安全世界,对应高通这边是HLOS,QSEE。

如下图:

如下是HLOS与QSEE的软件架构图

HLOS这两分为kernel层,user层。user层的通过qseecom提供的API起动trustzone那边的app。

qseecom driver 除了提供API,还调用scm函数做世界切换。

scm driver 那边接到qseecom的调用后,会把HLOS相关数据(包括指令参数)放入指它buffer,然后执行scm调用。

qsapp通过qsee提供的api接受来自HLOS那边的请求,并把执行结果返回HLOS。

qsee除了提供API,还与从monitor把来自HLOS的数据传给qsapp,然后把qsapp的数据返回给HLOS。

monitor就不用说了,切换世界用的,还处理shared buffer的内容。

是大概的架构图,细节比较复杂,没有开元。

下面通过一个简单的qseecom_security_test代码来说明整个调用流程。

如下图:

qseecom_security_test.c

 
  1. int main( int argc, char *argv[] )

  2. {

  3. ....

  4. /* Initialize the global/statics to zero */

  5. memset( g_qseeCommHandles, 0, sizeof(g_qseeCommHandles) );

  6. memset( g_xors, 0, sizeof(g_xors) );

先初始化全局变量g_qseeCommHandles

 
  1. for( j = 0; j < NUM_CLIENTS; j++ ) {

  2. /* Initialize the barriers to ensure that commands aren't sent before the listeners

  3. * have been started. Otherwise, errors will be generated.

  4. */

  5. ret = sem_init( &barrier[j], 0, 0 );//初始化一个信号量

  6. if( ret ) {

  7. LOGD( "barrier init failed %i, %i", ret, errno );

  8. g_err = -1;

  9. break;

  10. }

  11. ret = pthread_create( &threads[j], NULL, &test_thread, (void*)j );//创建test_thread线程

  12. }

初始化一个barrier信号变量,用于线程创建时的同步

然后调用pthread_create()函数创建test_thread线程,该线程将会起动QSApp。

 
  1. void *test_thread( void* threadid )

  2. {

  3. ...

  4. do {

  5. .....

  6. LOGD( "T%#X: Starting QSApp...", (uint32_t)threadid );

  7. ret = QSEECom_start_app( &g_qseeCommHandles[tid][0], "/firmware/image",//起动名为securitytest的QSApp

  8. "securitytest", sizeof(qseecom_req_res_t)*2 );

  9. LOGD( "T%#X: Started QSApp...", (uint32_t)threadid );

  10. CHECK_RETURN( ret, __LINE__ );

跟着来到test_thread线程

调用QSEECom_start_app()函数起动QSApp。

这个函数在kernel实现 如下:

qseecom.c

 
  1. static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)

  2. {

  3. ...

  4. /* Get the handle of the shared fd */

  5. ihandle = ion_import_dma_buf(qseecom.ion_clnt,

  6. load_img_req.ifd_data_fd);

  7. ...

  8. /* SCM_CALL to load the app and get the app_id back */

  9. ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &load_req,

  10. sizeof(struct qseecom_load_app_ireq),

  11. &resp, sizeof(resp));

Get shared buf fd,用于与安全世界通信

调用scm_call()来陷入安全世界。

scm_call()实现如下:

arch/arm/mach-msm/scm.c

 
  1. int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,

  2. void *resp_buf, size_t resp_len)

  3. {

  4. ...

  5. ret = scm_call_common(svc_id, cmd_id, cmd_buf, cmd_len, resp_buf,

  6. resp_len, cmd, len);

  7. kfree(cmd);

  8. return ret;

  9. }

scm_call_common的实现如下:

 
  1. static int scm_call_common(u32 svc_id, u32 cmd_id, const void *cmd_buf,

  2. size_t cmd_len, void *resp_buf, size_t resp_len,

  3. struct scm_command *scm_buf,

  4. size_t scm_buf_length)

  5. {

  6. ....

  7. mutex_lock(&scm_lock);

  8. ret = __scm_call(scm_buf);//调用

  9. mutex_unlock(&scm_lock);

  10. if (ret)

  11. return ret;

  12. rsp = scm_command_to_response(scm_buf);

  13. start = (unsigned long)rsp;

  14. do {

  15. scm_inv_range(start, start + sizeof(*rsp));

  16. } while (!rsp->is_complete);

  17. end = (unsigned long)scm_get_response_buffer(rsp) + resp_len;

  18. scm_inv_range(start, end);

  19. if (resp_buf)

  20. memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);

  21. return ret;

  22. }

调用__scm_call()陷入安全世界,回来后调用scm_get_response_buffer()获取安全世界返回的信息供上面QSApp client用

__scm_call实现如下:

 
  1. static int __scm_call(const struct scm_command *cmd)

  2. {

  3. ...

  4. ret = smc(cmd_addr);

  5. ...

  6. return ret;

  7. }

smc实现如下:

 
  1. static u32 smc(u32 cmd_addr)

  2. {

  3. int context_id;

  4. register u32 r0 asm("r0") = 1;

  5. register u32 r1 asm("r1") = (u32)&context_id;

  6. register u32 r2 asm("r2") = cmd_addr;

  7. do {

  8. asm volatile(

  9. __asmeq("%0", "r0")

  10. __asmeq("%1", "r0")

  11. __asmeq("%2", "r1")

  12. __asmeq("%3", "r2")

  13. #ifdef REQUIRES_SEC

  14. ".arch_extension sec\n"

  15. #endif

  16. "smc #0 @ switch to secure world\n"

  17. : "=r" (r0)

  18. : "r" (r0), "r" (r1), "r" (r2)

  19. : "r3");

  20. } while (r0 == SCM_INTERRUPTED);

  21. return r0;

  22. }

是一段汇编程序,好吧,安全世界的QSApp已经运行起来了,当QSApp完成相应服务后就会返回数据。这个函数就会返回。

Starting QSApp已经完成,下面就注册listener,这个listener用于监听QSApp那边的请求。因为有时QSApp也需要HLOS这边做一些事。

实现如下:

 
  1. void *listener_thread( void* threadid )

  2. {

  3. ....

  4. do {

  5. ...

  6. /* Register as a listener with the QSApp */

  7. LOGD( "L%#X: Registering as listener with QSApp...", (uint32_t)threadid );

  8. ret = QSEECom_register_listener( &g_qseeCommHandles[parent_tid][tid], GET_LSTNR_SVC_ID(parent_tid, tid),

  9. sizeof(qseecom_req_res_t), 0 );

  10. ....

  11. for( ;; ) {

  12. /* Wait for request from the QSApp */

  13. ret = QSEECom_receive_req( g_qseeCommHandles[parent_tid][tid], req_res, sizeof(qseecom_req_res_t) );

  14. if( ret ) break;

  15. ....

  16. /* Send the response to the QSApp */

  17. ret = QSEECom_send_resp( g_qseeCommHandles[parent_tid][tid], req_res, sizeof(qseecom_req_res_t) );

  18. CHECK_RETURN( ret, __LINE__ );

  19. }

  20. } while( 0 );

  21. ...

  22. }

这个函数比较长,简化一下,分步来看

首先调用QSEECom_register_listener()函数来注册监听,告诉QSApp,我可以接收你的申请。

再次看到for循环没有,这就是一直等待QSApp那边的消息,一但有消息QSEECom_reveive_req就返回,这边处理完之后。

再调用qSEECom_send_resp()发送response给QSApp。

无论是起动QSApp,还是注册listener都是线程中执行,一但所有线程都退出后就会调用QSEECom_shutdown_app()函数停止QSApp。

整个过程执行完毕。如下:

 
  1. void *test_thread( void* threadid )

  2. {

  3. ...

  4. if ( g_qseeCommHandles[tid][0] != NULL ) {

  5. QSEECom_shutdown_app( &g_qseeCommHandles[tid][0] );

  6. }

  7. } while( 0 );

  8. pthread_exit( NULL );

  9. return NULL;

  10. }

注:QSEECom _XX开头的函数都在kernel中的qseecom.c里实现,scm系统调用,都在scm.c中实现。

HLOS user层把握QSEEComAPI.h文件

HLOS kernel层把握qseecom.c 和 scm.c两文件

谢谢

--------------------- 本文来自 hovan-邓永坚 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/hovan/article/details/42674055?utm_source=copy

高通msm8916平台QSEE之trustzone分析

从硬件背景上看TZ是在ARMv6的架构上产生的,在ARMv7上重新设计了,TZ的目的是提供一个软硬件都安全的环境,安全的环境是单独的运行在一个硬件空间,和非安全的进行了硬件上的隔离。

QSEE主要负责加载APP,以及安全APP的堆栈管理,提供安全的API接口,安全的字符操作和LOG功能

QSAPPS是高通开发的APP,运行在QSEE之上

用户空间通过加载并调用QSEEAPP来是实现一些安全数据或敏感操作的加密

QSEEComAPIlib是暴露给HLOS的API,HLOS客户端和监听端利用QSEEComdriver通过这些API来和QSEE进行数据的收和发。

QSEEComclient是需要调用QSEECom_start_app来得到一个句柄指向QSEECom字符设备,并且可以用这个句柄来进行数据的首发

QSEEComlistener需要用QSEECom_register_listener来注册,可以注册多个listener,每个listener所在的线程将会被挂起,直到接收到包含到该listener的信息。

QSEEComdriver是一个字符型设备,通过IOCTL来和QSEECom进行通讯,这些IOCTL都应该被QSEEComAPI进行调用

因为qsee不开源 tz部分只能看到少量符号

所以主要从用户和开发角度观察tz

开发需要开发相应的qsapp来实现安全的一些数据操作

用户态中需要加载相应的qsapp,并且利用qsapplib提供的API来和qsapp进行通讯

而qsapp如何与qsee进行通讯的呢

qsapp则调用scm来将数据保存到安全空间

为什么tz能实现安全呢

从硬件上 就区分了两个世界,安全世界用一根总线,非安全世界用一根总线

非安全世界的操作无法访问到安全世界

必须通过qsee中的scm调用来访问

而用户操作只能访问qsapp

所以达到了安全保护的作用

高通msm8916平台QSEE之trustzone分析

转自http://www.it610.com/article/5292101.htm

转载于:https://www.cnblogs.com/zzb-Dream-90Time/p/9999794.html

简谈高通Trustzone的实现【转】相关推荐

  1. 简谈高通Trustzone的实现

    从trust zone之我见知道,支持trustzone的芯片会跑在两个世界. 普通世界.安全世界,对应高通这边是HLOS,QSEE. 如下图: 如下是HLOS与QSEE的软件架构图 HLOS这两分为 ...

  2. 浅谈高通的MSM7230-评各大厂商

    浅谈高通的MSM7230并解释U8800的FM 有些同学问到为什么U8800没有FM: 有些问到为什么CPU是800MHz而不是1G: 有人问MSM7230比OMAP 3610/3630好还是差:答案 ...

  3. 高通骁龙 8155 到底有什么魔力?

    高通骁龙8155采用安卓系统,兼容性更好,APP的数量也就相当多,硬件方面,这颗芯片最高支持3个4K屏或4个2K屏,4个麦克风6颗摄像头,还有WiFi6.5G.蓝牙5.0等功能,所以现在很多车有3块大 ...

  4. 高通CEO谈中国5G:原以为会晚个5-10年,结果第一年就推出了

    近日,高通CEO莫伦科夫接受媒体采访时感叹,中国在5G部署方面的进展非常惊人. 莫伦科夫表示,我认为中国正在加速5G的部署,预计今年年底前,中国会部署大约10万个5G基站,非常了不起. 莫伦科夫称,以 ...

  5. 高通android逆向分析,浅谈Android高通(Qualcomm)和联发科(MTK)平台

    一款CPU好不好是要从多个方面考虑的,并不是说简简单单看一个主频.几个核心数就完了,更重要的是它的综合实力到底有多强,这里面当然也会牵扯到价格问题,性能相似当然是便宜的获胜,这是毋庸置疑的. 事实上, ...

  6. 彻底与高通谈崩?苹果被爆计划自研5G调制解调器

    前不久,美国第四大运营商Sprint起诉第二大运营商AT\u0026amp;T,声称后者使用虚假5G标签误导消费者,其在部分手机中信号标识的5GE实际只是4G网络的改进版,仍属于4G网络技术,足以见得 ...

  7. 蓝牙 aptx android,没错,现在蓝牙耳机可以开始谈音质了 高通aptX HD SONY LDAC

    高通aptX HD Qualcomm aptX HD Apt-X是一种基于子带ADPCM(SB-ADPCM)技术的数字音频压缩算法. aptXHD音频确保蓝牙设备提供高清晰度(HD)音频.通过音频传输 ...

  8. (1)RIL简析(高通)——RIL如何启动及初始化

    Android设置了RIL层,是上层framework与Modem沟通的桥梁.高通使用qcril作为其vendor-RIL,与modem之间使用QMI机制通讯. 分3篇分析下面的问题: RIL如何启动 ...

  9. 浅谈Android高通(Qualcomm)和联发科(MTK)平台

    一款CPU好不好是要从多个方面考虑的,并不是说简简单单看一个主频.几个核心数就完了,更重要的是它的综合实力到底有多强,这里面当然也会牵扯到价格问题,性能相似当然是便宜的获胜,这是毋庸置疑的. 事实上, ...

最新文章

  1. jQuery对下拉框、单选框、多选框的处理
  2. 【scala】 scala 条件控制 和异常处理(二)
  3. mapreduce框架详解
  4. for-each 循环原理
  5. cisco 交换机vlan-trunk的配置详解及应用实例:
  6. [js] 使用js实现一个图片剪裁的功能
  7. python软件下载3版本-python
  8. php底部加载更多,关于vue底部加载更多的代码
  9. -分类数组-创建//修改(添加/改变原有/合并/删除)分类数组(categorical)
  10. react - next.js 引用本地图片和css文件
  11. spring mvc 实现websocket(服务器主动消息推送)
  12. OpenGL图形渲染管线(Pipeline)学习
  13. 光环效应引发的认知误区
  14. C语言编程 5.7 从键盘中输入一个英文字母,如果它是大写则转化为小写。如果它是小写则转化为大写,并将其ASCll码显示到屏幕上。
  15. 用计算机打根号怎么打,根号在电脑上怎么打出来啊?
  16. Mybatis中,SQLSessionFactoryBuilder使用build方法时做了哪些事?
  17. confluence 删除_Confluence 清理已经删除的页面(完全删除)
  18. samba服务器讲解
  19. Elasticsearch学习--索引快速检索
  20. svn plugin for VS —— AnkhSvn-2.6.12735下载地址

热门文章

  1. Redis基础 -- 地理坐标类型 Redis GEO 和 Redis GEO的常用命令(含GEOHASH编码说明)
  2. java web 酒店管理系统_GitHub - inkss/hotelbook-JavaWeb: 酒店管理系统-JavaWeb期末项目。...
  3. ACL’21 | 对话系统也要进军多模态了!
  4. 利用定时器实现PWM波对Zigbee(CC2530)上LED亮度进行强弱调整
  5. 超市收银系统无法连接服务器,超市收银系统常见问题介绍与回答
  6. 2021年幼儿园教师招聘:中班绘画活动《吹画梅花》
  7. 开发者必读:2022年移动应用技术趋势白皮书
  8. 项目经理如何面对困境
  9. 【C++习题笔记】谭浩强C++程序设计(第三版)第七章
  10. NB-IOT 模块 MT2625 使用总结