generic_boot_init_primary函數(shù)內(nèi)容
generic_boot_init_primary函數(shù)是OP-TEE建立系統(tǒng)運(yùn)行環(huán)境的入口函數(shù),該函數(shù)會(huì)進(jìn)行建立線程運(yùn)行空間、初始化OP-TEE內(nèi)核組件等操作。該函數(shù)的執(zhí)行流程如圖所示。
generic_boot_init_primary函數(shù)執(zhí)行流程
generic_boot_init_primary函數(shù)會(huì)調(diào)用init_primary_helper函數(shù)來完成系統(tǒng)運(yùn)行環(huán)境的建立 ,如果系統(tǒng)支持ATF,則該函數(shù)會(huì)返回OP-TEE的處理句柄,該處理句柄主要包含
- ? 各種安全監(jiān)控模式調(diào)用的處理函數(shù)、
- ? 安全世界狀態(tài)(SWS)的中斷
- ? 以及其他事件的處理函數(shù),
ATF中的bl31解析完安全監(jiān)控模式調(diào)用或中斷請(qǐng)求后會(huì)在安全世界狀態(tài)調(diào)用該處理句柄來處理對(duì)應(yīng)的事件。
init_primary_helper函數(shù)的主要內(nèi)容如下:
static void init_primary_helper(unsigned long pageable_part,
unsigned long nsec_entry, unsigned long fdt)
{
thread_set_exceptions(THREAD_EXCP_ALL); //設(shè)置支持哪些異常處理
init_vfp_sec(); //初始化浮點(diǎn)運(yùn)算(根據(jù)實(shí)際需要考慮是否開啟)
//初始化各種memory,清空BSS段,分配TA運(yùn)行時(shí)的memory
init_runtime(pageable_part);
/* 初始化TEE中支持的線程棧、異常處理、pagetable */
thread_init_primary(generic_boot_get_handlers());
//初始化每個(gè)CPU的monitor態(tài)的處理方式,如果支持ATF,則無需該操作
thread_init_per_cpu();
/* 如果系統(tǒng)不支持ATF,則需要配置在Linux內(nèi)核中monitor的處理方式 */
init_sec_mon(nsec_entry);
/* 初始化device tree */
init_fdt(fdt);
/* 初始化中斷控制器 */
main_init_gic();
/* 初始化非安全側(cè)的浮點(diǎn)運(yùn)算 */
init_vfp_nsec();
/* 初始化共享內(nèi)存并執(zhí)行存放在__initcall_start段的其他初始化函數(shù) */
if (init_teecore() ! = TEE_SUCCESS)
panic();
DMSG("Primary CPU switching to normal world bootn");
}
init_primary_helper函數(shù)最后會(huì)調(diào)用init_teecore來完成OP-TEE內(nèi)核的初始化 ,在init_teecore函數(shù)中會(huì)設(shè)定共享內(nèi)存、系統(tǒng)時(shí)間,然后再返回去執(zhí)行OP-TEE鏡像文件中的_initcall段中的內(nèi)容來啟動(dòng)系統(tǒng)的服務(wù)以及安全驅(qū)動(dòng)的掛載。
call_initcalls函數(shù)
init_teecore函數(shù)通過調(diào)用call_initcalls來 啟動(dòng)系統(tǒng)的服務(wù)以及安全驅(qū)動(dòng)的掛載 ,該函數(shù)的內(nèi)容如下:
static void call_initcalls(void)
{
initcall_t *call;
/* 遍歷并執(zhí)行_initcallx段中所有函數(shù) */
for (call = &__initcall_start; call < &__initcall_end; call++) {
TEE_Result ret;
ret = (*call)();
if (ret ! = TEE_SUCCESS) {
EMSG("Initial call 0x%08" PRIxVA " failed",
(vaddr_t)call);
}
}
}
在執(zhí)行call_initcalls函數(shù)之前,系統(tǒng)已完成了 memory、CPU相關(guān)設(shè)置、中斷控制器、共享內(nèi)存、線程堆棧設(shè)置、TA運(yùn)行內(nèi)存的分配等操作 。
call_initcalls是通過遍歷OP-TEE鏡像文件的_initcall段中從_initcall_start到_initcall_end之間的所有函數(shù)來完成啟動(dòng)服務(wù)和驅(qū)動(dòng)的掛載操作。
OP-TEE鏡像文件中** _initcalls段的內(nèi)容是通過使用__define_initcall宏來告知編譯器的**,在編譯時(shí)會(huì)將使用該宏定義的函數(shù)保存到OP-TEE鏡像文件的_initcall段中。該宏定義如下:
#define __define_initcall(level, fn)
static initcall_t __initcall_##fn __attribute__((used))
__attribute__((__section__(".initcall" level))) = fn
- ? initcall_t:是一個(gè)函數(shù)指針類型(typedef int(*initcall_t)(void))。
- ? attribute (( section ()):將fn對(duì)象放在一個(gè)由括號(hào)中的名稱指定的section中。
- ? ##:連接作用。
例如,如果使用該宏如下:
__define_initcall("1", init_operation)
則該宏的作用是聲明一個(gè)名稱為__initcall_init_operation的函數(shù)指針,將該函數(shù)指針初始化為init_operation,并在編譯時(shí)將該函數(shù)的內(nèi)容存放在名稱為“.initcall1”的段中。
core/arch/arm/kernel/kern.ld.S文件中存在如下內(nèi)容:
__initcall_start = .;
KEEP(*(.initcall1))
KEEP(*(.initcall2))
KEEP(*(.initcall3))
KEEP(*(.initcall4))
__initcall_end = .;
即在__initcall_start到__initcall_end之間保存的是initcall1到initcall4之間的內(nèi)容,而在整個(gè)OP-TEE源代碼的core/include/initcall.h文件中,__define_initcall宏被使用的情況如下:
#define __define_initcall(level, fn)
#define service_init(fn) __define_initcall("1", fn)
#define service_init_late(fn) __define_initcall("2", fn)
#define driver_init(fn) __define_initcall("3", fn)
#define driver_init_late(fn) __define_initcall("4", fn)
所以遍歷執(zhí)行從__initcall_start到__initcall_end之間的內(nèi)容就是啟動(dòng)OP-TEE的服務(wù)以及完成安全驅(qū)動(dòng)的掛載。
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1360瀏覽量
40185 -
TEE
+關(guān)注
關(guān)注
0文章
29瀏覽量
10235 -
函數(shù)調(diào)用
+關(guān)注
關(guān)注
0文章
19瀏覽量
2578
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論