Android开机启动流程


Android开机启动流程:APPS PBL——>XBL——>ABL——>kernel——>init进程——>Zygote进程和VM——>System Servers进程——>启动APP(桌面)

在这里插入图片描述

我们来看下这几个涉及的模块大概功能:

  1. Application primary boot loader (APPS PBL)
    PBL 启动时,CPU只开启了第一个核心 CPU Core 0,运行固件在ROM中,这部分是高通写死在芯片中的固件,外部开发人员是无法修改这部份的。
    主要功能为:
    (1)系统安全环境的初始化,以确保后续的XBL中的APPS 能够正常运行。
    (2)根据boot gpio的配置选择从什么设备启动操作系统(如 Nand,USB等)。
    (3)通过检测GPIO判断是否进入Emergency Download mode,用户可以通过FILE来下载完整的系统镜像。
    (4)通过L2 TCM来加载XBL1 ELF,OCIMEM 和 RPM CodeRAM 代码。

  2. Extensible boot loader (XBL)
    从XBL开始,跑的就是我们编译下载进eMMC/UFS的系统镜像了,在XBL中主要是初始化相关的硬件环境,及代码安全环境。
    (1)初始化 Buses、DDR、Clocks、CDT,启动QSEE,QHEE,RPM_FW, XBL core images。
    (2)使能memory dump through USB and Sahara(系统死机时memory dump),看门狗,RAM dump to SD support等功能。
    (3)初始化 USB驱动,USB充电功能,温升检测,PMIC驱动初始化,和 DDR training模块。

PS:XBL也可称为Secondary bootloader,有时细分为SBL1、SBL2、SBL3;

  1. XBL core (UEFI or LK,ABL)
    XBL core,就是之前的bootloader,主要功能就是初始化display驱动,提供fastboot功能,引导进入HLOS kernel操作系统。
    注意,在ABL中,同样也只有CPU Core0在工作,其他的CPU核以是在进入HLOS Kernel后才开始初始化启用的。

一、APPS PBL(Application primary boot loader:主引导加载程序)

时钟等硬件的初始化;
CPU缓存和MMU管理器的初始化;
根据引导选项配置检测引导设备,默认顺序维UFS>SD>USB,默认启动选项可以被EDL Cookie或USB GPIO强制重写;

二、XBL(Extensible boot loader:可扩展引导加载程序)

UEFI代码运行流程

SEC(安全验证)—>PEI(EFI前期初始化)—>DXE(驱动执行环境)—>BDS(启动设备选择)—>UEFI Loader(操作系统加载前期)—>RT(Run Time)

在这里插入图片描述

SEC (安全验证)

SEC的汇编代码入口位于:
amss\BOOT.XF.1.4\boot_images\QcomPkg\XBLCore\AARCH64\ModuleEntryPoint.masm的 _ModuleEntryPoint中

  • 关闭所有中断
  • 关闭MMU和Caches
  • 关闭TLB缓存表
  • 获得当前运行的安全环境:EL1、EL2、EL3
  • 初始化ELX 安全环境
  • 使能 Cache
  • 初始化栈
  • 调用 CEntryPoint,传参 _StackBase(0x80C00000)、_StackSize(0x00040000)

SEC的C代码入口位于:
amss\BOOT.XF.1.4\boot_images\QcomPkg\XBLCore\Sec.c的 CEntryPoint 中

获得fdf文件所在的地址,fdf可以说是UEFI的配置文件,在fdf文件中包含所有的inf文件所在路径,及相关的bmp图片资源路径,以及相关的cfg配置文件路径。
初始化栈
启动定时器周期计数
初始化UART,主要是serial port端口初始化,及 serial buffer初始化
打印"UEFI Start" 串口信息
初始化CPU异常处理入口
打印从开机到现在的时间差
如果支持的话,启动程序流预测 /* Enable program flow prediction, if supported /
Initialize Info Block
初始化 RAM 分区表,起始地址0x80000000,内存大小512M,检查地址是否非法,是否可正常访问
初始化hoblist,有关hob可参考:https://blog.csdn.net/z190814412/article/details/85330324
打印RAM 分区信息
初始化cache
加载并解析 uefiplat.cfg平台配置文件
更新系统内存区相关信息 /
Add information from all other memory banks /
初始化所有的共享库 /
All shared lib related initialization /
初始化的lib源码位于 amss\BOOT.XF.1.4\boot_images\QcomPkg\Sdm660Pkg\Library
配置文件位于 amss\BOOT.XF.1.4\boot_images\QcomPkg\Sdm660Pkg\LA\Sdm660Pkg_Core.dsc
获得DXE Heap堆内存信息,/
Look for “DXE Heap” memory region in config file /
初始化分页池缓存区
创建Stack、CPU Hob信息
Display 早期初始化
开启耗费的时间统计,用于计算性能 /
Start perf here, after timer init, start at current tick value */
加载且将CPU交给 DXE Core。

DXE (驱动执行环境)

DXE的加载位置在:
amss\BOOT.XF.1.4\boot_images\EmbeddedPkg\Library\PrePiLib\PrePiLib.c的 LoadDxeCoreFromFv中

  • 初始化CPU异常处理情况
  • 初始化内存、事件等相关基础服务, 主要目的是初始化UEFI代码基础环境(这一大段代码有点看不懂,跳过)
  • 初始化DXE 调度器相关

BDS (启动设备选择)

代码位于:
amss\BOOT.XF.1.4\boot_images\QcomPkg\Drivers\BdsDxe\BdsEntry.c 的 BdsEntry 中

注册按键事件,按下按键后会回调到HotkeyEvent() 函数,最终调用到HotkeyCallback()函数中,解析其中的key scancode
平台BDS初始化
在其中会打印显示版本号,平台版本信息等等
调用LaunchDefaultBDSApps ()加载默认APP
调用SetupPlatformSecurity()初始化secureboot安全环境
挂载efisp分区
调用ReadAnyKey() 循环检测音量下键是否按下,从而更新对应的启动项
初始化所有 DriverOptionList 上的 驱动协议。
根据选择的启动方式,启动对应的的系统

RT(Run Time)

代码位于:
amss\BOOT.XF.1.4\boot_images\MdeModulePkg\Core\RuntimeDxe\Runtime.c的 RuntimeDriverInitialize 中

三、ABL(Applications Boot Loader:应用程序引导加载程序)

主要是为了引导内核启动

LinuxLoaderEntry()函数入口
BootLinux()内核加载函数

PS:高通在MSM8998上引入了UEFI,用来代替LK(Little Kernel)。高通UEFI由XBL和ABL两部分组成

XBL负责芯片驱动及充电等核心应用功能,XBL核心是none-HLOS boot_image代码的一部分,属于高通私有代码(在该阶段会进行项目、板级、器件等区分,并将区分的信息通过数据结构传递至ABL);
ABL包括芯片无关的应用如fastboot,并接收XBL一些初始化的信息并将其传递至kernel,ABL则在开源Linux Android代码树里(内核会解析传递进来的信息)。

LK的设备驱动都放在了XBL核心,Linux加载启动及fastboot等功能组件则作为独立的UEFI应用存在。

有关UEFI、XBL及ABL的详细介绍,请参见高通文档《80_P2484_37_LINUX_ANDROID_UEFI_OVERVIEW.pdf》。

详细链接:https://www.cnblogs.com/schips/p/qualcomm_about_uefi.html

四、Kernel

Android使用的linux kernel,当kernel启动时,会执行一系列的初始化操作,比如设置缓存,内存,加载驱动程序,挂载根文件系统,初始化输入输出等。

内核启动后的第一件事情就是找init,作为根文件系统或第一个进程。

路径:/arch/arm64/kernel/head.S

初始化阶段:
__primary_switch
__primary_switched
start_kernel() //路径:kernel/msm-4.4/init/main.c

rest_init() //路径:kernel/msm-4.4/init/main.c

kernel_init() //路径:kernel/msm-4.4/init/main.c

这时init进程已经运行。

五、init

init进程主要负责两件事:

  • 挂载(mount) /sys, /dev 或者/proc等文件
  • 运行/init.rc脚本,init.rc负责系统的初始化设置。//init.rc位置:/system/core/rootdir/init.rc
    init.rc脚本会启动servicemanager,创建zygote进程(fork方式)。
  • init.zygote64.rc

六、Zygote and VM

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server //格式命令:app_process [java-options] cmd-dir start-class-name [options]

runtime.start(“com.android.internal.os.ZygoteInit”, args, zygote); //路径:frameworks/base/cmds/app_process/app_main.cpp

runtime其实是类AndroidRuntime(路径:frameworks/base/core/jni/AndroidRuntime.cpp),函数start做两件事:

  • startVm()//启动虚拟机;
  • register_jni_procs() //注册系统库中的JNI方法
    env->CallStaticVoidMethod()(路径:frameworks/base/core/jni/AndroidRuntime.cpp)函数调用ZygoteInit.java中main()

调用forkSystemServer()创建ZygoteServer,进入该函数定义处 //frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

Zygote.forkSystemServer()是调用Zygote类的成员函数forkSystemServer //frameworks/base/core/java/com/android/internal/os/Zygote.java

Zygote是一个VM进程,这个时候就进入了Java世界了.System Server进程也创建了。

七、System Servers

main();//frameworks/base/services/java/com/android/server/SystemServer.java

SystemServer().run(); (同上路径)主要的工作是启动服务:

  • Bootstrap Service
  • Core Service
  • Other Service

八、启动App(桌面)

finishBooting(); 函数中有mSystemServiceManager.startBootPhase(); //路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

让系统service知道已经启动。

参考连接

https://www.cnblogs.com/Cqlismy/p/11972885.html

https://www.jiangkang.tech/2020/06/12/android/android-xi-tong-qi-dong-liu-cheng-fen-xi/#toc-heading-1

https://ciellee.blog.csdn.net/article/details/113519478

  • 8
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值