optee的generic

xiaoxiao2021-02-28  54

generic_boot_init_primary是optee os初始化的主要函数 #if defined(CFG_WITH_ARM_TRUSTED_FW) 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; } unsigned long generic_boot_cpu_on_handler(unsigned long a0 __maybe_unused,                      unsigned long a1 __unused) {     DMSG("cpu %zu: a0 0x%lx", get_core_pos(), a0);     init_secondary_helper(PADDR_INVALID);     return 0; } #else void generic_boot_init_primary(unsigned long pageable_part,                    unsigned long nsec_entry, unsigned long fdt) {     init_primary_helper(pageable_part, nsec_entry, fdt); } void generic_boot_init_secondary(unsigned long nsec_entry) {     init_secondary_helper(nsec_entry); } #endif 可见optee针对是否有ATF 提供不同的generic_boot_init_primary 函数,这里我们只讨论enable CFG_WITH_ARM_TRUSTED_FW的情况 generic_boot_init_primary 中仅仅是调用init_primary_helper static void init_primary_helper(unsigned long pageable_part,                 unsigned long nsec_entry, unsigned long fdt) {     /*      * Mask asynchronous exceptions before switch to the thread vector      * as the thread handler requires those to be masked while      * executing with the temporary stack. The thread subsystem also      * asserts that the foreign interrupts are blocked when using most of      * its functions.      */ // 设定thread支持的所有异常,主要是写THREAD_EXCP_ALL到寄存器     thread_set_exceptions(THREAD_EXCP_ALL); //初始化cfp用于浮点运算,arm64 在init_vfp_sec 中disable vfp。要用vfp的话,需要通过thread_kernel_enable_vfp打开     init_vfp_sec(); //只要是清零bss段,并设定heap的范围为__heap1_start~__heap1_end。初始化ta用的memory     init_runtime(pageable_part); //初始化thread用到的线程栈     thread_init_primary(generic_boot_get_handlers()); //初始化pcpu结构     thread_init_per_cpu();     init_sec_mon(nsec_entry); //初始化fdt,如果没有定义CFG_DT则为null函数     init_fdt(fdt); //从fdt中配置console     configure_console_from_dt(fdt);     IMSG("OP-TEE version: %s", core_v_str); //初始化gic 各大厂商要自己实现     main_init_gic(); //如果定义CFG_WITH_ARM_TRUSTED_FW 的话,init_vfp_nsec 为null 函数     init_vfp_nsec(); //初始化共享内存并执行存放在__initcall_start段的其他初始化函数     if (init_teecore() != TEE_SUCCESS)         panic();     DMSG("Primary CPU switching to normal world boot\n"); } 我们重点看一下init_teecore TEE_Result init_teecore(void) {     static int is_first = 1;     /* (DEBUG) for inits at 1st TEE service: when UART is setup */     if (!is_first)         return TEE_SUCCESS;     is_first = 0; #ifdef CFG_WITH_USER_TA     tee_svc_uref_base = CFG_TEE_LOAD_ADDR; #endif     /* init support for future mapping of TAs */     teecore_init_pub_ram(); //初始化timmer     /* time initialization */     time_source_init(); //调用initcall ,类似kernel     /* call pre-define initcall routines */     call_initcalls();     IMSG("Initialized");     return TEE_SUCCESS; } static void call_initcalls(void) {     initcall_t *call;     for (call = &__initcall_start; call < &__initcall_end; call++) {         TEE_Result ret;         ret = (*call)();         if (ret != TEE_SUCCESS) {             EMSG("Initial call 0x" PRIxVA " failed",                  (vaddr_t)call);         }     } } 可以看到call_initcalls 会调用__initcall_start到__initcall_end 中定义的函数 inincalls的定义如下: #ifndef INITCALL_H #define INITCALL_H #include <tee_api_types.h> typedef TEE_Result (*initcall_t)(void); #define __define_initcall(level, fn) \     static initcall_t __initcall_##fn __attribute__((used)) \     __attribute__((__section__(".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) #endif 在程序中通过调用service_init/service_init_late/driver_init/driver_init_late 来注册initcall的函数,可见总共有四个优先级 static TEE_Result init_tzc400(void) {     void *va;     DMSG("Initializing TZC400");     va = phys_to_virt(TZC400_BASE, MEM_AREA_IO_SEC);     if (!va) {         EMSG("TZC400 not mapped");         panic();     }     tzc_init((vaddr_t)va);     tzc_dump_state();     return TEE_SUCCESS; } service_init(init_tzc400); 例如这个例子中,就会在call_initcalls 中调用init_tzc400
转载请注明原文地址: https://www.6miu.com/read-74121.html

最新回复(0)