日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简谈高通Trustzone的实现

發布時間:2025/4/16 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简谈高通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

view plaincopy to clipboardprint?
  • 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

    view plaincopy to clipboardprint?
  • 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。

    view plaincopy to clipboardprint?
  • 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

    view plaincopy to clipboardprint?
  • 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

    view plaincopy to clipboardprint?
  • 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的實現如下:

    view plaincopy to clipboardprint?
  • 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實現如下:

    view plaincopy to clipboardprint?
  • static?int?__scm_call(const?struct?scm_command?*cmd){...????ret?=?smc(cmd_addr);...?return?ret;}??

  • smc實現如下:

    view plaincopy to clipboardprint?
  • 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這邊做一些事。

    實現如下:


    view plaincopy to clipboardprint?
  • 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。

    整個過程執行完畢。如下:

    view plaincopy to clipboardprint?
  • 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兩文件

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的简谈高通Trustzone的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。