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

【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 汇编源码分析

【SA8295P 源码分析】06 - SA8295P XBL Loader 阶段 sbl1_main_ctl() 函数代码分析_第1张图片


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                    = 0x00010005
  BASE_NAME                      = XBLLoader
  FILE_GUID                      = BD4CC3FB-4872-DDC9-2CE9-AF999D7B9264
  MODULE_TYPE                    = USER_DEFINED
  VERSION_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=EL1
  	EL1_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_pointer
  	MOV x7, x0
  	
  	// 2. 将 栈指针寄存器 配置为0, sp = 0
  	MOV X0, #0
  	MOV SP, X0
  	
	// 3. 禁止 Cache、MMU 和 exception异常处理功能,关闭 TLB 页缓存,禁止CPU的指令和数据cache功能
  	DSB SY			// 清除CPU数据流水线
  	ISB SY			// 清除CPU指令流水线
  	TLBI VMALLE1  	// TLB invalidate
  	IC IALLU      	// Invalidate cache to PoU
 	DSB 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 fault
  	ORR 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 INSTRUCTIONS
  	MRS X0, CPACR_EL1
  	ORR X0, X0, #0X300000  
  	MSR CPACR_EL1, X0
  	ISB SY					// 清除CPU指令流水线

	// 7. 读取中断状态寄存器ISR_EL1的值到 X0中,通过 ISR_EL1_A_BIT 位来检查是否有pending的异常,如果有则进入死循环
  	MRS X0, ISR_EL1
  	AND X0, X0, #ISR_EL1_A_BIT
  	CBNZ 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 //开启Dbg
  	MSR DAIFClr, #INT_A_BIT
  	isb
	
	// 9. 配置Stack 栈地址,SBL的栈大小默认为12kb, 定义在 \boot\boot_images\boot\QcomPkg\SocPkg\Library\DevPrgDLib\sbl1.ld 中
  	LDR x0, = Image$$SBL1_STACK_BASE$$Pointer
  	MOV SP, x0
  
  	// 10. 使能 指令Cache 缓存功能
  	// Enable instruction cache
 	MRS X0, SCTLR_EL1
  	ORR X0,X0, #I_BIT

  	// 11. 设置PXN的SPAN位,用于设置EL1或EL2的异常  SET SPAN bit for PXNSET SPAN bit for PXN
  	ORR X0,X0, #CTRL_SPAN_BIT
  	MSR SCTLR_EL1, X0

  	// 12. 初始化栈内存、配置栈为16字节对齐
  	LDR x0, = Image$$SBL1_STACK$$Base
  	LDR x1, = Image$$SBL1_STACK$$Length
  	BIC  x1, x1, #0xF  
  	MOV  x2, #0             // used as counter
  	
write_16bytes_loop:
  	stp xzr,xzr,[x0], #0x10	// 将 xzr=xzr, [0]=0x10  往栈底写入#0x10 
  	add     x2, x2, #0x10   	// x2 += 0x10,  increment by 16 bytes
  	cmp     x1, x2			// 判断 x1 == x2 ?
  	b.ne write_16bytes_loop  

sbl1_entry_init_stack:  
	// 13. 将 x7寄存器的值 保存到 X0中,将它以参数传递入sbl1_main_ctl中,它是APPS_PBL传入的共享数据地址 pbl_shared_data_pointer
  	MOV w0, w7			// mov x0, x7
  	BL sbl1_main_ctl
	
  // For safety
  BL boot_loop_here  // never returns

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

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

二、XBL Loader C代码分析

【SA8295P 源码分析】06 - SA8295P XBL Loader 阶段 sbl1_main_ctl() 函数代码分析_第2张图片

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_if
    status = 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_imem
    boot_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: Off
    boot_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.c
    status = 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_init
    status = 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,启动 TrustZone
    status = 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/buffers
      are 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;
}






你可能感兴趣的:(车芯,SA8295P,源码分析,QAM8295,SA8295P,QAM8295P)