MTK安全启动分析8:MTK MicroTrust BL32 ATF跳转到LK流程

发布时间:2026/7/22 15:36:44

MTK安全启动分析8:MTK MicroTrust BL32 ATF跳转到LK流程 MT8766 MicroTrust BL32 初始化完成后返回、跳转LK完整流程结合Preloader汇编jumparch64、TEE编译Makefile、ARMv8 TF-A标准架构完整拆解区分硬件机制、ATF代码逻辑、MTK定制链路前置架构基础ARMv8 TrustZone硬件铁律EL3ATF BL31唯一拥有跨世界切换权限只有EL3能修改SCR_EL3安全位、执行ERET切换安全/非安全世界S-EL1MicroTrust BL32 TEE安全世界内核无权直接跳LKTEE初始化完成必须通过SMC同步异常陷回EL3 ATFEL1LK BL33普通世界Bootloader只能通过SMC调用安全服务无法主动切安全世界MT8766链路分工Preloader(BL2)一次性把 tee.img(BL31BL32)、lk_a/lk_b 全部加载到DRAM永久保存在内存热复位不清DRAM汇编jumparch64触发CPU暖复位强制进入AArch64 EL3从BL31入口执行BL31 ATF先启动BL32等TEE全部初始化完毕切换到ATF再切换非安全世界跳转预加载好的LK。阶段1Preloader侧前置准备1.1 固件全加载bldr_load_imagesPreloader在bldr_pre_process流程中加载tee_a → 拼接好的atf_teeid.img microtrust_teeid.imgBL31BL32整体tee.img存入CFG_ATF_ROM_MEMADDR加载lk_a/lk_b存入CFG_UBOOT_MEMADDR两块镜像都完成RSA验签常驻DRAM暖复位不会清空。1.2 jumparch64 汇编配置暖复位jumparch64: LDR r5, bl31_base_addr LDR r5,[r5] ; 读取BL31 ATF入口地址 LDR r6, rst_vector_base_addr str r5,[r6] ; 写入复位向量暖复位后PC直接指向BL31 MRC p15,0,r6,c12,c0,2 orr r6, #1 ; 复位后启用AArch64 64位模式 MCR p15,0,r6,c12,c0,2 DSB;ISB orr r6,#2 ; 发起warm热复位请求 MCR p15,0,r6,c12,c0,2 WFI_LOOP: WFI; B WFI_LOOP动作总结把BL31入口写入芯片复位向量寄存器配置复位后CPU切AArch64发送热复位信号CPU暂停进入WFI等待复位热复位触发后DRAM数据完整保留CPU自动从BL31地址启动EL3 ATF。阶段2ATF BL31 启动加载并运行MicroTrust BL322.1 BL31主流程 bl31_mainTF-A标准入口bl31_main() { // 1. 平台、GIC、PSCI、SMC调度初始化 bl31_early_platform_setup(); bl31_plat_arch_setup(); runtime_svc_init(); // SMC服务注册MicroTrust SPD安全分发器 // 2. 注册BL32 SPD驱动MT MicroTrust适配层 microtrust_spd_register(); // 3. 进入安全世界执行BL32 TEE初始化 bl32_init(); // ↓ 此处阻塞直到BL32完整初始化、SMC返回BL31 // 4. TEE返回后准备非安全世界上下文跳转LK /* Determine which image to execute next */ image_type bl31_get_next_image_type(); /* Program EL3 registers to enable entry into the next EL */ next_image_info bl31_plat_get_next_image_ep_info(image_type); assert(next_image_info ! NULL); assert(image_type GET_SECURITY_STATE(next_image_info-h.attr)); INFO(BL31: Preparing for EL3 exit to %s world\n, (image_type SECURE) ? secure : normal); print_entry_point_info(next_image_info); cm_init_my_context(next_image_info); cm_prepare_el3_exit(image_type);// ERET切非安全世界跳BL33 LK }2.2 bl32_init 执行流程进入S-EL1运行TEEtf-a-2.4\services\spd\teeid\450\teei_fastcall.cDECLARE_RT_SVC( teei_fastcall, OEN_TOS_START, OEN_TOS_END, SMC_TYPE_FAST, teei_fastcall_setup, teei_fastcall_handler );tf-a-2.4\services\spd\teeid\450\teei_main.cint teei_fastcall_setup(void) { if (is_abnormal_boot()) { ERROR(abnormal boot, return\n); return 0; } entry_point_info_t *image_info; image_info bl31_plat_get_next_image_ep_info(SECURE); assert(image_info); uint32_t linear_id plat_core_pos_by_mpidr(read_mpidr()); teeiBootCoreMpidr read_mpidr(); teei_gic_setup(); teei_init_secure_context(secure_context[linear_id]); if (teei_is_aarch64()) teei_init_eret(image_info-pc, TEEI_AARCH64); else teei_init_eret(image_info-pc, TEEI_AARCH32); bl31_register_bl32_init(teei_init_entry); return 0; }ATF读取tee.img中BL32镜像的GFH头部校验独立RSA签名配置SCR_EL3.NS0标记接下来进入安全世界填充S-EL1上下文栈、异常向量、BL32入口执行ERETCPU从EL3下降到S-EL1开始运行MicroTrust BL32。阶段3MicroTrust BL32 TEE 完整初始化 SMC返回EL3关键TEE回到ATF的核心动作3.1 BL32内部完整初始化流程MicroTrust内核执行顺序安全堆、TZ内存、硬件加密引擎初始化RPMB、eFuse安全接口初始化批量加载所有内置TAsecstore/指纹/DRM/防克隆TA初始化安全中断、TZASC外设隔离完成整机安全环境就绪此时TEE进入常驻服务状态等待普通世界SMC请求。3.2 TEE主动发送SMC陷回EL3 BL31TEE没有权限直接跳LKTEE初始化收尾执行一条标准安全监控SMC指令SMC #0x32000000 // MT MicroTrust专用SPD同步返回FID硬件行为CPU从S-EL1安全世界触发SMC同步异常自动提升到EL3异常向量进入BL31的smc_handler64ATF匹配SMC FID识别为「BL32初始化完成、归还控制权」SPD分发器microtrust_spd_handler处理完返回回到bl31_main阻塞点继续向下执行跳转LK逻辑。重点BL32绝对不能直接访问非世界内存、修改EL3寄存器必须靠SMC把执行权还给ATF由EL3统一切换到LK。阶段4BL31 ATF 切换非安全世界跳转LK BL33TEE通过SMC返回后BL31执行两套上下文配置最终ERET跳LK4.1 读取LK加载信息Preloader提前备好ATF从全局启动参数区读取Preloader传递的LK镜像物理加载地址 CFG_UBOOT_MEMADDRLK入口、栈、异常等级EL1非安全。4.2 配置非安全世界CPU上下文初始化时设置了每个镜像的运行地址func bl31_entrypoint /* --------------------------------------------------------------- * Stash the previous bootloader arguments x0 - x3 for later use. * --------------------------------------------------------------- */ mov x20, x0 mov x21, x1 mov x22, x2 mov x23, x3 #if !RESET_TO_BL31 /* --------------------------------------------------------------------- * For !RESET_TO_BL31 systems, only the primary CPU ever reaches * bl31_entrypoint() during the cold boot flow, so the cold/warm boot * and primary/secondary CPU logic should not be executed in this case. * * Also, assume that the previous bootloader has already initialised the * SCTLR_EL3, including the endianness, and has initialised the memory. * --------------------------------------------------------------------- */ el3_entrypoint_common \ _init_sctlr0 \ _warm_boot_mailbox0 \ _secondary_cold_boot0 \ _init_memory0 \ _init_c_runtime1 \ _exception_vectorsruntime_exceptions \ _pie_fixup_sizeBL31_LIMIT - BL31_BASE #else /* --------------------------------------------------------------------- * For RESET_TO_BL31 systems which have a programmable reset address, * bl31_entrypoint() is executed only on the cold boot path so we can * skip the warm boot mailbox mechanism. * --------------------------------------------------------------------- */ el3_entrypoint_common \ _init_sctlr1 \ _warm_boot_mailbox!PROGRAMMABLE_RESET_ADDRESS \ _secondary_cold_boot!COLD_BOOT_SINGLE_CPU \ _init_memory1 \ _init_c_runtime1 \ _exception_vectorsruntime_exceptions \ _pie_fixup_sizeBL31_LIMIT - BL31_BASE /* --------------------------------------------------------------------- * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so * theres no argument to relay from a previous bootloader. Zero the * arguments passed to the platform layer to reflect that. * --------------------------------------------------------------------- */ mov x20, 0 mov x21, 0 mov x22, 0 mov x23, 0 #endif /* RESET_TO_BL31 */ /* -------------------------------------------------------------------- * Perform BL31 setup * -------------------------------------------------------------------- */ mov x0, x20 mov x1, x21 mov x2, x22 mov x3, x23 bl bl31_setup /******************************************************************************* * Setup function for BL31. ******************************************************************************/ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { /* Perform early platform-specific setup */ bl31_early_platform_setup2(arg0, arg1, arg2, arg3); /* Perform late platform-specific setup */ bl31_plat_arch_setup(); #if CTX_INCLUDE_PAUTH_REGS /* * Assert that the ARMv8.3-PAuth registers are present or an access * fault will be triggered when they are being saved or restored. */ assert(is_armv8_3_pauth_present()); #endif /* CTX_INCLUDE_PAUTH_REGS */ } static entry_point_info_t bl32_ep_info; static entry_point_info_t bl33_ep_info; void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { static console_t console; params_early_setup(arg1); #if COREBOOT if (coreboot_serial.type) console_16550_register(coreboot_serial.baseaddr, coreboot_serial.input_hertz, coreboot_serial.baud, console); #else console_16550_register(UART0_BASE, UART_CLOCK, UART_BAUDRATE, console); #endif NOTICE(MT8183 bl31_setup\n); bl31_params_parse_helper(arg0, bl32_ep_info, bl33_ep_info); }4.3 el3_exit() ERET 硬件跳转adrp x0, __DATA_START__ add x0, x0, :lo12:__DATA_START__ adrp x1, __DATA_END__ add x1, x1, :lo12:__DATA_END__ sub x1, x1, x0 bl clean_dcache_range adrp x0, __BSS_START__ add x0, x0, :lo12:__BSS_START__ adrp x1, __BSS_END__ add x1, x1, :lo12:__BSS_END__ sub x1, x1, x0 bl clean_dcache_range b el3_exitfunc el3_exit #if ENABLE_ASSERTIONS /* el3_exit assumes SP_EL0 on entry */ mrs x17, spsel cmp x17, #MODE_SP_EL0 ASM_ASSERT(eq) #endif /* ---------------------------------------------------------- * Save the current SP_EL0 i.e. the EL3 runtime stack which * will be used for handling the next SMC. * Then switch to SP_EL3. * ---------------------------------------------------------- */ mov x17, sp msr spsel, #MODE_SP_ELX str x17, [sp, #CTX_EL3STATE_OFFSET CTX_RUNTIME_SP] /* ---------------------------------------------------------- * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET * ---------------------------------------------------------- */ ldr x18, [sp, #CTX_EL3STATE_OFFSET CTX_SCR_EL3] ldp x16, x17, [sp, #CTX_EL3STATE_OFFSET CTX_SPSR_EL3] msr scr_el3, x18 msr spsr_el3, x16 msr elr_el3, x17 #if IMAGE_BL31 DYNAMIC_WORKAROUND_CVE_2018_3639 /* ---------------------------------------------------------- * Restore mitigation state as it was on entry to EL3 * ---------------------------------------------------------- */ ldr x17, [sp, #CTX_CVE_2018_3639_OFFSET CTX_CVE_2018_3639_DISABLE] cbz x17, 1f blr x17 1: #endif restore_ptw_el1_sys_regs /* ---------------------------------------------------------- * Restore general purpose (including x30), PMCR_EL0 and * ARMv8.3-PAuth registers. * Exit EL3 via ERET to a lower exception level. * ---------------------------------------------------------- */ bl restore_gp_pmcr_pauth_regs ldr x30, [sp, #CTX_GPREGS_OFFSET CTX_GPREG_LR] #if IMAGE_BL31 RAS_EXTENSION /* ---------------------------------------------------------- * Issue Error Synchronization Barrier to synchronize SErrors * before exiting EL3. Were running with EAs unmasked, so * any synchronized errors would be taken immediately; * therefore no need to inspect DISR_EL1 register. * ---------------------------------------------------------- */ esb #endif exception_return endfunc el3_exitERET硬件原子操作一步完成权限切换把ELR_EL3的值加载到PC跳LK入口恢复SPSR到PSTATECPU降级到EL1SCR_EL3.NS1 永久开启普通世界模式完全退出EL3 ATF监控进入LK运行。阶段5完整全局时序串联所有代码联动1. BootROM BL1 → 验签、启动Preloader BL2(AArch32 EL1) 2. Preloader bldr_pre_process() a. 初始化DDR、存储、安全库sec_lib_init() b. bldr_load_images() 一次性加载 tee_a(BL31BL32)、lk_a到DRAM c. 执行jumparch64汇编配置复位向量、发起warm热复位 3. CPU热复位AArch64 EL3自动执行BL31 ATF a. ATF初始化PSCI/SMC/SPD b. bl32_init() → ERET进入S-EL1 MicroTrust BL32 4. BL32 TEE完整初始化全部安全硬件TA → 执行SMC指令异常陷回EL3 BL31 5. BL31收到TEE返回配置非安全世界上下文 → ERET原子跳转进入LK BL33普通世界EL1 6. LK初始化安卓外设加载boot.img内核3个核心约束与MTK定制特性1. 为什么TEE不能直接跳LKARMv8硬件强制隔离S-EL1安全世界没有权限修改SCR_EL3安全位无法关闭TrustZone隔离只有EL3能控制安全/非世界切换TEE一旦允许直接跳转会破坏硬件信任根隔离存在安全逃逸漏洞。2. DRAM常驻设计Preloader提前加载所有固件MT8766方案特殊点Preloader一次性把ATFTEELK全部载入内存热复位不清DRAMATF不需要再读写eMMC加载LK直接使用Preloader准备好的镜像大幅缩短启动时间。3 和tee.img编译Makefile对应关系编译生成的combined.imgatf_teeid.imgmicrotrust_teeid.img前半段atf_teeid.img BL31 ATF复位向量指向它后半段microtrust_teeid.img BL32 MicroTrustATF运行时向后偏移内存找到BL32镜像校验自身独立RSA签名后启动TEE。Preloader(AArch32 EL1) ↓jumparch64 暖复位 CPU切换AArch64 EL3 → BL31 ATF ↓ ERET 切S-EL1 BL32 MicroTrust TEE 完整初始化 ↓ SMC 异常陷回EL3 BL31 ATF 配置普通世界上下文 ↓ ERET 原子跳转 LK BL33EL1 安卓二级引导

相关新闻