入口
在此文件中:tfm/secure_fw/spm/cmsis_psa/main.c
Main()
->tfm_arch_set_msplim((uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base)); //设置堆栈限制
->fih_delay_init();
->tfm_core_init()
->tfm_hal_set_up_static_boundaries
->configure_mpu(rnr++, base, limit, XN_EXEC_OK, AP_RO_PRIV_UNPRIV); //配置各个内存边界的读写属性
->tfm_hal_platform_init() //核心函数,需要重点展开分析
->__enable_irq(); //使能中断
->stdio_init(); //初始化串口
-> fwu_metadata_init()
-> FWU_METADATA_FLASH_DEV.Initialize(NULL) //初始化FWU metadata所在的FLASH,就是 32MB 那个
-> flash_info = FWU_METADATA_FLASH_DEV.GetInfo()
->tfm_plat_otp_init()
->tfm_plat_provisioning_perform()
-> tfm_plat_otp_read //读OTP值
->tfm_arch_config_extensions()
->SCB->NSACR |= SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk;
->SCnSCB->CPPWR |= SCnSCB_CPPWR_SUS11_Msk | SCnSCB_CPPWR_SUS10_Msk;
->SPMLOG_DBGMSGVAL("TF-M isolation level is: ", TFM_LVL);
->SPMLOG_INFMSG("\033[1;34m Booting TFM v"VERSION_FULLSTR"\033[0m\r\n"); /* Print the TF-M version */
->tfm_arch_clear_fp_status(); //汇编代码
->tfm_core_handler_mode(); //发送SVC命令,触发tfm_spm_init(),这个函数是PSA的重点
//tfm_core_handler_mode()函数定义如下,它会调用SVC命令,并且,传递一个参数 TFM_SVC_SPM_INIT,最终,会调用到SVC_Handler, 最后,根据ID,调用到 tfm_spm_init()函数,后面会重点讲到tfm_spm_init()函数
__attribute__ ((naked)) void tfm_core_handler_mode(void)
{
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_SPM_INIT));
}
PendSV响应
PendSV(可悬起的系统调用),它和SVC 协同使用。
SVC异常是必须立即得到响应的,应用程序执行SVC 时都是希望所需的请求立即得到响应。
PendSV 则不同,它是可以像普通的中断一样被抢占挂起的。
PendSV_Handler
SVC响应
SVC_Handler
->BL tfm_core_svc_handler
->tfm_core_svc_handler
-> case TFM_SVC_SPM_INIT: tfm_spm_init() //初始化SPM
-> case TFM_SVC_GET_BOOT_DATA: tfm_core_get_boot_data_handler(svc_args);
-> case TFM_SVC_PREPARE_DEPRIV_FLIH: tfm_flih_prepare_depriv_flih (struct partition_t *)svc_args[0], (uintptr_t)svc_args[1]);
-> case TFM_SVC_FLIH_FUNC_RETURN: tfm_flih_return_to_isr(svc_args[0], (struct context_flih_ret_t *)msp);
-> default: svc_args[0] = SVC_Handler_IPC(svc_number, svc_args, exc_return); //根据Client端调用SVC命令时,传入的ID,进入不同的case处理函数
tfm_spm_init
tfm_spm_init
->tfm_pool_init(conn_handle_pool,
POOL_BUFFER_SIZE(conn_handle_pool),
sizeof(struct conn_handle_t),
CONFIG_TFM_CONN_HANDLE_MAX_NUM)
->load_a_partition_assuredly //从 section: .part.load 段中,依次获取一个 一个的partition_load_info_t
-> p_ptldinf->psa_ff_ver //检查Magic是否是:0x5F5F0000