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