Linux/Android系统知识之Qcom Platform开机流程概述

前言

高通芯片平台种类众多涵盖低端到高端的各种档次种类繁多:低端有诸如8909,中端有8916、8929、8937等,高端的有8953、8953、8953pro、8993,8996、8996pro。从存储介质上讲,从早期emmc慢慢发展到emcp最终由向ufs转化的趋势,运行位数更是从早期的32位全体过渡到64位地址总线。科技发展日新月异成果遍地!

也正是由于技术和平台的差异较大,很难通过一篇文章来穷尽所有高通平台的流程。好在所有的chip在boot时有很大的通性,便于举一反三,故本文将以2017年正在使用的Qcom平台为例,带领大家从宏观上把握开机流程的核心。

子系统模块架构

要了解高通的平台,必须先了解下芯片中集成了那些子系统(SubSystem)。与Intel的做法不同,高通芯片中所包含的子系统数量多,集成度高,这些子系统都有各自独立的cpu,只要在开机过程中通过主cpu子系统(APPS)引导/烧录进对应的firmware,就可以地独立运行起来。

在较新的高通芯片中较常见到的子系统(SubSystem)有下面这些:

SubSystem Function
APPS (Application Processer Subsystem) 主CPU
RPM (Resource Power Manager) 电源管理模块(带独立cpu)
Venus 高通的图像处理模块
LPASS (LowPower Audio Subsystem)音频处理模块
WCNSS (Pronto) Wifi模块
Modem Modem处理器或称之为baseband
TZ (TrustZone) Arm平台负责Security的Cpu,主系统可通过scm call与之通讯获取想要的数据

Boot流程

既然芯片中集成了这么多颗cpu,讲解开机流程的核心就演变为讲解主cpu是如何逐步引导子cpu完整boot的流程了。

  1. 按PowerKey引导主CPU Reset
  2. cpu抓取存取器(emmc or ufs)中已预先烧入的sbl1 fw 执行。
    • 将sbl1fw加载到L2缓存
    • 将rpm的初始化引导代码(存放在sbl1中)加载到rpm子系统中
    • jump到L2中执行sbl1(因为DDR还没初始化,所以此时在cache中运行最为方便)
  3. sbl1开始初始化DDR为后续大内存的使用代码提供运行环境
  4. sbl1将TZ img加载到DDR中
  5. sbl1将RPM的firmware(img)导入rpm子系统中
  6. sbl1将HLOS APPSBL Image(指的是lk即little kernel,有人习惯称之为aboot或是大家尝叫的BootLoader;其中的HLOS是Qcom常用的说法,指的是High-Level Operationg System)引导进DDR
  7. sbl1将执行权转交给TZ,完成系统安全环境(TrustZone)的建立、xpu的初始化和fuse的代码支援(security boot)
  8. TZ开始设置memory和io接口的访问权限,并通知RPM子系统开始运行
  9. TZ将引导执行HLOS APPSBL(LK)代码,并转移执行权到LK
  10. LK根据此时用户的按键行为(是否长按音量键等)决定下一步的运行模式。

    Boot模式一般有如下三种: 
    1:Normal Boot(boot进kernel)
    2:Fastboot Mode
    3:Recovery Mode
    
    我们这里将只分析Normal Boot的情况
  11. LK加载Kernel

  12. LK通过执行SCM call将执行权转交给kernel
  13. Kernel通过PIL(Peripheral image loader)将MBA(Modem Boot Authenticator)加载到DDR
  14. Kernel开始warm reset(warm reset DDR 不会掉电,内存数据保留) Modem的Cpu以便MBA开始boot流程,等待Modem完整Firmware的到来
  15. Kernel通过PIL加载Modem img到DDR
  16. Modem cpu开始正常启动
  17. Kernel通过PIL加载WCNSS img到DDR,然后warm reset wcnss子系统以便WCNSS img被正常执行
  18. Kernel通过PIL加载LPASS img到DDR,然后warm reset LPASS子系统以便LPASS img被正常执行
  19. Kernel通过PIL加载并执行Venus img
  20. kernel继续正常boot,调用init和zygote将android系统调用起来

这样一来,所有的子系统都正常开始执行,并且我们有了一个security的环境(TZ),来保证与用户隐私和权限相关的data会非常安全。

总结

上面的流程是基于中高端高通平台的通用流程,有些细节在不同平台上有细小的区别故没有特意展开。在8996平台上,高通引入了xbl这样的新机制替代了sbl1,但他们功能类似,行为相仿。

每个子系统由于都是独立的cpu,可能有些读者会产生这样的疑惑:万一某个子系统运行不正常,那Kernel如何才能对他们进行有效监控和管理呢?高通引入了QMI(Qcom Message Interface)的接口,让各个子系统可以通过其进行较为高效的数据交换,当然这些数据是可以包含系统日志(log)的,这样我们就可以对其进行一定程度上的管理和监控了。当然,我们还有一系列的driver节点,可以通过其对子系统进行reset和clock的管理。最最重要的是,每个子系统都提供了一个sub-system restart的监控节点,这样只要某个子系统异常宕机(例如modem偶尔重启,用户可能看到短暂的无服务),我们可以通过modem的引导程序,将modem子系统的整个运行内存状态完整的dump出来,这样就可以分析crash前的所有变量和堆栈状态了。

了解高通平台的boot流程,对做bsp的同仁来说是十分有必要的,我们bring up某个新平台的EVB主板时,有了基础知识才能很找到不开机时的问题点,才能尽快进行针对性的debug。

顺便分享点经验:电池电量,电池id电阻,DDR是否有部分虚焊点是常常导致无法开机的元凶。这些问题可以通过log或在edl mode下烧入不同的firehouse来快速验证。

欢迎大家提出宝贵意见和建议,共同成长。

你可能感兴趣的:(Linux/Android系统知识之Qcom Platform开机流程概述)