高通平台Android源码bootloader分析之sbl1(一)
高通平台Android源码bootloader分析之sbl1(二)
高通平台Android源码bootloader分析之sbl1(三)
高通8k平台的boot过程搞得比较复杂, 我也是前段时间遇到一些问题深入研究了一下才搞明白。不过虽然弄得很复杂,我们需要动的东西其实很少,modem侧基本就sbl1(全称:Secondary boot loader)的代码需要动一下,ap侧就APPSBL代码需要动(对此部分不了解,可参照:bootable源码解析),其他的都是高通搞好了的,甚至有些我们看不到代码。今天就要分析一下开机前几秒钟起着关键作用的sbl1, 这套代码在modem侧的boot_images\中。
启动流程
首先来看一下高通的bootloader流程框图,主要由ap、RPM及modem三部分构成,由于我工作主要涉及到ap侧,所以对RPM和modem侧代码不了解,以后有空时间的话到可以研究一下,框图如下:
由上图可知,系统启动流程主要由以下几步组成:
系统上电或重启。
在Cortex-a53芯片中,ap侧的PBL执行,从boot device中加载sbl1镜像到TCM,并对镜像进行校验,然后跳转到sbl1中继续执行.
sbl1初始化ddr,从boot device中加载QSEE镜像和QHEE镜像到DDR,并对镜像进行校验,QSEE执行并设置一个安全的环境,QHEE为VMM设置、SMMU配置及xPU访问控制服务。
sbl1从boot device加载RPM固件镜像到code-RAM,并对镜像进行校验。
sbl1从启动设备加载HLOS APPSBL镜像到ddr,并对镜像进行校验。
sbl1跳转到QSEE->QHEE。
QHEE通知RPM侧跳转到RPM固件中并自己跳转到HLOS APPSBL中执行。RPM侧开始执行RPM固件。
QHEE跳转到HLOS APPSBL中初始化系统。
HLOS APPSBL加载和校验HLOS内核。
由内核来加载文件系统等完成整个Android系统的启动。
HLOS APPSBL即为ap侧的bootloader,见:bootable源码解析
modem侧主要是射频网络相关的代码,我没有研究过也不了解,RPM侧的代码也没怎么研究,高通文档对其介绍如下:
sbl1流程分析
接下来我就来跟一下sbl1的代码,总结出关键流程,此部分代码皆在modem侧。我平时主要会涉及的几个重要文件:
1 | boot_images\core\boot\secboot3\hw\msm8916\sbl1\sbl1_hw.c |
首先从其入口文件sbl1.s开始,如下:
sbl1入口: sbl1.s
此部分代码路径在:boot_images/core/boot/secboot3/hw/msm8916/sbl1/sbl1.s,此文件引导处理器,主要有实现如下操作:
- 设置硬件,继续boot进程。
- 初始化ddr。
- 加载Trust_Zone操作系统。
- 加载RPM固件。
- 加载APPSBL然后继续boot进程。
关键源码如下:
1 | /*引入c函数,主要为异常实现函数,及一个关键函数sbl1_main_ctl*/ ; Import the external symbols that are referenced in this module. IMPORT |Image$$SBL1_SVC_STACK$$ZI$$Limit| IMPORT |Image$$SBL1_UND_STACK$$ZI$$Limit| IMPORT |Image$$SBL1_ABT_STACK$$ZI$$Limit| IMPORT boot_undefined_instruction_c_handler IMPORT boot_swi_c_handler IMPORT boot_prefetch_abort_c_handler IMPORT boot_data_abort_c_handler IMPORT boot_reserved_c_handler IMPORT boot_irq_c_handler IMPORT boot_fiq_c_handler IMPORT boot_nested_exception_c_handler IMPORT sbl1_main_ctl #主要关注此函数 IMPORT boot_crash_dump_regs_ptr ... # 关于中断向量配置等汇编语句,就没有去详细看了,我们一般也不会涉及到这么底层的东西 |
sbl1_main_ctl
此函数位于boot_images\core\boot\secboot3\hw\mdm9x45\sbl1\sbl1_mc.c,主要完成初始化RAM等工作, 注此函数决不return。部分关键源码如下,我加汉字解释的是我认为我们应该关注的部分:
1 | /* Calculate the SBL start time for use during boot logger initialization. */ |
sbl1_config_table
sbl1_config_table为一个结构体数组,里面存储了加载QSEE、RPM、APPSBL等镜像所需要的配置参数及执行函数,位于boot_images\core\boot\secboot3\hw\msm8909\sbl1\sbl1_config.c。其关键代码如下:
1 | boot_configuration_table_entry sbl1_config_table[] = |
load_qsee_pre_procs
load_qsee_pre_procs为一个函数结构体数组,在QSEE加载之前执行。源码注释写得很清楚并且容易理解,我就不多此一举去翻译了,关键源码如下:
1 | /* Save reset register logs */ |
load_qsee_post_procs
load_qsee_post_procs同样也为一个函数结构体数组,其在加载QSEE之后执行。关键源码如下:
1 | /* Enable the secure watchdog |
pm_chg_charger_detect_state
pm_chg_charger_detect_state函数是启动工程中非常重要的一个函数,它将监测电池的状态,然后决定启动过程,调用关系和解析如下:
1 | sbl1_hw_init_secondary |
pm_chg_sbl_charging_state_entry
pm_chg_sbl_charging_state_entry是充电状态机的入口函数, 如果充电状态不正确的话会造成死机,代码如下:
1 | pm_err_flag_type pm_chg_sbl_charging_state_entry(void) //called at the end of pm_driver_init |
pm_chg_process_sbl_charger_states
pm_chg_process_sbl_charger_states函数也是启动过程中非常重要的一个函数,此函数里面有一个死循环,用来更新充电状态或者关机,其被pm_chg_sbl_charging_state_entry函数调用(见上调用关系)。插上充电器开机前几秒就出现的重启问题, 多半是此部分出了状况。代码如下:
1 | static pm_err_flag_type pm_chg_process_sbl_charger_states(void) |