简谈高通Trustzone的实现
从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
- int main( int argc, char *argv[] ){.... /* Initialize the global/statics to zero */ memset( g_qseeCommHandles, 0, sizeof(g_qseeCommHandles) ); memset( g_xors, 0, sizeof(g_xors) );
先初始化全局变量g_qseeCommHandles
- for( j = 0; j < NUM_CLIENTS; j++ ) { /* Initialize the barriers to ensure that commands aren't sent before the listeners * have been started. Otherwise, errors will be generated. */ ret = sem_init( &barrier[j], 0, 0 );//初始化一个信号量 if( ret ) { LOGD( "barrier init failed %i, %i", ret, errno ); g_err = -1; break; } ret = pthread_create( &threads[j], NULL, &test_thread, (void*)j );//创建test_thread线程 }
初始化一个barrier信号变量,用于线程创建时的同步
然后调用pthread_create()函数创建test_thread线程,该线程将会起动QSApp。
- void *test_thread( void* threadid ){ ... do {..... LOGD( "T%#X: Starting QSApp...", (uint32_t)threadid ); ret = QSEECom_start_app( &g_qseeCommHandles[tid][0], "/firmware/image",//起动名为securitytest的QSApp "securitytest", sizeof(qseecom_req_res_t)*2 ); LOGD( "T%#X: Started QSApp...", (uint32_t)threadid ); CHECK_RETURN( ret, __LINE__ );
跟着来到test_thread线程
调用QSEECom_start_app()函数起动QSApp。
这个函数在kernel实现 如下:
qseecom.c
- static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp){.../* Get the handle of the shared fd */ ihandle = ion_import_dma_buf(qseecom.ion_clnt, load_img_req.ifd_data_fd);.../* SCM_CALL to load the app and get the app_id back */ ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &load_req, sizeof(struct qseecom_load_app_ireq), &resp, sizeof(resp));
Get shared buf fd,用于与安全世界通信
调用scm_call()来陷入安全世界。
scm_call()实现如下:
arch/arm/mach-msm/scm.c
- int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, void *resp_buf, size_t resp_len){ ... ret = scm_call_common(svc_id, cmd_id, cmd_buf, cmd_len, resp_buf, resp_len, cmd, len); kfree(cmd); return ret;}
scm_call_common的实现如下:
- static int scm_call_common(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, void *resp_buf, size_t resp_len, struct scm_command *scm_buf, size_t scm_buf_length){ .... mutex_lock(&scm_lock); ret = __scm_call(scm_buf);//调用 mutex_unlock(&scm_lock); if (ret) return ret; rsp = scm_command_to_response(scm_buf); start = (unsigned long)rsp; do { scm_inv_range(start, start + sizeof(*rsp)); } while (!rsp->is_complete); end = (unsigned long)scm_get_response_buffer(rsp) + resp_len; scm_inv_range(start, end); if (resp_buf) memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len); return ret;}
调用__scm_call()陷入安全世界,回来后调用scm_get_response_buffer()获取安全世界返回的信息供上面QSApp client用
__scm_call实现如下:
- static int __scm_call(const struct scm_command *cmd){... ret = smc(cmd_addr);... return ret;}
smc实现如下:
- static u32 smc(u32 cmd_addr){ int context_id; register u32 r0 asm("r0") = 1; register u32 r1 asm("r1") = (u32)&context_id; register u32 r2 asm("r2") = cmd_addr; do { asm volatile( __asmeq("%0", "r0") __asmeq("%1", "r0") __asmeq("%2", "r1") __asmeq("%3", "r2")#ifdef REQUIRES_SEC ".arch_extension sec\n"#endif "smc #0 @ switch to secure world\n" : "=r" (r0) : "r" (r0), "r" (r1), "r" (r2) : "r3"); } while (r0 == SCM_INTERRUPTED); return r0;}
是一段汇编程序,好吧,安全世界的QSApp已经运行起来了,当QSApp完成相应服务后就会返回数据。这个函数就会返回。
Starting QSApp已经完成,下面就注册listener,这个listener用于监听QSApp那边的请求。因为有时QSApp也需要HLOS这边做一些事。
实现如下:
- void *listener_thread( void* threadid ){.... do {... /* Register as a listener with the QSApp */ LOGD( "L%#X: Registering as listener with QSApp...", (uint32_t)threadid ); ret = QSEECom_register_listener( &g_qseeCommHandles[parent_tid][tid], GET_LSTNR_SVC_ID(parent_tid, tid), sizeof(qseecom_req_res_t), 0 );.... for( ;; ) { /* Wait for request from the QSApp */ ret = QSEECom_receive_req( g_qseeCommHandles[parent_tid][tid], req_res, sizeof(qseecom_req_res_t) ); if( ret ) break; .... /* Send the response to the QSApp */ ret = QSEECom_send_resp( g_qseeCommHandles[parent_tid][tid], req_res, sizeof(qseecom_req_res_t) ); CHECK_RETURN( ret, __LINE__ ); } } while( 0 );...}
这个函数比较长,简化一下,分步来看
首先调用QSEECom_register_listener()函数来注册监听,告诉QSApp,我可以接收你的申请。
再次看到for循环没有,这就是一直等待QSApp那边的消息,一但有消息QSEECom_reveive_req就返回,这边处理完之后。
再调用qSEECom_send_resp()发送response给QSApp。
无论是起动QSApp,还是注册listener都是线程中执行,一但所有线程都退出后就会调用QSEECom_shutdown_app()函数停止QSApp。
整个过程执行完毕。如下:
- void *test_thread( void* threadid ){...if ( g_qseeCommHandles[tid][0] != NULL ) { QSEECom_shutdown_app( &g_qseeCommHandles[tid][0] ); } } while( 0 ); pthread_exit( NULL ); return NULL;}
注:QSEECom _XX开头的函数都在kernel中的qseecom.c里实现,scm系统调用,都在scm.c中实现。
HLOS user层把握QSEEComAPI.h文件
HLOS kernel层把握qseecom.c 和 scm.c两文件
简谈高通Trustzone的实现相关推荐
- 简谈高通Trustzone的实现【转】
本文转载自:https://blog.csdn.net/hovan/article/details/42520879 从trust zone之我见知道,支持trustzone的芯片会跑在两个世界. 普 ...
- 浅谈高通的MSM7230-评各大厂商
浅谈高通的MSM7230并解释U8800的FM 有些同学问到为什么U8800没有FM: 有些问到为什么CPU是800MHz而不是1G: 有人问MSM7230比OMAP 3610/3630好还是差:答案 ...
- 高通骁龙 8155 到底有什么魔力?
高通骁龙8155采用安卓系统,兼容性更好,APP的数量也就相当多,硬件方面,这颗芯片最高支持3个4K屏或4个2K屏,4个麦克风6颗摄像头,还有WiFi6.5G.蓝牙5.0等功能,所以现在很多车有3块大 ...
- 高通CEO谈中国5G:原以为会晚个5-10年,结果第一年就推出了
近日,高通CEO莫伦科夫接受媒体采访时感叹,中国在5G部署方面的进展非常惊人. 莫伦科夫表示,我认为中国正在加速5G的部署,预计今年年底前,中国会部署大约10万个5G基站,非常了不起. 莫伦科夫称,以 ...
- 高通android逆向分析,浅谈Android高通(Qualcomm)和联发科(MTK)平台
一款CPU好不好是要从多个方面考虑的,并不是说简简单单看一个主频.几个核心数就完了,更重要的是它的综合实力到底有多强,这里面当然也会牵扯到价格问题,性能相似当然是便宜的获胜,这是毋庸置疑的. 事实上, ...
- 彻底与高通谈崩?苹果被爆计划自研5G调制解调器
前不久,美国第四大运营商Sprint起诉第二大运营商AT\u0026amp;T,声称后者使用虚假5G标签误导消费者,其在部分手机中信号标识的5GE实际只是4G网络的改进版,仍属于4G网络技术,足以见得 ...
- 蓝牙 aptx android,没错,现在蓝牙耳机可以开始谈音质了 高通aptX HD SONY LDAC
高通aptX HD Qualcomm aptX HD Apt-X是一种基于子带ADPCM(SB-ADPCM)技术的数字音频压缩算法. aptXHD音频确保蓝牙设备提供高清晰度(HD)音频.通过音频传输 ...
- (1)RIL简析(高通)——RIL如何启动及初始化
Android设置了RIL层,是上层framework与Modem沟通的桥梁.高通使用qcril作为其vendor-RIL,与modem之间使用QMI机制通讯. 分3篇分析下面的问题: RIL如何启动 ...
- 浅谈Android高通(Qualcomm)和联发科(MTK)平台
一款CPU好不好是要从多个方面考虑的,并不是说简简单单看一个主频.几个核心数就完了,更重要的是它的综合实力到底有多强,这里面当然也会牵扯到价格问题,性能相似当然是便宜的获胜,这是毋庸置疑的. 事实上, ...
最新文章
- linux——用脚本实现全自动安装虚拟机
- c语言实参形参函数调用指针引用 符号实例,C语言实参、形参、函数调用、指针、引用、符号实例.doc...
- 第16讲:ODBCJDBC简介
- python多线程详解_python基础:python多线程详解
- 在WPF中弹出右键菜单时判断鼠标是否选中该项
- php中多选提交如何获取,php中checkbox值获取,显示,多选值获取
- 在c 语言中 一个函数由函数头和,C语言程序设计基础教程_习题答案
- vbox里面的Ubuntu虚拟机与主机win7之间设置共享文件夹
- Ubuntu中添加应用程序快速启动器的方法
- WEEX|初始化工程
- 洛谷-UVA12676 Inverting Huffman(反转树)
- 链表哈夫曼树--编码--解码
- 写文章不会起标题?爬取虎嗅5万篇文章告诉你
- 一般家用路由器买多大的合适_家用路由器选多少M(兆)的合适【图】
- Unity 游戏的String interning优化
- 浅谈大数据背景下数据库安全保障体系
- 很不错的PERL管道应用
- 青龙,XDD-plus,若兰,安装
- TFT-LCD移植记录
- LuaJIT Bytecode介绍
热门文章
- 052_Drawer抽屉
- 004_Redis的String数据类型
- 062_JavaScript异常
- 026_html表单
- Unity5x编辑器的视图一
- 大数据中心周边辐射大吗_PETCT有辐射,PETCT对陪同人员的影响大吗?
- oracle怎么解析sql,oracle SQL解析步骤小结
- gtp怎么安装系统_UEFI+GTP模式下使用GHO文件安装WIN7或WIN8系统图文教程详解
- fir.im 全名 Fly It Remotely ,是一个为移动开发者服务,FIR一个免费的App托管平台
- Mysql搭建主从服务器