【SA8295P 源码分析】06 - SA8295P XBL Loader 阶段 sbl1_main_ctl() 函数代码分析

news/2024/11/23 22:45:25/

【SA8295P 源码分析】06 - SA8295P XBL Loader 阶段 sbl1_main_ctl 函数代码分析

  • 一、XBL Loader 汇编源码分析
    • 1.1 解析 boot\QcomPkg\XBLLoader\XBLLoader.inf
    • 1.2 boot\QcomPkg\XBLDevPrg\ModuleEntryPoint.S:跳转 sbl1_entry 函数
    • 1.3 XBLLoaderLib\sbl1_Aarch64.s:跳转 sbl1_main_ctl 函数
  • 二、XBL Loader C代码分析
    • 2.1 XBLLoaderLib\sbl1_mc.c:入口函数 sbl1_main_ctl(), SBL1(XBL Loader环境初始化)
    • 2.2 SBL1(XBL Loader)解析 sbl1_config_table:加载并验证 SMSS、XBL Config、shrm、apdp、sblramdump(dload)、aop、QSEE Devcfg、QSEE、secdata、QHEE, 最终返回sbl 后跳转 QSEE,启动 TrustZone



系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》
本文链接:《【SA8295P 源码分析】06 - SA8295P XBL Loader 阶段 sbl1_main_ctl() 函数代码分析》

在前文《【SA8295P 源码分析】05 - SA8295P QNX Host 上电开机过程 进一步梳理(结合代码)》中,
我们从把 SA8295P 上电启动流程从头到尾的梳理了一遍,整体流程已经很清楚了,包括每个流程所对应的代码在哪,我们也都清楚了。

万事俱备,从本文开始,我们就深入代码,一点一点地分析下,SA8295P芯片,从上电开始的每个步骤的代码实现。


在前文中,我们知道 XBL Loader 是由APPS PBL 加载起来的,的源码位置如下:
源代码位于:sa8295p-hqx-4-2-4-0_amss_standard_oem.git\boot\boot_images\boot\QcomPkg\XBLLoader
汇编代码位于:sa8295p-hqx-4-2-4-0_amss_standard_oem.git\boot\boot_images\boot\QcomPkg\XBLLoader\ModuleEntryPoint.S
入口汇编位于:sa8295p-hqx-4-2-4-0_amss_standard_oem.git\boot\boot_images\boot\QcomPkg\SocPkg\Library\XBLLoaderLib\sbl1_Aarch64.s
入口函数为:BL sbl1_main_ctl

好,话不多说,我们开始分析代码吧:

一、XBL Loader 汇编源码分析

1.1 解析 boot\QcomPkg\XBLLoader\XBLLoader.inf

XBLLoader.inf 中可以看出,XBLDevPrg 的汇编代码为 ModuleEntryPoint.S
它是运行在 FEATURE_START_EL3 安全环境下。

# sa8295p-hqx-4-2-4-0_amss.git\boot\boot_images\boot\QcomPkg\XBLLoader\XBLLoader.inf
[Defines]INF_VERSION                    = 0x00010005BASE_NAME                      = XBLLoaderFILE_GUID                      = BD4CC3FB-4872-DDC9-2CE9-AF999D7B9264MODULE_TYPE                    = USER_DEFINEDVERSION_STRING                 = 1.0[Sources.common]boot_gpt_partition_id.c[Sources.AARCH64]ModuleEntryPoint.S[BuildOptions.AARCH64]#GCC:*_*_*_CC_FLAGS = -O0 -fno-inline#GCC:*_*_*_PP_FLAGS = -DFEATURE_START_EL3			// 定义GCC 编译宏控 FEATURE_START_EL3

1.2 boot\QcomPkg\XBLDevPrg\ModuleEntryPoint.S:跳转 sbl1_entry 函数

ModuleEntryPoint.S 的主要工作如下:

  1. 获取当前的运行环境,保存在 x4 寄存器中, CurrentEL : 0xC=EL3; 0x8=EL2; 0x4=EL1
  2. 第一个传参X0APPS_PBL 传入的共享数据地址,将 x0的值保存到X19 寄存器中
  3. 禁止所有中断,对应的指令为 asm{ msr daifset, #DAIF_WR_INT_BITS(禁止中断) ; isb(清除指令流水线) }
  4. 关闭所有的CachesMMU
  5. 关闭 指令缓存 功能
  6. 关闭 TLB 页缓存 功能
  7. 恢复x9的值 (APPS_PBL 传入的共享数据地址) 到x0 中,作为第一个传参,传入sbl1_entry
  8. 跳转到 sbl1_entry 函数,传参为 x0APPS_PBL传入的共享数据地址 pbl_shared_data_pointer
# sa8295p-hqx-4-2-4-0_amss.git\boot\boot_images\boot\QcomPkg\XBLLoader\ModuleEntryPoint.S.global pbl_shared_data_pointer
pbl_shared_data_pointer:.quad 0x14810270_ModuleEntryPoint:
#ifdef FEATURE_START_EL3// 1. 获取当前的运行环境,保存在 x4 寄存器中,  CurrentEL : 0xC=EL3; 0x8=EL2; 0x4=EL1EL1_OR_EL2_OR_EL3(x4)
1:// 2. 第一个传参X0 是 APPS_PBL 传入的共享数据地址,将经x0的值保存到X19 寄存器中	
BootBackupX0:    mov x19, x0// 3. 禁止所有中断,对应的指令为 asm{ msr daifset, #DAIF_WR_INT_BITS(禁止中断) ;  isb(清除指令流水线) }
BootDisableInterrupts:bl ASM_PFX(ArmDisableInterrupts)	// 4. 关闭所有的Caches 和 MMU 
BootDisableCacheMmu:bl ASM_PFX(ArmDisableCachesAndMmu)// 5. 关闭 指令缓存功能
BootInvalInstructionCache:  bl ASM_PFX(ArmInvalidateInstructionCache)// 6. 关闭 TLB 页缓存
BootInvalidateTlb:bl ASM_PFX(ArmInvalidateTlb)// 7. 恢复x9的值 (APPS_PBL 传入的共享数据地址) 到x0 中,作为第一个传参,传入sbl1_entry 中
BootRestoreX0:    mov x0, x19
#endif// 8. 跳转到 sbl1_entry 函数,传参为 x0 (APPS_PBL传入的共享数据地址 pbl_shared_data_pointer)
BootBranchLoaderEntry:    b sbl1_entry

1.3 XBLLoaderLib\sbl1_Aarch64.s:跳转 sbl1_main_ctl 函数

sbl1_Aarch64.s 主要工作:

  1. x0 传参保存到 x7 寄存器中,它是 APPS_PBL 传入的共享数据地址 pbl_shared_data_pointer
  2. 将 栈指针寄存器 sp 配置为0
  3. 禁止 CacheMMUexception 异常处理功能,关闭 TLB 页缓存,禁止CPU的指令和数据cache功能
  4. SCTLR_EL1 寄存器的 MMU 位(0x1)、Cache位(0x4)、Stack Alignment Check位(0x8)清零
  5. 配置异常向量表:将 sbl1_vector_table 异常向量表的地址 保存在 X0 寄存器中,然后写入 VBAR_EL1 异常向量表寄存器中
  6. 设置FPEN bit20bit 21 ,不捕获 FP 和高级 SIMD 指令
  7. 读取中断状态寄存器ISR_EL1的值到 X0中,通过 ISR_EL1_A_BIT 位来检查是否有pending的异常,如果有则进入死循环
  8. 开启外部中止功能:在指令获取失败(指令中止)或数据访问失败(数据中止)时会生成中止
  9. 配置Stack 栈地址,SBL的栈大小默认为12kb, 定义在 \boot\boot_images\boot\QcomPkg\SocPkg\Library\DevPrgDLib\sbl1.ld
  10. 使能 指令Cache 缓存功能
  11. 设置PXNSPAN位,SPAN位用于设置EL1EL2的异常
  12. 初始化栈内存、配置栈为16字节对齐
  13. x7寄存器的值 保存到 X0中,将它以参数传递入sbl1_main_ctl中,它是APPS_PBL传入的共享数据地址 pbl_shared_data_pointer
# sa8295p-hqx-4-2-4-0_amss.git\boot\boot_images\boot\QcomPkg\SocPkg\Library\XBLLoaderLib\sbl1_Aarch64.s
.global sbl1_entry
sbl1_entry:// 1. 将 x0传参保存到 x7寄存器中,它是APPS_PBL传入的共享数据地址 pbl_shared_data_pointerMOV x7, x0// 2. 将 栈指针寄存器 配置为0, sp = 0MOV X0, #0MOV SP, X0// 3. 禁止 Cache、MMU 和 exception异常处理功能,关闭 TLB 页缓存,禁止CPU的指令和数据cache功能DSB SY			// 清除CPU数据流水线ISB SY			// 清除CPU指令流水线TLBI VMALLE1  	// TLB invalidateIC IALLU      	// Invalidate cache to PoUDSB SY			// 清除CPU数据流水线ISB SY			// 清除CPU指令流水线// 4. 将 SCTLR_EL1 寄存器的 MMU 位(0x1)、Cache位(0x4)、Stack Alignment Check位(0x8)清零MRS X0, SCTLR_EL1		// 读取EL1状态的系统控制寄存器 的值到X0中AND X0,X0, #~(M_BIT)	// 将 MMU 位清零, 禁止MMU, X0 = X0 & (~0x1) 		#define M_BIT 0x1 /* MMU Enable */AND X0,X0, #~(C_BIT)	// 将 Cache 位清零, 禁止Cache, X0 = X0 & (~0x1) 	#define C_BIT 0x4 /* Cache */// ORR X0,X0, #(A_BIT) 	//TODO: Enable after CPR fixes alignment faultORR X0,X0, #(SA_BIT)	// 禁止栈对检测 	#define SA_BIT 0x8 /* Stack Alignment Check */MSR SCTLR_EL1, X0		// 将 X0 写回 SCTLR_EL1寄存器中DSB SY					// 清除CPU数据流水线ISB SY					// 清除CPU指令流水线// 5. 配置异常向量表:将 sbl1_vector_table 异常向量表的地址 保存在 X0  寄存器中,然后写入 VBAR_EL1 异常向量表寄存器中LDR x0, =sbl1_vector_table  MSR VBAR_EL1, x0// 6. 设置FPEN bit20 和 bit 21 ,不捕获 FP和高级SIMD指令// SET FPEN BITS 20 AND 21 FOR NOT TRAPPING FP AND ADVANCED SIMD INSTRUCTIONSMRS X0, CPACR_EL1ORR X0, X0, #0X300000  MSR CPACR_EL1, X0ISB SY					// 清除CPU指令流水线// 7. 读取中断状态寄存器ISR_EL1的值到 X0中,通过 ISR_EL1_A_BIT 位来检查是否有pending的异常,如果有则进入死循环MRS X0, ISR_EL1AND X0, X0, #ISR_EL1_A_BITCBNZ X0, boot_loop_here// 8. 开启外部中止功能:在指令获取失败(指令中止)或数据访问失败(数据中止)时会生成中止// Enable external aborts// msr daifset, #1 //关闭FIQ		msr daifclr, #1 //开启FIQ// msr daifset, #2 //关闭IRQ		msr daifclr, #2 //开启IRQ// msr daifset, #4 //关闭Async		msr daifclr, #4 //开启Async// msr daifset, #8 //关闭Dbg		msr daifclr, #8 //开启DbgMSR DAIFClr, #INT_A_BITisb// 9. 配置Stack 栈地址,SBL的栈大小默认为12kb, 定义在 \boot\boot_images\boot\QcomPkg\SocPkg\Library\DevPrgDLib\sbl1.ld 中LDR x0, = Image$$SBL1_STACK_BASE$$PointerMOV SP, x0// 10. 使能 指令Cache 缓存功能// Enable instruction cacheMRS X0, SCTLR_EL1ORR X0,X0, #I_BIT// 11. 设置PXN的SPAN位,用于设置EL1或EL2的异常  SET SPAN bit for PXNSET SPAN bit for PXNORR X0,X0, #CTRL_SPAN_BITMSR SCTLR_EL1, X0// 12. 初始化栈内存、配置栈为16字节对齐LDR x0, = Image$$SBL1_STACK$$BaseLDR x1, = Image$$SBL1_STACK$$LengthBIC  x1, x1, #0xF  MOV  x2, #0             // used as counterwrite_16bytes_loop:stp xzr,xzr,[x0], #0x10	// 将 xzr=xzr, [0]=0x10  往栈底写入#0x10 add     x2, x2, #0x10   	// x2 += 0x10,  increment by 16 bytescmp     x1, x2			// 判断 x1 == x2 ?b.ne write_16bytes_loop  sbl1_entry_init_stack:  // 13. 将 x7寄存器的值 保存到 X0中,将它以参数传递入sbl1_main_ctl中,它是APPS_PBL传入的共享数据地址 pbl_shared_data_pointerMOV w0, w7			// mov x0, x7BL sbl1_main_ctl// For safetyBL boot_loop_here  // never returns

汇总下,在汇编代码中,主要做了四件事,如下:

  1. 禁止 CPU 的中断、CacheMMUTLB 功能
  2. 初始化中断向量表 VBAR_EL1 = &sbl1_vector_table
  3. 开启外部中止功能:在指令获取失败(指令中止)或数据访问失败(数据中止)时会生成中止
  4. 初始化栈
  5. 跳转进入 C 函数 sbl1_main_ctl()

二、XBL Loader C代码分析

2.1 XBLLoaderLib\sbl1_mc.c:入口函数 sbl1_main_ctl(), SBL1(XBL Loader环境初始化)

sbl1_main_ctl() 主要工作如下:

  1. 记录 sbl1 开始运行的时间,保存在 sbl_start_time
  2. 初始化 DAL 层(Device Abstraction Layer)的 堆head内存,大小为207kb (0x33C00)
  3. 初始化 DAL 层(Device Abstraction Layer,位于硬件与应用层之间,DAL API定义在DDI文件中,应用层调用DDI接口使用驱动提供的服务)
  4. 初始化 boot_config_context 保存在 config_context_handle中, memory_mgr_dal=config_context_handle->mem_if
  5. 配置 ConfigContext 参数,将 Context IDContext interface 接口 绑定在一起
  6. 获取 CONFIG_CONTEXT_CLK_INTERFACE 对应的 clk 接口指针 保存在 clk_if
  7. 调用 clk_if->Clock_DebugInit() 函数初始化clock, QREF,PLL, LPASS
  8. 初始化栈溢出保护 (SSP) 功能机制的参数 __stack_chk_guard 为一个随机数
    主要作用是,在调用子函数时,将__stack_chk_guard的值存入栈顶,然后在函数返回之前取出栈顶的值,
    __stack_chk_guard比较,如果一致则说明栈数据没有被破坏,继续返回运行母函数
    如果比较不一致,说明出现了栈溢出,则直接调用__stack_chk_fail()函数宕机
  9. 获取 CONFIG_CONTEXT_MEMORY_MGR_INTERFACE 对应的 mem 接口指针 保存在 mem_if
  10. pbl_shared 的数据保存在 sbl1_pbl_shared_data 中,处理pbl传入的数据后保存在 sbl_verified_info
  11. pbl_shared->pbl_flash_shared_data中保存了启动设备的boot_device信息,将其保存在 ConfigContext的CONFIG_CONTEXT_BOOT_DEVICE
  12. 调用 mem_if->malloc 申请 media_if 的内存,用于保存 media_interface_if 的接口
  13. media_interface_if 的接口地址保存在 config_contextCONFIG_CONTEXT_BOOT_MEDIA_INTERFACE
  14. 初始化 SBL memory map 内存表
  15. 获取CONFIG_CONTEXT_BUSYWAIT_INTERFACE 对应的 busywait接口指针 保存在busywait_if
  16. 初始化busywait模块, 获取HWIO QTimer的地址 和 QTimerfreq,后面uart 串口需要用到
  17. 初始化共享imem boot_shared_imem
  18. 读取SMEM缓冲区数据进行初始化XBL_Core chip info driver芯片信息驱动程序,它是在XBL Loader阶段PlatformInfo填充的,如chip idchip serial
  19. 获取CONFIG_CONTEXT_BOOT_STATS_INTERFACE 对应的 boot_stats接口指针 保存在boot_stats_if中,初始化 boot_statistics_obj 结构体中的 time 统计信息
  20. 初始化 boot logger, 将 boot loggerlogger_uart_if 绑定在一起,这样 log 就可以通过 uart 口打印出来
  21. 打印串口 logboot 的相关属性,如下:
    第一句logFormat: Log Type - Time(microsec) - Message - Optional Info
    第二句logLog Type: B - Since Boot(Power On Reset), D - Delta, S - Statistic
    镜像版本号:QC_IMAGE_VERSION_STRING=BOOT.MXF.1.1-00539-MAKENA-1
    启动设备类型:Boot Interface: UFS
    secure boot 状态:Secure Boot: Off
  22. 如果配置了 debug cookie, 则会停留在此处等待 JTag 调试器的接入
  23. 获取CONFIG_CONTEXT_DDR_INFO_INTERFACE对应的 ddr接口指针 保存在 di_if 中, 然后初始化DDR
    主要是申请了 boot_ddr_info 类型的内存,指针保存在 ddr_info_ptr->mem_ifdi_ptr->mem_if
  24. 初始化 QSEE 接口,为后续SBL1跳转到QSEE 做准备
  25. 初始化 Temperature Sensor温度传感器,通过Tsens_Init() 配置使能PMICPS_HOLD reset功能,这样我们就可以通过PS_HOLD来做 warm reset
    初始化QUSB2,配置 High Speed QUSB2 PHY到无驱动模式,为 dload 下载做准备
  26. SBL1 (XBL Loader)阶段即将结束,解析sbl1_config_table,加载 SMSSXBL Configshrmapdpsblramdumpdload)、aopQSEE DevcfgQSEEsecdataQHEE, 最终返回sbl 后跳转 QSEE,启动 TrustZone

源码及注释分析如下:

# sa8295p-hqx-4-2-4-0_amss.git\boot\boot_images\boot\QcomPkg\SocPkg\Library\XBLLoaderLib\sbl1_mc.c
void sbl1_main_ctl(boot_pbl_shared_data_type *pbl_shared)
{do{// 1. 记录 sbl1 开始运行的时间,保存在sbl_start_time 中sbl_start_time = CALCULATE_TIMESTAMP(HWIO_IN(TIMETICK_CLK));// 2. 初始化 DAL层(Device Abstraction Layer)的 堆head内存,大小为207kb (0x33C00)dal_result = dal_if.HeapInit(boot_internal_heap, BOOT_INTERNAL_HEAP_SIZE, FALSE);================>+		// dal_if 定义在 boot\boot_images\boot\QcomPkg\XBLLoader\ExtDrivers\boot_dal.c中+		boot_dal_if_type dal_if = {+		    DALSYS_InitMod,+		    DALSYS_DeInitMod,+		 	......+		    DALSYS_HeapInit,+		    DALSYS_HeapDeInit,+		   	......+		};<================// 3. 初始化 DAL 层(Device Abstraction Layer,位于硬件与应用层之间,DAL API定义在DDI文件中,应用层调用DDI接口使用驱动提供的服务)// 待研究 SBL DAL Device 驱动dal_if.InitMod(NULL);// 4. 初始化 boot_config_context 保存在 config_context_handle中, memory_mgr_dal=config_context_handle->mem_ifstatus = boot_config_context_open(&config_context_handle, &memory_mgr_dal);================>+		// 初始化 ConfigContext支持的参数, 保存在config_context->entries[] 数组中+		// boot\boot_images\boot\QcomPkg\LoaderFramework\ConfigContext\boot_config_context.c+	    do{+	    	memset((uint8 *)config_context, 0, sizeof(config_context_type));+	+	    	config_context->handle_data.id = CONFIG_CONTEXT_ID;+	    	config_context->handle_data.config_context_handle = NULL;+	+	    	for(int i = 0; i < CONFIG_CONTEXT_NO_PARAMS; i++){+	      		config_context->entries[i].set = NOT_SET;+	      		config_context->entries[i].ptr.allocated = FALSE;+	    	}+	    }+	 	while(FALSE);+	  +		// 定义在 boot\boot_images\boot\QcomPkg\Include\api\boot\boot_config_context.h中+     	typedef enum{+		    CONFIG_CONTEXT_PRE_PROCS = 0,                     //_populate_config_context_per_image+		    ......+		  	CONFIG_CONTEXT_TIMER_INTERFACE					//config_context_global_values+		  	CONFIG_CONTEXT_MEMORY_MGR_INTERFACE,              //config_context_global_values+		  	CONFIG_CONTEXT_BAM_INTERFACE,                     //config_context_global_values+ 		  	CONFIG_CONTEXT_BUS_INTERFACE,                     //config_context_global_values+		  	......+		  	CONFIG_CONTEXT_DAL_INTERFACE,                     //config_context_global_values+	      	CONFIG_CONTEXT_QSEE_INTERFACE,                    //config_context_global_values+		  	CONFIG_CONTEXT_SEC_IMG_INTERFACE,                 //config_context_global_values+		  	CONFIG_CONTEXT_BOOT_STATS_INTERFACE,              //config_context_global_values+		  	CONFIG_CONTEXT_TLMM_INTERFACE,                    //config_context_global_values+		  	CONFIG_CONTEXT_TSENSOR_INTERFACE,                 //config_context_global_values+		  	CONFIG_CONTEXT_UART_INTERFACE,                    //config_context_global_values+		  	CONFIG_CONTEXT_PARTITION_ID,                      //_populate_config_context_per_image+		  	CONFIG_CONTEXT_LOAD_FLAG,                         //_populate_config_context_per_image+		  	CONFIG_CONTEXT_EXEC_FLAG,                         //_populate_config_context_per_image+		  	CONFIG_CONTEXT_JUMP_FLAG,                         //_populate_config_context_per_image+		  	CONFIG_CONTEXT_XBLCFG_PARTITION_ID,+		  	......+		  	CONFIG_CONTEXT_NO_PARAMS+	  	} boot_config_context_param_type;<================// 5. 配置 ConfigContext 参数,将 Context ID 和 Context interface接口 绑定在一起status = boot_config_context_set_parameters(config_context_handle, config_context_global_values, sizeof(config_context_global_values)/sizeof(boot_config_context_populate_table));================>+	// sa8295p-hqx-4-2-4-0_amss.git\boot\boot_images\boot\QcomPkg\SocPkg\Library\XBLLoaderLib\sbl1_mc.c+	boot_config_context_populate_table config_context_global_values[] =+	{+		......+		{CONFIG_CONTEXT_MEMORY_MGR_INTERFACE,       PARAMETER_TYPE_PTR,  {}, {&memory_mgr_dal,       0, NULL}, },+		{CONFIG_CONTEXT_BUS_INTERFACE,              PARAMETER_TYPE_PTR,  {}, {&boot_bus,             0, NULL}, },+		{CONFIG_CONTEXT_RESET_INTERFACE,            PARAMETER_TYPE_PTR,  {}, {&reset_if,             0, NULL}, },+		{CONFIG_CONTEXT_CLK_INTERFACE,              PARAMETER_TYPE_PTR,  {}, {&clk_if,               0, NULL}, },+		{CONFIG_CONTEXT_DAL_INTERFACE,              PARAMETER_TYPE_PTR,  {}, {&dal_if,               0, NULL}, },+		{CONFIG_CONTEXT_DDI_INTERFACE,              PARAMETER_TYPE_PTR,  {}, {&ddi_if,               0, NULL}, },+		{CONFIG_CONTEXT_DDR_INFO_INTERFACE,         PARAMETER_TYPE_PTR,  {}, {&ddr_info_if,          0, NULL}, },+		{CONFIG_CONTEXT_DDR_INTERFACE,              PARAMETER_TYPE_PTR,  {}, {&ddr_if,               0, NULL}, },+		{CONFIG_CONTEXT_EFS_INTERFACE,              PARAMETER_TYPE_PTR,  {}, {&efs_if,               0, NULL}, },+		{CONFIG_CONTEXT_PIMEM_INTERFACE,            PARAMETER_TYPE_PTR,  {}, {&pimem_if,             0, NULL}, },+		{CONFIG_CONTEXT_PLATFORMINFO_INTERFACE,     PARAMETER_TYPE_PTR,  {}, {&platforminfo_if,      0, NULL}, },+		{CONFIG_CONTEXT_PMIC_INTERFACE,             PARAMETER_TYPE_PTR,  {}, {&pmic_if,              0, NULL}, },+		{CONFIG_CONTEXT_POWER_INTERFACE,            PARAMETER_TYPE_PTR,  {}, {&power_if,             0, NULL}, },+		{CONFIG_CONTEXT_QSEE_INTERFACE,             PARAMETER_TYPE_PTR,  {}, {&qsee_if,              0, NULL}, },+		{CONFIG_CONTEXT_QUSB_LDR_INTERFACE,         PARAMETER_TYPE_PTR,  {}, {&qusb_ldr_if,          0, NULL}, },+		{CONFIG_CONTEXT_BOOT_STATS_INTERFACE,       PARAMETER_TYPE_PTR,  {}, {&boot_statistics_if,   0, NULL}, },+		{CONFIG_CONTEXT_SECCFG_INTERFACE,           PARAMETER_TYPE_PTR,  {}, {&seccfg_if,            0, NULL}, },+		{CONFIG_CONTEXT_SECLIB_INTERFACE,           PARAMETER_TYPE_PTR,  {}, {&seclib_if,            0, NULL}, },+		{CONFIG_CONTEXT_SMEM_INTERFACE,             PARAMETER_TYPE_PTR,  {}, {&smem_if,              0, NULL}, },+		{CONFIG_CONTEXT_TLMM_INTERFACE,             PARAMETER_TYPE_PTR,  {}, {&tlmm_if,              0, NULL}, },+		{CONFIG_CONTEXT_TSENSOR_INTERFACE,          PARAMETER_TYPE_PTR,  {}, {&tsensor_if,           0, NULL}, },+		{CONFIG_CONTEXT_UART_INTERFACE,             PARAMETER_TYPE_PTR,  {}, {&uart_if,              0, NULL}, },+		{CONFIG_CONTEXT_VSENSE_INTERFACE,           PARAMETER_TYPE_PTR,  {}, {&vsense_if,            0, NULL}, },+		{CONFIG_CONTEXT_CONFIG_DATA_INTERFACE,      PARAMETER_TYPE_PTR,  {}, {&cdt_if,               0, NULL}, },+		{CONFIG_CONTEXT_TIMER_HW_INTERFACE,         PARAMETER_TYPE_PTR,  {}, {&timer_hw_if,          0, NULL}, },+		{CONFIG_CONTEXT_VSENSE_INTERFACE,           PARAMETER_TYPE_PTR,  {}, {&vsense_if,            0, NULL}, },+		{CONFIG_CONTEXT_EDK2_CACHE_INTERFACE,       PARAMETER_TYPE_PTR,  {}, {&edk2_cache_if,        0, NULL}, },+		{CONFIG_CONTEXT_EDK2_MMU_INTERFACE,         PARAMETER_TYPE_PTR,  {}, {&edk2_mmu_if,          0, NULL}, },+		......+		{CONFIG_CONTEXT_SAHARA_STATUS_MAP_INTERFACE, PARAMETER_TYPE_PTR, {}, {&sahara_status_map_if, 0, NULL}, },+	};<================// 6. 获取CONFIG_CONTEXT_CLK_INTERFACE 对应的 clk接口指针 保存在clk_if中status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_CLK_INTERFACE, (void **)&clk_if);// 7. 调用 clk_if->Clock_DebugInit() 函数初始化clock,QREF,PLL,LPASS等 // 定义在boot\boot_images\boot\QcomPkg\XBLLoader\ExtDrivers\boot_clk.c中ret = clk_if->debug_init();// 8. 初始化栈溢出保护(SSP)功能机制的参数__stack_chk_guard为一个随机数// 主要作用是,在调用子函数时,将__stack_chk_guard的值存入栈顶,然后在函数返回之前取出栈顶的值,// 与__stack_chk_guard比较,如果一致则说明栈数据没有被破坏,继续返回运行母函数// 如果比较不一致,说明出现了栈溢出,则直接调用__stack_chk_fail()函数宕机boot_init_stack_chk_canary();// 9. 获取CONFIG_CONTEXT_MEMORY_MGR_INTERFACE 对应的 mem接口指针 保存在mem_if中status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_MEMORY_MGR_INTERFACE, (void **)&mem_if);// 10. 将pbl_shared的数据保存在sbl1_pbl_shared_data中,处理pbl传入的数据后保存在sbl_verified_info中status = sbl1_retrieve_shared_info_from_pbl(pbl_shared);// PBL Shared 内容如下:====================> // boot\boot_images\boot\QcomPkg\SocPkg\Library\XBLLoaderLib\SM\pbl_sbl_shared.h+	typedef struct boot_pbl_shared_data_type{+		uint32      bl_sdata_version;							/* 共享数据版本号 */+		uint32      pbl_version;								/* PBL 版本号 */+		uint32      pbl_patch_version;							/* PBL Patch 版本号 */+		uint32      boot_option_fuse_val;						/* PBL Boot option configured in the fuse */+		uint32      bl_loader_auth_enabled;						/* BL loader authentication state */+		uint32      deprecated_hash_integrity_check_disabled;	/*Deprecated dummy entry for XBL-sec - temporary*/+		uint32      deprecated_bl_sec_boot_flow_supported;		/*Deprecated dummy entry for XBL-sec - temporary*/+		uint32      bl_sec_auth_disabled;  						/* BL-Sec authentication state */+		uint8       *boot_stack_base;							/* PBL 栈顶地址 */+		uint32      boot_stack_size;							/* PBL 栈大小 */+		uint32      reserved_fields_bl[BL_RESERVED_LENGTH];    	/* Reserved fields*/+		pbl_apps_timestamp_type *     timestamps;				/* Timestamps at main milestones in PBL */+		void*       pbl_debug_shared_data;						/* PBL shared data structure, maps to: pbl_sdata_type */+		void*       deprecated_pbl_clock_shared_data;			/*Deprecated dummy entry for XBL-sec - temporary*/+		void*       pbl_elf_shared_data;						/* Pointer to elf image shared data structure, maps to: pbl_elf_img_share_info_type */+		void*       pbl_secboot_shared_data;					/* Pointer to Secboot shared data structure, maps to: secboot_pbl_shared_info_type */+		void*       pbl_pcie_shared_data; 						/* Pointer to PCIE shared shared data structure, maps to: pcie_bhi_shared_data_type*/+		void*       pbl_flash_shared_data;						/* Pointer to flash shared data structure, maps to: boot_flash_shared_dev_info_type */+		void*       pbl_cache_mmu_share_data;					/* Pointer to cache mmu shared data structure,maps to: pbl_cache_mmu_share_info_type */+		void*       pbl_ecc_shared_data;						/* Pointer to ECC shared data structure,maps to: crypto_ecc_shared_info_type */+		void*       pbl_crypto_hash_cipher_shared_data;			/* Pointer to cipher Hash shared data structure,maps to: crypto_hash_cipher_shared_info_type */+	} boot_pbl_shared_data_type;<====================// 11. 在pbl_shared->pbl_flash_shared_data中保存了启动设备的boot_device信息,将其保存在 ConfigContext的CONFIG_CONTEXT_BOOT_DEVICE处status = boot_config_context_set_value(config_context_handle, CONFIG_CONTEXT_BOOT_DEVICE, (uint32)((((boot_flash_shared_dev_info_type*)(pbl_shared->pbl_flash_shared_data))->type)));// pbl shared data 中的 boot_device 信息结构体如下:=====================>+		/* This defines Flash shared data */+		typedef struct		// boot\boot_images\boot\QcomPkg\SocPkg\Library\XBLLoaderLib\SM\pbl_sbl_shared.h+		{+		  	uint32                shared_data_version;+		  	boot_media_type       type;        /* Type of flash  */+		  	uint32                CS_base;     /* Base address of chip select device is connected to.*/+		  	uint32                data_width;  /* Bit width of device ie: 8bit/16bit */+		  	boot_flash_ctrl_type  ctrl_type;   /* Controller used to interface with device*/+		  	boolean               is_recovery_partition;+			union+			{+			    boot_flash_shared_nand_dev_type nand;  /* Shared info for NAND device  */+			    boot_flash_shared_sdc_dev_type  sdc;   /* Shared info for SDC device   */+			    boot_flash_shared_spi_dev_type  spi;   /* Shared info for SPI device   */+			    struct boot_sahara_shared_data* sahara;/* Shared info pointer for Sahara flashless boot/eDL */+			}dev_info;+		}boot_flash_shared_dev_info_type;<=====================// 12. 调用mem_if->malloc 申请 media_if 的内存,用于保存 media_interface_if 的接口status = mem_if->malloc(sizeof(boot_media_interface_if_type), (void *)&media_if);status = boot_media_get_interface(config_context_handle, media_if);==========-========>	// boot\boot_images\boot\QcomPkg\XBLLoader\BlockDev\boot_block_dev.c((boot_media_interface_if_type *)media_interface_if)->media_hw_init = boot_block_dev_hw_init;((boot_media_interface_if_type *)media_interface_if)->media_hw_deinit = NULL;((boot_media_interface_if_type *)media_interface_if)->open = boot_block_dev_open;((boot_media_interface_if_type *)media_interface_if)->close = boot_block_dev_close;((boot_media_interface_if_type *)media_interface_if)->read = boot_block_dev_read;((boot_media_interface_if_type *)media_interface_if)->write = boot_block_dev_write;((boot_media_interface_if_type *)media_interface_if)->async_read = NULL;((boot_media_interface_if_type *)media_interface_if)->async_read_poll = NULL;<====================// 13. 将media_interface_if 的接口地址保存在  config_context 的 CONFIG_CONTEXT_BOOT_MEDIA_INTERFACE中status = boot_config_context_set_ptr(config_context_handle, CONFIG_CONTEXT_BOOT_MEDIA_INTERFACE, (void *)(media_if));// 14. 初始化 SBL memory map内存表status = xbl_populate_initial_mem_map(config_context_handle);===================>+    ARM_MEMORY_REGION_DESCRIPTOR xbl_initial_memory_map[]=+    {+ 		// [1M - 3M]	BASE=0x00100000 (1M),  size=0x1f0000 (2M, 1.9375M)+       { GCC_CLK_CTL_REG_REG_BASE,            GCC_CLK_CTL_REG_REG_BASE,          GCC_CLK_CTL_REG_REG_BASE_SIZE,          ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// [1M - 7.5M]	BASE=0x00100000(1M),  size=0x00680000  (6.5M)+       { REGISTER_REGION1_BASE,               REGISTER_REGION1_BASE,             REGISTER_REGION1_SIZE,                  ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// [7.5M - 7.5625M]	BASE=0x00780000(7.5M),  size=0x00010000(0.0625M)+       { SECURITY_CONTROL_BASE,               SECURITY_CONTROL_BASE,             QFPROM_READONLY_BLOCK_SIZE,             ARM_MEMORY_REGION_ATTRIBUTE_DEVICE_RO },+ 		// [7.523M - 176.875M]	BASE=0x00786000(7.523M),  size=0x0A95A000 (169.35M) +       { REGISTER_REGION2_BASE,               REGISTER_REGION2_BASE,             REGISTER_REGION2_SIZE,                  ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// [176.875M - 176.3063M]	BASE=0x0B0E0000 (176.875M),  size=0x8000 (32kb) 对应 AOP Data RAM region, MEMORY_REGION3+       { SCL_AOP_DATA_RAM_BASE,               SCL_AOP_DATA_RAM_BASE,             SCL_AOP_DATA_RAM_SIZE,                  ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XN },+ 		// [176.9M - 256M]	BASE=0x0B0E8000 (176.9M),  size=0x04F18000 (79.09375M) +       { REGISTER_REGION3_BASE,               REGISTER_REGION3_BASE,             REGISTER_REGION3_SIZE,                  ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// [336M - 336.0156M]	BASE=0x15000000 (336M),  size=0x4000 (16kb) +       { SYS_TCU_CFG_V2APPS_MMU500_SMMU_APP_BASE, SYS_TCU_CFG_V2APPS_MMU500_SMMU_APP_BASE, SYS_TCU_CFG_V2APPS_MMU500_SMMU_APP_SIZE, ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// [326.679M - 326.6914M]	BASE=‭0x146AE000‬(326.679M),  size= 0x00003000(12kb) +       { SCL_SYSTEM_DEBUG_CO_RO_BASE,         SCL_SYSTEM_DEBUG_CO_RO_BASE,       SCL_SYSTEM_DEBUG_CO_RO_SIZE,            ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO },+ 		// [326.746M - 326.75M]	BASE=‭0x146BF000‬ (326.746M),  size=0x00001000 (4kb) +       { (uint64)SHARED_IMEM_BASE,            (uint64)SHARED_IMEM_BASE,          (uint64)SHARED_IMEM_SIZE,               ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED_XN },+ 		// [328M - 329.5M]	BASE=0x14800000 (328M),  size=0x00180000 (1.5M) +       { (uint64)SCL_BOOT_IMEM_BASE_ADDR,     (uint64)SCL_BOOT_IMEM_BASE_ADDR,   (uint64)SCL_BOOT_IMEM_START_XBL_UNUSED, ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// SBL1 code 代码段起始地址	// boot\boot_images\boot\QcomPkg\SocPkg\Library\DevPrgDLib\sbl1.ld+       { (uint64)Image$$SBL1_CODE$$Base,      (uint64)Image$$SBL1_CODE$$Base,    (uint64)Image$$SBL1_CODE$$Length,       ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO },+ 		// SBL1 data_ro 只读数据段起始地址	// boot\boot_images\boot\QcomPkg\SocPkg\Library\DevPrgDLib\sbl1.ld+       { (uint64)Image$$SBL1_DATA_RO$$Base,   (uint64)Image$$SBL1_DATA_RO$$Base, (uint64)Image$$SBL1_DATA_RO$$Length,    ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XN_RO },+ 		// SBL1 stack 栈段起始地址	// boot\boot_images\boot\QcomPkg\SocPkg\Library\DevPrgDLib\sbl1.ld+       { (uint64)Image$$SBL1_STACK$$Base,     (uint64)Image$$SBL1_STACK$$Base,   (uint64)Image$$SBL1_STACK$$Length,      ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XN },+ 		// SBL1 data 数据段起始地址	// boot\boot_images\boot\QcomPkg\SocPkg\Library\DevPrgDLib\sbl1.ld+       { (uint64)Image$$SBL1_DATA_RW$$Base,   (uint64)Image$$SBL1_DATA_RW$$Base, (uint64)Image$$SBL1_DATA_RW$$Length,    ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XN },+ 		// SBL1 data_zi 数据段起始地址, 保存未初始化的可读写全局或静态变量+       { (uint64)Image$$SBL1_DATA_ZI$$Base,   (uint64)Image$$SBL1_DATA_ZI$$Base, (uint64)Image$$SBL1_DATA_ZI$$Length,    ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XN },+ 		// [376M - 389.5977M]	BASE=0x17800000 (376M),  size=0x00d99000 (13.5976M) +       { APSS_HM_BASE,                        APSS_HM_BASE,                      APSS_HM_BASE_SIZE,                      ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// [2G - 16G]	BASE=0x80000000 (2G),  size=0x380000000 (14G) +       { DDR_MEM_BASE_1,                      DDR_MEM_BASE_1,                    DDR_MEM_SIZE_1,                         ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// [32G - 64G]	BASE=0x800000000 (M),  size=0x800000000 (32G) +       { DDR_MEM_BASE_2,                      DDR_MEM_BASE_2,                    DDR_MEM_SIZE_2,                         ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// [768M - 1G]	BASE=0x30000000 (768M),  size=0x10000000 (256M) +       { PCIE_REGION_BASE,                    PCIE_REGION_BASE,                  PCIE_REGION_SIZE,                       ARM_MEMORY_REGION_ATTRIBUTE_DEVICE },+ 		// SBL1 SBL1_DEVPROG_UNCACHED_ZI segment段+	    {(uint64)Image$$SBL1_DEVPROG_UNCACHED_ZI$$Base,(uint64)Image$$SBL1_DEVPROG_UNCACHED_ZI$$Base, (uint64)Image$$SBL1_DEVPROG_UNCACHED_ZI$$ZI$$Length, EFI_ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED_XN },+		// SBL1 data_zi 数据段末尾地址, 保存未初始化的可读写全局或静态变量+	    {(uint64)Image$$SBL1_DATA_ZI$$End,(uint64)Image$$SBL1_DATA_ZI$$End,(( (uint64)(SCL_XBL_SEC_BASE_ADDR))-(uint64)(Image$$SBL1_DATA_ZI$$End)),ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XN}, +       {0,0,0,0}+    };<==================// 15. 获取CONFIG_CONTEXT_BUSYWAIT_INTERFACE 对应的 busywait接口指针 保存在busywait_if中status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_BUSYWAIT_INTERFACE, (void **)&busywait_if);// 16. 初始化busywait模块, 获取HWIO QTimer的地址 和 QTimerfreq,后面uart 串口需要用到bsy_wait_init = busywait_if->init();// 17. 初始化共享imem  boot_shared_imemboot_shared_imem_init();// 18. 读取SMEM缓冲区数据进行初始化XBL_Core chip info driver芯片信息驱动程序,它是在XBL Loader阶段PlatformInfo填充的,如chip id,chip serial等ChipInfo_Init();==================>+	  // Read the chip information from SMem+	  ChipInfoCtxt.nRawPartNum = pSMem->nRawChipId;+	  ChipInfoCtxt.eChipInfoId = (ChipInfoIdType)pSMem->eChipId;+	  ChipInfoCtxt.nRevNumber = pSMem->nRawChipVersion;+	  ChipInfoCtxt.nVersion = pSMem->nChipVersion;+	  ChipInfoCtxt.eFamilyId = (ChipInfoFamilyType)pSMem->nChipFamily;+	  ChipInfoCtxt.nFamilyDeviceId = pSMem->nRawDeviceNumber;+	  ChipInfoCtxt.nRawFamilyId = pSMem->nRawDeviceFamily;+	  ChipInfoCtxt.eFoundryId = (ChipInfoFoundryIdType)pSMem->nFoundryId;+	  ChipInfoCtxt.nSerialNum = pSMem->nChipSerial;+	  ChipInfoCtxt.nQFPROMChipId = pSMem->nQFPROMChipId;+	  ChipInfoCtxt.nModemSupported = pSMem->nModemSupported;+	  ChipInfo_strcpy(ChipInfoCtxt.szChipIdString, pSMem->szChipIdStr, CHIPINFO_MAX_ID_LENGTH);++	// SMem 中的 chip info 结构体如下;+	// 定义在 sa8295p-hqx-4-2-4-0_amss.git\boot\boot_images\boot\QcomPkg\Include\PlatformInfoDefs.h+	typedef struct+	{+		uint32                          nFormat;          				/**< Format of the structure. */+		uint32                          eChipId;          				/**< Chip ID. */+		uint32                          nChipVersion;     				/**< Chip version. */+		char                            aBuildId[DALPLATFORMINFO_SMEM_BUILD_ID_LENGTH];+																		/**< Build ID. */+		uint32                          nRawChipId;       				/**< Raw chip ID. */+		uint32                          nRawChipVersion;  				/**< Raw chip version. */+		DalPlatformInfoPlatformType     ePlatformType;    				/**< Platform type. */+		uint32                          nPlatformVersion; 				/**< Platform version. */+		uint32                          bFusion;          				/**< TRUE if Fusion; FALSE otherwise. */+		uint32                          nPlatformSubtype; 				/**< Platform subtype. */+		DalPlatformInfoSMemPMICType     aPMICInfo[DALPLATFORMINFO_SMEM_MAX_PMIC_DEVICES];+							/**< DEPRECATED. May not contain the full list. Use array at nPMICArrayOffset instead. */+		uint32                          nFoundryId;       				/**< Chip foundry ID. */+		uint32                          nChipSerial;      				/**< Chip serial number. */+		uint32                          nNumPMICs;        				/**< Number of PMICs in array. */+		uint32                          nPMICArrayOffset; 				/**< Offset from base of structure to array of DalPlatformInfoSMemPMICType. */+		uint32                          nChipFamily;        			/**< Chip family. */+		uint32                          nRawDeviceFamily;   			/**< Raw device family. */+		uint32                          nRawDeviceNumber;   			/**< Raw device number. */+		+		uint32                          nQFPROMChipId;      			/**< QFPROM Chip ID   */+		char                            szChipIdStr[DALPLATFORMINFO_SMEM_MAX_CHIP_ID_LENGTH];   	/**< Chip name */+		uint32                          nNumClusters;         			/**< Number of clusters for PartialGoods to consider */+		uint32                          nClusterArrayOffset;  			/**< Offset from base of structure to uint32 array of defective CPU clusters. */+		uint32                          nNumDefectiveParts;   			/**< Number of defective parts supported by the PartialGoods APIs */+		uint32                          nDefectivePartsArrayOffset;  	/**< Offset from base of structure to uint32 array of defective parts */+		uint32                          nModemSupported;      			/**< 0 if not supported, nonzero if supported */+	} DalPlatformInfoSMemType;<==================// 19. 获取CONFIG_CONTEXT_BOOT_STATS_INTERFACE 对应的 boot_stats接口指针 保存在boot_stats_if中, 初始化 boot_statistics_obj 结构体中的time 统计信息status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_BOOT_STATS_INTERFACE, (void **)&boot_stats_if);// 初始化 boot_statistics_obj 结构体中的time 统计信息status = boot_stats_if->init();		// boot_statistics_init()============>+	  boot_statistics_obj.flash_timer_start_timetick = 0;+	  boot_statistics_obj.flash_total_time_us = 0;+	  boot_statistics_obj.flash_total_bytes_read = 0;+	  boot_statistics_obj.flash_byte_counter = 0;<============// 20. 初始化 boot logger, 将 boot logger 与 logger_uart_if 绑定在一起,这样 log 就可以通过uart 口打印出来status = sbl1_boot_logger_init(config_context_handle, &boot_log_data, pbl_shared);=============>+		status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_LOGGER_INTERFACE, (void *)&logger_if);+		/*initialize boot logger*/+		logger_if->init(config_context_handle, boot_log_data);++		status = boot_logger_uart_get_interface(&logger_uart_if);+		status = logger_if->register_logger(logger_uart_if);<=============// 21. 打印串口log 及 boot 的相关属性,如下:// 第一句log: Format: Log Type - Time(microsec) - Message - Optional Info// 第二句log:Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic// 镜像版本号:QC_IMAGE_VERSION_STRING=BOOT.MXF.1.1-00539-MAKENA-1// 启动设备类型:Boot Interface: UFS// secure boot 状态:Secure Boot: Offboot_log_early_info(&boot_log_data, sbl_start_time, pbl_shared);============>+	void boot_log_early_info(boot_log_init_data *boot_log_data, uint32 sbl_start_time, boot_pbl_shared_data_type *pbl_shared)+	{+		// 打印:	Format: Log Type - Time(microsec) - Message - Optional Info+		boot_log_message_raw("\b\b\b\bFormat: Log Type - Time(microsec) - Message - Optional Info", BOOT_DND_TIMESTAMP, LOG_MSG_TYPE_STATISTIC, NULL);+		// 打印:	Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic+		boot_log_message_raw("\b\b\b\bLog Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic", BOOT_DND_TIMESTAMP, LOG_MSG_TYPE_STATISTIC, NULL);+		// 打印:	S - QC_IMAGE_VERSION_STRING=BOOT.MXF.1.1-00539-MAKENA-1+		//			S - IMAGE_VARIANT_STRING=SocMakenaAU+		//			S - OEM_IMAGE_VERSION_STRING=f556ff7556f9+		boot_log_image_version();+		// 打印:	S - Boot Interface: UFS+		boot_log_boot_device_type();+		// 打印:	S - Secure Boot: Off+		boot_log_secboot_status();+		// 打印: 	S - Boot Config @ 0x00786064 = 0x00000001+		//			S - JTAG ID @ 0x00786130 = 0x1014b0e1+		//			S - OEM ID @ 0x00786138 = 0x00000000+		//			S - Serial Number @ 0x00786134 = 0x87bb3c39+		//			S - OEM Config Row 0 @ 0x007841c8 = 0x0000000000000000+		//			S - OEM Config Row 1 @ 0x007841d0 = 0x0000000000000001+		//			S - Feature Config Row 0 @ 0x00784148 = 0x0000000000000000+		//			S - Feature Config Row 1 @ 0x00784150 = 0x0000000000000000+		boot_log_raw_fuse_values();+		// 打印:	S - Core 0 Frequency, 1440 MHz+		boot_log_apps_frequency(0);+		// 打印:	S - PBL Patch Ver: 0+		boot_log_pbl_version();+		// 打印:	"PBL freq: %d MHZ",+		boot_log_pbl_clk_freq();+		// 将 pbl 的时间戳 写在 log开头,+		// 打印log 		S -    102178 - PBL, End+		boot_pbl_log_milestones(pbl_shared);+		// 打印 		B -    112331 - SBL1, Start+		boot_log_message_raw("SBL1, Start", sbl_start_time, LOG_MSG_TYPE_BOOT, NULL);+		// 打印SBL编译时间			B -    244518 - SBL1 BUILD @ 12:28:32 on Apr 20 2023+		boot_log_message("SBL1 BUILD @ " __TIME__ " on " __DATE__);+	}<============boot_log_set_meta_info(boot_log_data.meta_info_start);		// 空函数// 22. 如果配置 debug cookie, 则会停留在此处等待 jtag 调试器的接入boot_debug_mode_check();// 23. 获取CONFIG_CONTEXT_DDR_INFO_INTERFACE对应的 ddr接口指针 保存在di_if中, 然后初始化DDR,// 主要是申请了 boot_ddr_info 类型的内存,指针保存在 ddr_info_ptr->mem_if 和 di_ptr->mem_if中 // sa8295p-hqx-4-2-4-0_amss.git\boot\boot_images\boot\QcomPkg\XBLLoader\ExtDrivers\boot_ddr_info.cstatus = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_DDR_INFO_INTERFACE, (void **)&di_if);status = di_if->init(config_context_handle);// 24. 初始化 QSEE 接口,为后续SBL1跳转到QSEE 做准备/* Initialize the QSEE interface */sbl1_init_sbl_qsee_interface(config_context_handle, &sbl_verified_info);// 25. 初始化 temperature sensor温度传感器,通过Tsens_Init() 配置使能PMIC 的 PS_HOLD reset功能,这样我们就可以通过PS_HOLD来做 warm reset // 	初始化QUSB2,配置 High Speed QUSB2 PHY到无驱动模式,为dload下载做准备/* Call sbl1_hw_init to config pmic device so we can use PS_HOLD to reset */// 打印log: D -    256322 - sbl1_hw_initstatus = sbl1_hw_init(config_context_handle);=================>	+	return_status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_TSENSOR_INTERFACE, (void **)&tsensor_if);+	status = tsensor_if->Init();+		----------->+		+	TsensResultType Tsens_Init(void)+		+		--------> // boot\boot_images\boot\QcomPkg\Library\TsensLib\TsensLoader.c+		+		+	static TsensResultType Tsens_ConfigureControllers(void)+		+		+		----->	//boot_images\boot\QcomPkg\SocPkg\Makena\Library\TsensTargetLib\HALtsens.c+		+		+		+	// Enables / disables PS_HOLD reset functionality+		+		+		+	void HAL_tsens_srot_SetPSHoldResetEn(uint8 *pucTsensSROTAddr, boolean bEnable)+		+		+		<-----+		+		<---------+		<-------------<=================#ifdef FEATURE_DEVICEPROGRAMMER_IMAGE/* Check if we need to branch to device programmer */device_programmer_lite_check(config_context_handle);device_programmer_ddr_check(config_context_handle);
#endif// 26. SBL1 (XBL Loader)阶段即将结束,解析sbl1_config_table,加载并验证 SMSS、XBL Config、shrm、apdp、sblramdump(dload)、aop、QSEE Devcfg、QSEE、secdata、QHEE, 最终返回sbl 后跳转 QSEE,启动 TrustZonestatus = sbl1_config_process_bl(config_context_handle, sbl1_config_table);} while (FALSE);error_if.error_handler(__FILE_BASENAME__, __LINE__, status);} /* sbl1_main_ctl() */

2.2 SBL1(XBL Loader)解析 sbl1_config_table:加载并验证 SMSS、XBL Config、shrm、apdp、sblramdump(dload)、aop、QSEE Devcfg、QSEE、secdata、QHEE, 最终返回sbl 后跳转 QSEE,启动 TrustZone


考虑到文章篇幅,本文先写到这,后续的内容,请见下篇文章,谢谢!


解析sbl1_config_table,并载并验证如下 target_img_partition_id 处的镜像,最终需要跳转到 qsee_jump_func(),启动QSEE

  1. smss_partition_id
  2. XBLConfig_partition_id
  3. shrm_partition_id
  4. apdp_partition_id
  5. sbl1_partition_id:执行 sbl1_dload_entry() 进入下载模式
  6. multi_image_partition_id
  7. multi_image_qti_partition_id
  8. aop_partition_id
  9. qsee_devcfg_image_partition_id
  10. qsee_partition_id
  11. secdata_partition_id
  12. cpucpfw_partition_id
  13. qhee_partition_id
  14. sbl1_partition_id: 执行qsee_jump_func()
# sa8295p-hqx-4-2-4-0_amss.git\boot\boot_images\boot\QcomPkg\SocPkg\Library\XBLLoaderLib\sbl1_config.c
#define CDT_STR         (uint8 *)"CDT"
#define DDR_STR         (uint8 *)"DDR"
#define QSEE_STR        (uint8 *)"QSEE"
#define QHEE_STR        (uint8 *)"QHEE"
#define APPSBL_STR      (uint8 *)"APPSBL"
#define QSEE_DEVCFG_STR (uint8 *)"QSEE Dev Config"
#define XCFG_STR        (uint8 *)"XBL Config"
#define APDP_STR        (uint8 *)"APDP"
#define AOP_STR         (uint8 *)"AOP"
#define OEM_MISC_STR    (uint8 *)"OEM_MISC"
#define QTI_MISC_STR    (uint8 *)"QTI_MISC"
#define SEC_STR         (uint8 *)"SEC"
#define CPUCPFW_STR     (uint8 *)"CPUCPFW"
#define SHRM_STR        (uint8 *)"SHRM"
#define RAMDUMP_STR     (uint8 *)"RamDump"
#define SMSS_STR        (uint8 *)"SMSS"/*==========================================================================DEFINE TARGET BOOT CONFIG TABLE
===========================================================================*/
boot_configuration_table_entry sbl1_config_table[] =
{
/* boot_media_type target_img_sec_type     config_img_type  boot_elf_loader_sync_type             optional_image  load    auth   exec   jump   exec_func jump_func      pre_procs             post_procs          load_cancel_func  load_metadata_func        target_img_partition_id         recovery_img_partition_id                seg_elf_entry_point     ram_part_entry_type   whitelist_ptr           whitelist_num_valid_entries                       target_img_str */{PBL_MEDIA, SECBOOT_SMSS_SW_TYPE,       CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  TRUE,           TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              smss_pre_procs,       smss_post_procs,    NULL,             NULL,                     smss_partition_id,              smss_recovery_partition_id,              0x0,                    0x0,                  smss_img_whitelist,     WHITELIST_VALID_ENTRIES(smss_img_whitelist),      SMSS_STR        },{PBL_MEDIA, SECBOOT_XBL_CONFIG_SW_TYPE, CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          FALSE,  TRUE,  FALSE, FALSE, NULL, NULL,              xcfg_pre_procs,       NULL,               NULL,             NULL,                     XBLConfig_partition_id,         XBLConfig_recovery_partition_id,         0x0,                    0x0,                  xcfg_img_whitelist,     WHITELIST_VALID_ENTRIES(xcfg_img_whitelist),      XCFG_STR        },{PBL_MEDIA, SECBOOT_SHRM_SW_TYPE,       CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              shrm_pre_procs,       NULL,               NULL,             NULL,                     shrm_partition_id,              shrm_recovery_partition_id,              0x0,                    0x0,                  shrm_img_whitelist,     WHITELIST_VALID_ENTRIES(shrm_img_whitelist),      SHRM_STR        },{PBL_MEDIA, SECBOOT_INVALID_SW_TYPE,    CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          FALSE,  FALSE, FALSE, FALSE, NULL, NULL,              cdt_pre_procs,        NULL,               NULL,             NULL,                     cdt_partition_id,               NULL,                                    0x0,                    0x0,                  cdt_img_whitelist,      WHITELIST_VALID_ENTRIES(cdt_img_whitelist),       CDT_STR         },{PBL_MEDIA, SECBOOT_INVALID_SW_TYPE,    CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          FALSE,  FALSE, FALSE, FALSE, NULL, NULL,              ddr_pre_procs,        NULL,               NULL,             NULL,                     ddr_params_partition_id,        NULL,                                    0x0,                    0x0,                  ddr_img_whitelist,      WHITELIST_VALID_ENTRIES(ddr_img_whitelist),       DDR_STR         },{PBL_MEDIA, SECBOOT_APDP_SW_TYPE,       CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  TRUE,           TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              apdp_pre_procs,       apdp_post_procs,    NULL,             NULL,                     apdp_partition_id,              apdp_recovery_partition_id,              0x0,                    0x0,                  apdp_img_whitelist,     WHITELIST_VALID_ENTRIES(apdp_img_whitelist),      APDP_STR        },{PBL_MEDIA, SECBOOT_SBL_SW_TYPE,        CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  TRUE,           TRUE,   TRUE,  FALSE, TRUE,  NULL, sbl1_dload_entry,  xblramdump_pre_procs, NULL,               NULL,             xblramdump_load_metadata, sbl1_partition_id,              sbl1_recovery_partition_id,              SCL_RAMDUMP_CODE_BASE,  0x0,                  ramdump_img_whitelist,  WHITELIST_VALID_ENTRIES(ramdump_img_whitelist),   RAMDUMP_STR     },{PBL_MEDIA, SECBOOT_OEM_MISC_SW_TYPE,   CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  TRUE,           TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              oemm_pre_procs,       NULL,               NULL,             NULL,                     multi_image_partition_id,       multi_image_recovery_partition_id,       0x0,                    0x0,                  oem_misc_img_whitelist, WHITELIST_VALID_ENTRIES(oem_misc_img_whitelist),  OEM_MISC_STR    },{PBL_MEDIA, SECBOOT_QTI_MISC_SW_TYPE,   CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  TRUE,           TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              NULL,                 NULL,               NULL,             NULL,                     multi_image_qti_partition_id,   multi_image_qti_recovery_partition_id,   0x0,                    0x0,                  qti_misc_img_whitelist, WHITELIST_VALID_ENTRIES(qti_misc_img_whitelist),  QTI_MISC_STR    },{PBL_MEDIA, SECBOOT_AOP_SW_TYPE,        CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              aop_pre_procs,        NULL,               NULL,             NULL,                     aop_partition_id,               aop_recovery_partition_id,               0x0,                    0x0,                  aop_img_whitelist,      WHITELIST_VALID_ENTRIES(aop_img_whitelist),       AOP_STR         },{PBL_MEDIA, SECBOOT_QSEE_DEVCFG_SW_TYPE,CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              NULL,                 NULL,               NULL,             NULL,                     qsee_devcfg_image_partition_id, qsee_devcfg_recovery_partition_id,       0x0,                    0x0,                  devcfg_img_whitelist,   WHITELIST_VALID_ENTRIES(devcfg_img_whitelist),    QSEE_DEVCFG_STR },{PBL_MEDIA, SECBOOT_QSEE_SW_TYPE,       CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              NULL,                 qsee_post_procs,    NULL,             NULL,                     qsee_partition_id,              qsee_recovery_partition_id,              0x0,                    0x0,                  qsee_img_whitelist,     WHITELIST_VALID_ENTRIES(qsee_img_whitelist),      QSEE_STR        },{PBL_MEDIA, SECBOOT_SEC_SW_TYPE,        CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  TRUE,           TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              NULL,                 NULL,               NULL,             NULL,                     secdata_partition_id,           NULL,                                    0x0,                    0x0,                  sec_img_whitelist,      WHITELIST_VALID_ENTRIES(sec_img_whitelist),       SEC_STR         },{PBL_MEDIA, SECBOOT_CPUCPFW_SW_TYPE,    CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              NULL,                 NULL,               NULL,             NULL,                     cpucpfw_partition_id,           cpucpfw_recovery_partition_id,           0x0,                    0x0,                  cpucpfw_img_whitelist,  WHITELIST_VALID_ENTRIES(cpucpfw_img_whitelist),   CPUCPFW_STR     },{PBL_MEDIA, SECBOOT_QHEE_SW_TYPE,       CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          TRUE,   TRUE,  FALSE, FALSE, NULL, NULL,              NULL,                 NULL,               NULL,             NULL,                     qhee_partition_id,              qhee_recovery_partition_id,              0x0,                    0x0,                  qhee_img_whitelist,     WHITELIST_VALID_ENTRIES(qhee_img_whitelist),      QHEE_STR        },{PBL_MEDIA, SECBOOT_SBL_SW_TYPE,        CONFIG_IMG_ELF,  BOOT_ELF_LOADER_SYNC_LOAD_SYNC_HASH,  FALSE,          TRUE,   TRUE,  FALSE, TRUE,  NULL, qsee_jump_func,    NULL,                 appsbl_post_procs,  NULL,             appsbl_load_metadata,     sbl1_partition_id,              sbl1_recovery_partition_id,              SCL_XBL_CORE_CODE_BASE, 0x0,                  xbl_core_img_whitelist, WHITELIST_VALID_ENTRIES(xbl_core_img_whitelist),  APPSBL_STR      },{MEDIA_TYPE_MAX, }
};

开始跳转QSEE

/* Executing QSEE from SBL1 */
static bl_error_boot_type qsee_jump_func(boot_handle config_context_handle)
{bl_error_boot_type status = BL_ERR_NONE;bl_shared_data_type *bl_shared_data_ptr = NULL;boot_pmic_if_type *pmic_if = NULL;boot_power_if_type *power_if = NULL;boot_edk2_cache_if_type *edk2_cache_if = NULL;xblconfig_status_type xcfg_status;do{status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_BL_SHARED_DATA, (void **)&bl_shared_data_ptr);if(status != BL_ERR_NONE){break;}status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_EDK2_CACHE_INTERFACE, (void**)&edk2_cache_if);if(status != BL_ERR_NONE || edk2_cache_if == NULL){break;}/* Flush the cache before entering QSEE */edk2_cache_if->WriteBackInvalidateDataCacheRange((void *)Image$$SBL1_CODE$$Base, Image$$SBL1_DATA_ZI$$End-Image$$SBL1_CODE$$Base);edk2_cache_if->WriteBackInvalidateDataCacheRange((void *)SCL_SBL1_DDR_BASE, SCL_SBL1_DDR_SIZE);status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_PMIC_INTERFACE, (void **)&pmic_if);if(status != BL_ERR_NONE) {break;}status = boot_config_context_get_ptr(config_context_handle, CONFIG_CONTEXT_POWER_INTERFACE, (void **)&power_if);if(status != BL_ERR_NONE){break;}pmic_if->pm_vib_off();power_if->aop_mini_dump_init();status = boot_minidump_register_regions(config_context_handle); if(status != BL_ERR_NONE){break;}/* De-initialize XBL Config Lib*/xcfg_status = xblconfig_deinit();memcpy(&sbl_qsee_interface_ddr, &(bl_shared_data_ptr->qsee_interface), sizeof(boot_qsee_interface));edk2_cache_if->WriteBackInvalidateDataCacheRange((void *)&sbl_qsee_interface_ddr, sizeof(boot_qsee_interface));/* De-initialize the boot logger */sbl1_boot_logger_deinit(config_context_handle);/* De-init hardware.  This must be done after sbl1_logger_deinit()This is also used to turn off VMEM memory clocks. So ensure the api code/buffersare not in memory if it is being used.  */sbl1_hw_deinit(config_context_handle);edk2_cache_if->WriteBackInvalidateDataCache();/* clearing the continuous boot failure count which is stored in IMEM */if (boot_shared_imem_cookie_ptr != NULL){boot_shared_imem_cookie_ptr->boot_fail_count = 0;}/* "Exit" bootloader and enter QSEE context. */if (sbl1_get_current_el() == EL_1) {boot_fastcall_tz_no_rsp(TZ_SBL_END_MILESTONE, TZ_SBL_END_MILESTONE_PARAM_ID,(uint32)(&sbl_qsee_interface_ddr),(uint32)(sizeof(sbl_qsee_interface_ddr)), 0,0);}/*Must not reach here*/while(1);}while(FALSE);return status;
}







http://www.ppmy.cn/news/97565.html

相关文章

Android 12.0framework添加自定义开机广播

1.概述 在12.0的进行系统定制化开发中,在内置一些app需要收到开机广播以后然后做一些相关的操作的功能的时候,发现开机广播要好久能收到,要么就收不到开机广播,所以这就需要了解开机广播在哪里发送,然后自定义开机广播来接收自定义开机广播然后开发一些功能 2.framework…

美债死期推迟

* * * 原创&#xff1a;刘教链 * * * 号外&#xff1a;今天在小号“刘教链Pro”发表了一篇《链上投票是社会契约的一种存证》&#xff0c;探讨未来组织和DAO的治理问题&#xff0c;欢迎关注“刘教链Pro”并阅读。 * * * 隔夜比特币略有回升&#xff0c;从26.5k下方来到了26.5k…

Qt基础之三十六:异常处理

本文将介绍如何在Qt中使用try...catch和调试dump文件来处理异常。 Qt版本5.12.6 一.使用try...catch 一段简单的捕获异常的代码,新建一个控制台工程,pro文件不用修改 #include <QCoreApplication> #include <QDebug>int main(int argc, char *argv[]) {QCoreA…

论文阅读_增强语言模型综述

论文信息 name_en: Augmented Language Models: a Survey name_ch: 增强语言模型综述 paper_addr: http://arxiv.org/abs/2302.07842 date_read: 2023-05-20 date_publish: 2023-02-15 tags: [‘深度学习’,‘自然语言处理’,‘大模型’] author: Grgoire Mialon&#xff0c;M…

【springcloud微微服务】分布式事务框架Seata使用详解

目录 一、前言 二、事务简介 2.1 原子性 2.2 一致性 2.3 隔离性 2.4 持久性

【SpringBoot集成Nacos+Dubbo】企业级项目集成微服务组件,实现RPC远程调用

文章目录 一、需求环境/版本 二、须知2.1、什么是RPC&#xff1f;2.2、什么是Dubbo&#xff1f;2.3、什么是Nacos&#xff1f; 三、普通的SpringBoot项目集成微服务组件方案&#xff08;笔者给出两种&#xff09;方案一&#xff08;推荐&#xff09;1、导入maven依赖&#xff0…

安卓上基于透明代理对APP抓包

简述 使用iptables将手机的全部tcp流量转到指定的透明代理上&#xff1b; 再使用redsocks将流量转发到正向代理&#xff0c;如Charles的socks5代理 基于iptables redsocks2 Charles&#xff0c;最终实现对安卓APP进行抓包&#xff0c;且APP无感知 即APP不能通过检查系统代理…

springboot接口返回的json字符串如何不显示null值字段

springboot接口返回的json字符串如何不显示null值字段 POSTMAN 测试接口时&#xff0c;默认字段值即使是null也显示出来&#xff0c;如何去掉更加简洁&#xff1f;这个跟POSTMAN无关&#xff0c;POSTMAN仅仅是展示response的body而已 思考&#xff1a;为什么要去掉null值的字…