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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

optee中的thread_vector_table线程向量表

發布時間:2025/3/21 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 optee中的thread_vector_table线程向量表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈

文章目錄

        • 1、向量表的定義
        • 2、向量表的注冊

1、向量表的定義

在thread_a64.S中:

/** Vector table supplied to ARM Trusted Firmware (ARM-TF) at* initialization.** Note that ARM-TF depends on the layout of this vector table, any change* in layout has to be synced with ARM-TF.*/ FUNC thread_vector_table , :b vector_std_smc_entryb vector_fast_smc_entryb vector_cpu_on_entryb vector_cpu_off_entryb vector_cpu_resume_entryb vector_cpu_suspend_entryb vector_fiq_entryb vector_system_off_entryb vector_system_reset_entry END_FUNC thread_vector_table KEEP_PAGER thread_vector_table

這個向量表地址,會被傳到ATF中,保存在全局變量中

2、向量表的注冊

在optee初始化時,generic_boot_init_primary函數獲取該向量表的地址:

struct thread_vector_table * generic_boot_init_primary(unsigned long pageable_part, unsigned long u __unused,unsigned long fdt) {init_primary_helper(pageable_part, PADDR_INVALID, fdt);return &thread_vector_table; }

_start函數調用的generic_boot_init_primary

FUNC _start , :mov x19, x0 /* Save pagable part address */mov x20, x2 /* Save DT address */adr x0, reset_vect_tablemsr vbar_el1, x0isbset_sctlr_el1isb#ifdef CFG_WITH_PAGER/** Move init code into correct location and move hashes to a* temporary safe location until the heap is initialized.** The binary is built as:* [Pager code, rodata and data] : In correct location* [Init code and rodata] : Should be copied to __init_start* [Hashes] : Should be saved before initializing pager**/adr x0, __init_start /* dst */adr x1, __data_end /* src */adr x2, __tmp_hashes_end /* dst limit *//* Copy backwards (as memmove) in case we're overlapping */sub x2, x2, x0 /* len */add x0, x0, x2 /* __init_start + len = __init_end */add x1, x1, x2 /* __data_end + len */adr x2, __init_start copy_init:ldp x3, x4, [x1, #-16]!stp x3, x4, [x0, #-16]!cmp x0, x2b.gt copy_init #endif/** Clear .bss, this code obviously depends on the linker keeping* start/end of .bss at least 8 byte aligned.*/adr_l x0, __bss_startadr_l x1, __bss_end clear_bss:str xzr, [x0], #8cmp x0, x1b.lt clear_bss/* Setup SP_EL0 and SP_EL1, SP will be set to SP_EL0 */set_sp/* Enable aborts now that we can receive exceptions */msr daifclr, #DAIFBIT_ABTadr_l x0, __text_start #ifdef CFG_WITH_PAGERadrp x1, __tmp_hashes_endadd x1, x1, :lo12:__tmp_hashes_end #elseadrp x1, __endadd x1, x1, :lo12:__end #endifsub x1, x1, x0bl dcache_inv_range/* Enable Console */bl console_initbl core_init_mmu_mapbl core_init_mmu_regsbl cpu_mmu_enablebl cpu_mmu_enable_icachebl cpu_mmu_enable_dcachemov x0, x19 /* pagable part address */mov x1, #-1mov x2, x20 /* DT address */bl generic_boot_init_primary/** In case we've touched memory that secondary CPUs will use before* they have turned on their D-cache, clean and invalidate the* D-cache before exiting to normal world.*/mov x19, x0adr_l x0, __text_start #ifdef CFG_WITH_PAGERadrp x1, __tmp_hashes_endadd x1, x1, :lo12:__tmp_hashes_end #elseadrp x1, __endadd x1, x1, :lo12:__end #endifsub x1, x1, x0bl dcache_cleaninv_range/** Clear current thread id now to allow the thread to be reused on* next entry. Matches the thread_init_boot_thread in* generic_boot.c.*/bl thread_clr_boot_thread/* Pass the vector address returned from main_init */mov x1, x19mov x0, #TEESMC_OPTEED_RETURN_ENTRY_DONEsmc #0b . /* SMC should not return */ END_FUNC _start KEEP_INIT _start

然后我們剖析下,這個線程向量表地址記錄到哪里去了?

可以看出,optee讀取到線程向量表后,將該地址放到X1參數中,然后調用smc切換到ATF

在ATF中,我們看opteed_smc_handler()函數,有如下片段,我們可以看到,在optee初始化完畢后,將線程量表表保存到X1中,然后調用smc(cmd=TEESMC_OPTEED_RETURN_ENTRY_DONE)切回到ATF,ATF中將該向量表保存到全局變量中optee_vectors

switch (smc_fid) { /** OPTEE has finished initialising itself after a cold boot*/ case TEESMC_OPTEED_RETURN_ENTRY_DONE:/** Stash the OPTEE entry points information. This is done* only once on the primary cpu*/assert(optee_vectors == NULL);optee_vectors = (optee_vectors_t *) x1;if (optee_vectors) {set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_ON);/** OPTEE has been successfully initialized.* Register power management hooks with PSCI*/psci_register_spd_pm_hook(&opteed_pm);/** Register an interrupt handler for S-EL1 interrupts* when generated during code executing in the* non-secure state.*/flags = 0;set_interrupt_rm_flag(flags, NON_SECURE);rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,opteed_sel1_interrupt_handler,flags);if (rc)panic();}/** OPTEE reports completion. The OPTEED must have initiated* the original request through a synchronous entry into* OPTEE. Jump back to the original C runtime context.*/opteed_synchronous_sp_exit(optee_ctx, x1);

當從REE—>ATF—>TEE流程時,在ATF中其實就是跳轉到的optee_vector表中指向的函數

if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) {cm_set_elr_el3(SECURE, (uint64_t)&optee_vectors->fast_smc_entry); } else {cm_set_elr_el3(SECURE, (uint64_t)&optee_vectors->std_smc_entry); }

總結

以上是生活随笔為你收集整理的optee中的thread_vector_table线程向量表的全部內容,希望文章能夠幫你解決所遇到的問題。

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