Msm8998 Cold Boot Flow示意图
qualcomm-boot-sequence.png

按下Power键后,启动ROM中的APPS PBL, PBL支持紧急下载功能,并且load启动XBL SEC。

XBL SEC启动流程

XBL SEC image是 从PBL到XBL之间的启动流程,有最高的权限。当XBL SEC跳转到XBL后, XBL开始运行在Non-secure模式。XBL SE包含在 XBL.ELF 文件中。 在boot_images/QcomPkg/Msm8998Pkg/Library/XBLLoaderLib路径下,有sbl1_Aarch64.s和sbl1.s xbl的main()函数。 根据编译buildit.py文件中的DEFAULT_COMPILER_ARCH = “AARCH64”和.inf文件,Msm8998选择编译sbl1_Aarch64.s, 相关程序如下:

__main:
_main:
sbl1_entry:
  // Save the passing parameter from PBL
  MOV x7, x0
………
  BL sbl1_main_ctl

这时跳转到boot_images/QcomPkg/Msm8998Pkg/Library/XBLLoaderLib/sbl1_mc.c文件中的sbl1_main_ctl()函数。

sbl1_main_ctl()函数

void sbl1_main_ctl(boot_pbl_shared_data_type *pbl_shared)
{
    DALResult bsy_wait_init;
    bl_error_boot_type secboot_ftbl_init;
  
    /* Calculate the SBL start time for use during boot logger initialization. */
    sbl_start_time = CALCULATE_TIMESTAMP(HWIO_IN(TIMETICK_CLK));

    /*Configure Domain access control register */
    mmu_set_dacr(DACR_ALL_DOMAIN_CLIENTS);
  
    /* Enable qdss workaround*/
    boot_clock_debug_init();
  
    /* Enter debug mode if debug cookie is set */
    sbl1_debug_mode_enter();
  
    /* Initialize the stack protection canary */
    boot_init_stack_chk_canary();
  
    /* Initialize boot shared imem */
    boot_shared_imem_init(&bl_shared_data);

    /* Zero out the SBL1 OCIMEM ZI */
    boot_ram_init(&sbl1_ram_init_data_ocimem);
    ……
    /* 在sbl1_boot_logger_init()函数之前,主要做 时钟、mem 、QSEE 等的初始化。在这之前,不能打印log 信息。
       sbl1_boot_logger_init(&boot_log_data, pbl_shared);
       当执行完此函数后,可以打印log信息。*/
    ……
}

sbl1_boot_logger_init() 函数

/* sbl1_boot_logger_init */
static void sbl1_boot_logger_init( boot_log_init_data *boot_log_data, boot_pbl_shared_data_type *pbl_shared)
{
    /*initialize boot logger ,

    boot_log_init(boot_log_data);
    /*initialize boot logger*/
    boot_log_set_init_info_marker();
    /* Write PBL timestamp milestones into beginning of log */
    boot_pbl_log_milestones(pbl_shared);
    /*Set the reference time to 0 as the start of boot*/
    boot_log_set_ref_time(0);
    /* Add SBL start entry using stored time from beginning of sbl1_main_ctl */
    boot_log_message_raw("SBL1, Start",
                       sbl_start_time,
                       LOG_MSG_TYPE_BOOT,
                       NULL);
}

boot_log_init在此函数中调用了boot_log_init_uart()函数,完成了uart 的初始化,可以开始打印log信息。 输出信息,需要修改boolean boot_uart_init(void)

boolean boot_uart_init(void)
{
    uart_initialize();
    uart_connection_status = FALSE;
    return TRUE;
}

这时开始打印SBL版本信息等。

XBL SEC各外设的初始化

在sbl1_main_ctl()函数 最后,调用如下执行RAM 、PMIC等入口函数列表的函数。 boot_config_process_bl(&bl_shared_data, SBL1_IMG,sbl1_config_table); 在sbl_config.c中的sbl1_config_table[]定义了启动构造表。

boot_configuration_table_entry sbl1_config_table[] = 
{
  /* SBL1 -> PMIC */
  {
    SBL1_IMG,                   /* host_img_id */
    CONFIG_IMG_QC,              /* host_img_type */
    GEN_IMG,                    /* target_img_id */
    CONFIG_IMG_ELF,             /* target_img_type */
    SECBOOT_PMIC_SW_TYPE,       /* target_img_sec_type */ 
    TRUE,                       /* load */
    TRUE,                       /* auth */
    FALSE,                      /* exec */
    FALSE,                      /* jump */
    NULL,                       /* exec_func */
    NULL,                       /* jump_func */
    load_pmic_pre_procs,        /* pre_procs */ 
    load_pmic_post_procs,       /* post_procs */
    pmic_load_cancel,           /* load_cancel */
 }
/*如load_pmic_pre_procs 中定义了 各初始化函数。*/
boot_procedure_func_type load_pmic_pre_procs[] = 
{
  /* Save reset register logs */
  boot_save_reset_register_log,
  /* Initialize the flash device */
  boot_flash_init,
  boot_config_data_table_default_init,
  …………
  }

UEFI启动的各阶段

qualcomm-uefi-stages.png

UEFI 有如上几个启动阶段:SEC–>DXE –> BDS –> ABLboot_images/QcomPkg/XBLCore目录下有ModuleEntryPoint.masmSec.c. 在Sec.c中的Main()函数如下:

Main (IN  VOID  *StackBase, IN  UINTN StackSize)
 {
        InitStackCanary();
        StartCyclCounter ();
        /* Start UART debug output */
        UartInit();
        PrintUefiStartInfo();
        InitializeCpuExceptionHandlers (NULL);
        PrintTimerDelta();
        /* Enable program flow prediction, if supported */
        ArmEnableBranchPrediction ();
        /* Initialize Info Block */
        UefiInfoBlkPtr = InitInfoBlock (UefiFdBase + UEFI_INFO_BLK_OFFSET);
        UefiInfoBlkPtr->StackBase = StackBase;
        UefiInfoBlkPtr->StackSize = StackSize;
        InitRamPartitionTableLib ();
        ValidateFdRegion(UefiFdBase);
        //TODO: Move this to ACPI-specific location
        InitializeFBPT();
    }

UEFI 调试

打开XBL SEC阶段的log 方法:

python ../buildit.py --variant LA -r DEBUG -t Msm8998Pkg,QcomToolsPkg

编译必须使用 DEBUG模式。

boolean boot_uart_init(void)
{
    uart_initialize();
    // 增加如下代码:
    uart_connection_status = FALSE;
    return TRUE;
}

参考文档

  • 80-p2484-37_c_linux_android_uefi_overview.pdf
  • 80-p2484-64_b_msm8998_boot_and_corebsp_architecture_overview.pdf
最后编辑:2020年03月19日 ©著作权归作者所有

已有 4 条评论

  1. 请问一下那个QcomPkg源代码是在哪里下载

      1. @evsio0n

        那怎么获取访问这些私密代码这些权限呢,是不是只有高通的员工才能下载?

发表评论

正在加载 Emoji
×