0
点赞
收藏
分享

微信扫一扫

【SemiDrive源码分析】【X9芯片启动流程】28 - AP1 Android SMC 指令进入 EL3 环境执行 ATF 镜像(加载并跳转 bootloader)


【SemiDrive源码分析】【X9芯片启动流程】28 - AP1 Android SMC 指令进入 EL3 环境执行 ATF 镜像(加载并跳转 bootloader)

  • ​​一、SMC Handler​​
  • ​​二、EL3环境下执行 atf 镜像​​

本 SemiDrive源码分析 之 Yocto源码分析 系列文章汇总如下:

  1. 《​​【SemiDrive源码分析】【Yocto源码分析】01 - yocto/base目录源码分析(编译环境初始化流程)​​》
  2. 《​​【SemiDrive源码分析】【Yocto源码分析】02 - yocto/meta-openembedded目录源码分析​​》
  3. 《​​【SemiDrive源码分析】【Yocto源码分析】03 - yocto/meta-semidrive目录及Yocto Kernel编译过程分析(上)​​》
  4. 《​​【SemiDrive源码分析】【Yocto源码分析】04 - yocto/meta-semidrive目录及Yocto Kernel编译过程分析(下)​​》
  5. 《​​【SemiDrive源码分析】【Yocto源码分析】05 - 找一找Yocto Kernel编译过程中所有Task的源码在哪定义的呢?​​》
  6. 《​​【SemiDrive源码分析】【Yocto源码分析】06 - Kernel编译生成的Image.bin、Image_nobt.dtb、modules.tgz 这三个文件分别是如何生成的?​​》
  7. 《​​【SemiDrive源码分析】【Yocto源码分析】07 - core-image-base-x9h_ref_serdes.rootfs.ext4 文件系统是如何生成的​​》
  8. 《​​【SemiDrive源码分析】【X9芯片启动流程】08 - X9平台 lk 目录源码分析 之 目录介绍​​》
  9. 《​​【SemiDrive源码分析】【X9芯片启动流程】09 - X9平台系统启动流程分析​​》
  10. 《​​【SemiDrive源码分析】【X9芯片启动流程】10 - BareMetal_Suite目录R5 DIL.bin 引导程序源代码分析​​》
  11. 《​​【SemiDrive源码分析】【X9芯片启动流程】11 - freertos_safetyos目录Cortex-R5 DIL2.bin 引导程序源代码分析​​》
  12. 《​​【SemiDrive源码分析】【X9芯片启动流程】12 - freertos_safetyos目录Cortex-R5 DIL2.bin 之 sdm_display_init 显示初始化源码分析​​》
  13. 《​​【SemiDrive源码分析】【X9芯片驱动调试】13 - GPIO 配置方法​​》
  14. 《​​【SemiDrive源码分析】【X9芯片启动流程】14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析​​》
  15. 《​​【SemiDrive源码分析】【X9芯片启动流程】15 - freertos_safetyos目录 R5 SafetyOS 之 tcpip_init() 代码流程分析​​》
  16. 《​​【SemiDrive源码分析】【X9 Audio音频模块分析】16 - 音频模块框图及硬件原理图分析​​》
  17. 《​​【SemiDrive源码分析】【X9芯片启动流程】17 - R5 SafetyOS 之 LK_INIT_LEVEL_PLATFORM 阶段代码流程分析(上)dcf_init 核间通信初始化​​》
  18. 《​​【SemiDrive源码分析】【X9芯片启动流程】18 - R5 SafetyOS 之 LK_INIT_LEVEL_PLATFORM 阶段代码流程(下)启动QNX、Android​​》
  19. 《​​【SemiDrive源码分析】【X9芯片启动流程】19 - MailBox 核间通信机制介绍(理论篇)​​》
  20. 《​​【SemiDrive源码分析】【X9芯片启动流程】20 - MailBox 核间通信机制介绍(代码分析篇)之 MailBox for RTOS 篇​​》
  21. 《​​【SemiDrive源码分析】【X9芯片启动流程】21 - MailBox 核间通信机制介绍(代码分析篇)之 Mailbox for Linux 篇​​》
  22. 《​​【SemiDrive源码分析】【X9芯片启动流程】22 - MailBox 核间通信机制介绍(代码分析篇)之 RPMSG-VIRTIO Kernel 篇​​》
  23. 《​​【SemiDrive源码分析】【X9芯片启动流程】23 - MailBox 核间通信机制介绍(代码分析篇)之 RPMSG-IPCC Kernel 篇​​》
  24. 《​​【SemiDrive源码分析】【X9芯片启动流程】24 - MailBox 核间通信机制相关寄存器介绍​​》
  25. 《​​【SemiDrive源码分析】【X9芯片启动流程】25 - MailBox 核间通信机制介绍(代码分析篇)之 RPMSG-IPCC RTOS & QNX篇​​》
  26. 《​​【SemiDrive源码分析】【X9芯片启动流程】26 - R5 SafetyOS 之 LK_INIT_LEVEL_TARGET 阶段代码流程分析(TP Drvier、Audio Server初始化)​​》
  27. 《​​【SemiDrive源码分析】【X9芯片启动流程】27 - AP1 Android Preloader启动流程分析(加载atf、tos、bootloader镜像后进入BL31环境)​​》
  28. 《​​【SemiDrive源码分析】【X9芯片启动流程】28 - AP1 Android SMC 指令进入 EL3 环境执行 ATF 镜像(加载并跳转 bootloader)​​》
  29. 《【SemiDrive源码分析】【X9芯片启动流程】29 - AP1 Android Bootloader启动流程分析(加载并跳转kernel)》
    .
  30. 《【SemiDrive源码分析】【X9芯片启动流程】28 - MailBox 核间通信机制介绍(代码分析篇)之 Property篇》
  31. 《【SemiDrive源码分析】【X9芯片启动流程】29 - MailBox 核间通信机制介绍(代码分析篇)之 RPCall篇》
  32. 《【SemiDrive源码分析】【X9芯片启动流程】30 - MailBox 核间通信机制介绍(代码分析篇)之 Notify篇》
  33. 《【SemiDrive源码分析】【X9芯片启动流程】31 - MailBox 核间通信机制介绍(代码分析篇)之 Socket篇》
  34. 《【SemiDrive源码分析】【X9芯片启动流程】32 - MailBox 核间通信机制介绍(代码分析篇)之 /dev/vircan篇》


在前面文章,我们分析到,启动 ​​AP1​​​时:
​​​atf​​​、​​tos​​​ 这两个镜像在加载完成后,由于其​​flag​​​为​​PT_SAVE_F​​​,加载后会将这两个镜像放入​​boot_args​​​中。
​​​bootloader ​​​则在加载后,由于其​​flag​​​为​​PT_KICK_F​​​,则会配置 ​​arg1=atf的entry​​​, ​​arg3 = tos的entry​​​ 接下来,调​​smc​​ 指令,触发一个异常后,至此 ​​android preloader​​ 生命周期结束。

我们来看下 ​​smc​​指令:

smc(SMC_RUN_IMAGE_BL31, arg1, arg2, arg3, 0, 0, 0, 0);

# buildsystem\rtos\lk\arch\arm64\asm.S
FUNCTION (smc)
smc #0

意思就是,此时​​smc​​​指令触发异常后,会进入 ​​SMC_RUN_IMAGE_BL31​​​ 环境,传参分别为 ​​arg1=atf​​​, ​​arg3 = tos​

​ATF​​​镜像对应的分区名为:​​eMMC1_ATF_A​​​​TOS​​镜像对应的分区名为:​​eMMC1_TOS_A​​ (​​Trusty OS​​)



一、SMC Handler

​smc handler ​​​定义在此,最终通过​​eret​​​ 指令,跳转到 ​​EL3​​ 环境执行,主要工作如下:

  1. 将​​SMC_RUN_IMAGE_BL31​​​ 的值放入​​X9​​​寄存器中,将其与​​x0 ​​​寄存器比较,如果相等则执行​​smc_run_bl31​​ 函数
  2. 在​​smc_run_bl31​​​ 函数中,通过比较​​scr​​​ 寄存器的​​NS​​ 位来判断当前环境是否安全,如果不安全则产生异常。
  3. 将​​X1​​​值传入​​elr_el3​​​中,也就是​​atf​​​镜像的​​ entry​​​地址,此时​​elr_el3 = atf_entry​
  4. 配置​​EL3​​​ 环境​​spsr ​​​寄存器的值为​​#0x1cd​
  5. 禁止​​EL3​​​ 的​​MMU​​​ 的指令​​cache​
  6. 将​​arg2​​​ 保存在​​x0​​​ 寄存器中,此时​​x0 = 0​
  7. 将​​arg3​​​ 保存在​​x1​​​ 寄存器中,此时​​x1 = tos_entry​
  8. 将​​arg4​​​ 保存在​​x2​​​ 寄存器中,此时​​x2 = 0​
  9. 开始跳转到​​EL3​​​环境执行​​atf_entry​

# buildsystem\rtos\lk\arch\arm64\exceptions_el3.S
/* ----------------------------------------------
* Detect if this is a RUN_IMAGE or other SMC.
* ----------------------------------------------
*/
mov x9, #SMC_RUN_IMAGE_BL31 // 将 SMC_RUN_IMAGE_BL31 的值放入X9寄存器中
cmp x9, x0 // x0 代表是第一个参数,也就是SMC_RUN_IMAGE_BL31
b.eq smc_run_bl31 // 比较,如果相等,则运行 smc_run_bl31 函数
==============>
+ FUNCTION(smc_run_bl31)
+ /* ------------------------------------------------
+ * Make sure only Secure world reaches here. non secure world smc can not boot bl31 img
+ * ------------------------------------------------
+ */
+ mrs x30, scr_el3 // 取scr寄存器的值
+ tst x30, #SCR_NS_BIT // 比较scr寄存器中的NS位 与 SCR_NS_BIT是否相等
+ b.ne unexpected_sync_exception // 如果当前NS位为非安全位,则说明当前环境不安全,产生unexpected_sync_exception异常
+
+ /* ---------------------------------------------------------------------
+ * Pass EL3 control to next BL image.
+ * Here it expects X1 with the address of a entry_point_info_t
+ * structure describing the next BL image entrypoint.
+ * spsr_el3 value 0x1cd comefrom g_spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS)
+ * ---------------------------------------------------------------------
+ */
+ mov x29, #0x1cd
+ msr elr_el3, x1 // 将 X1值传入 elr_el3中,也就是 atf镜像的 entry地址
+ msr spsr_el3, x29 // 配置 EL3 环境 spsr 寄存器的值为 #0x1cd
+
+ bl disable_mmu_icache_el3 // 禁止 EL3 的MMU的指令cache
+ tlbi alle3
+ dsb ish /* ERET implies ISB, so it is not needed here */
+
+ mov x0, x2 /* bl32 image addr */ // 将 arg2 保存在 x0 寄存器中,此时 x0 = 0
+ mov x1, x3 /* bl33 image addr */ // 将 arg3 保存在 x1 寄存器中,此时 x1 = tos
+ mov x2, x4 /* linux dtb base */ // 将 arg4 保存在 x2 寄存器中,此时 x2 = 0
+ eret // 开始跳转到 EL3环境执行 atf_entry
<==============
mov x9, #0xc4000000
movk x9, #0x21
cmp x9, x0
bne 1f
mrs x10, scr_el3
bic x10, x10, #0x100 /* Disable SCR_EL3.HCE */
msr scr_el3, x10
1:



二、EL3环境下执行 atf 镜像

​ATF​​​镜像对应的分区名为:​​eMMC1_ATF_A​​​​TOS​​镜像对应的分区名为:​​eMMC1_TOS_A​​ (​​Trusty OS​​)

我们来看下它们对应的镜像,分别是什么:

最开始想到的是通过下载工具来看,可以看出,镜像对应为 ​​atf.img​​​, ​​tos.img​​,

没毛病,但最大的问题是跟代码对应不上,我还是母鸡它们对应的是代码中是哪个镜像或哪些代码。

【SemiDrive源码分析】【X9芯片启动流程】28 - AP1 Android SMC 指令进入 EL3 环境执行 ATF 镜像(加载并跳转 bootloader)_启动流程


通过上面还是没找到镜像,

想了下,这个是打包后改名的镜像,那我们抓下打包 log 看看,整理如下:

vbmeta_emmc_desc: binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/dil2.bin:dil2:sha256:hash 
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/preloader_ivi.bin:preloader:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/ddr_fw.bin:ddr_fw:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/ddr_init_seq.bin:ddr_init_seq:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/ssystem.bin:ssystem:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/system_config.img:system_config:sha256:hash
image_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/fat_res.img:res:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/safety.bin:safety_os:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/dtb:dtb:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/qnx.img:cluster_kernel:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/clusterbootloader.bin:cluster_bootloader:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/preloader_cluster.bin:cluster_preloader:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/ivibootloader.bin:bootloader:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/fake_tos.img:tos:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/smlap2.bin:cluster_atf:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/fake_cluster_tos.img:cluster_tos:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/sml.bin:atf:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/boot.img:boot:sha256:hash
binary_X9HP_Ref_Isolation_Android_Qnx_Serdes_8G_emmc_3200/dtbo.img:dtbo:sha256:hash

还真找到了!!!



​atf​​​ 镜像分别为 ​​smb.bin​​​ 和 ​​smlap2.bin​​​​tos​​ 镜像分别为 ​​fake_tos.img​​ 和 ​​fake_cluster_tos.img​

在代码中找下,发现它是预编译好的。。。。

【SemiDrive源码分析】【X9芯片启动流程】28 - AP1 Android SMC 指令进入 EL3 环境执行 ATF 镜像(加载并跳转 bootloader)_源码分析_02


​GG​​​ ,那 ​​ATF​​ 的代码是看不到了。

那我们只能结合文档的描述:

​AP1 preloader​​​ 在触发 ​​AP2 watchdog​​​ 后,接着从 ​​eMMC​​​ 中加载 ​​ATF​​​,​​TOS​​​,​​bootloader​​​,
然后 进入​​​ATF​​​,由ATF切换到​​non-secure world​​​ 运行​​bootloader​​​,
​​​bootloader​​​从​​eMMC​​​中加载​​kernel​​​, ​​dtb​​ 等镜像并运行。



可以看出,​​ATF​​​ 的主要作用是启动 ​​bootloadder​​​,那既然 ​​ATF​​​的代码看不到,那我们只能跳过它,看它的下一步,​​bootloader​​ 了

好,本文就先写到这吧,

快晚上11点了,太晚了,先下班了,等下打个车回家,估计11点半应该能到家。

下文,我们进入​​Android bootloader​​ 来分析下。


举报

相关推荐

0 条评论