基于MT6752的Android系统启动流程分析报告1、Bootloader引导 (2)2、Linux内核启动 (23)3、Android系统启动 (23)报告人:日期:2016.09.03对于Android整个启动过程来说,基本可以划分成三个阶段:Bootloader引导、Linux kernel启动、Android启动。
但根据芯片架构和平台的不同,在启动的Bootloader阶段会有所差异。
本文以MTK的MT6752平台为例,分析一下基于该平台的Android系统启动流程。
1、Bootloader引导1.1、Bootloader基本介绍BootLoader是在操作系统运行之前运行的一段程序,它可以将系统的软硬件环境带到一个合适状态,为运行操作系统做好准备,目的就是引导linux操作系统及Android框架(framework)。
它的主要功能包括设置处理器和内存的频率、调试信息端口、可引导的存储设备等等。
在可执行环境创建好之后,接下来把software装载到内存并执行。
除了装载software,一个外部工具也能和bootloader握手(handshake),可指示设备进入不同的操作模式,比如USB下载模式和META模式。
就算没有外部工具的握手,通过外部任何组合或是客户自定义按键,bootloader也能够进入这些模式。
由于不同处理器芯片厂商对arm core的封装差异比较大,所以不同的arm处理器,对于上电引导都是由特定处理器芯片厂商自己开发的程序,这个上电引导程序通常比较简单,会初始化硬件,提供下载模式等,然后才会加载通常的bootloader。
下面是几个arm平台的bootloader方案:marvell(pxa935) : bootROM + OBM + BLOBinformax(im9815) : bootROM + barbox + U-bootmediatek(mt6517) : bootROM + pre-loader + U-bootbroadcom(bcm2157) : bootROM + boot1/boot2 + U-boot而对MT6752平台,MTK对bootloader引导方案又进行了调整,它将bootloader分为以下两个部分:(1) 第1部分bootloader,是MTK内部(in-house)的pre-loader,这部分依赖平台。
(2) 第2部分bootloader,是LK(little kernel的缩写,作用同常见的u-boot差不多),这部分依赖操作系统,负责引导linux操作系统和Android框架。
1.2、bootloader的工作流程1.2.1 bootloader正常的启动流程先来看启动流程图:正常启动的主要工作如下:(1) 设备上电后,Boot ROM开始运行。
(2) BootROM初始化软件堆栈(software stack)、通信端口和可引导存储设备(比如NAND/EMMC)。
(3) BootROM从存储器中加载pre-loader到内部SRAM(ISRAM)中,因为这时候还没有初始化外部的DRAM。
(4) BootROM跳转到pre-loader的入口处并执行。
(5) Pre-loader初始化DRAM和加载U-Boot到RAM中。
(6) Pre-loader跳转到U-Boot中并执行,然后U-Boot做一些初始化,比如显示的初始化等。
(7) U-Boot从存储器中加载引导镜像(boot image),包括linux内核和ramdisk(Android呢?)(8) U-Boot跳转到linux内核并执行。
正常的下载主要工作如下:(1) 设备上电后,Boot ROM开始运行。
(2) BootROM初始化软件堆栈(software stack)、通信端口和可引导存储设备(比如NAND/EMMC)。
(3) BootROM通过UART/USB和flash工具握手。
(4) BootROM通过UART下载pre-loader镜像到NAND flash/EMMC中,然后重启。
(5) BootROM加载pre-loader到内部SRAM汇总,因为DRAM还没有初始化。
(6) BootROM跳转到pre-loader并执行。
(7) Pre-loader初始化DRAM和通过USB与flash工具握手。
(8) Pre-loader通过USB下载其余镜像文件,比如U-Boot、boot image、recovery image、android system image、user data到NAND FLASH/EMMC中。
1.2.3 Bootloader备用的下载流程(emergency download procedure)(1) 设备上电后,Boot ROM开始运行。
(2) BootROM初始化软件堆栈(software stack)、通信端口和可引导存储设备(比如NAND/EMMC)。
(3) BootROM在emergency DL按键按下后,通过USB和flash工具握手。
(4) BootROM通过USB把指定的镜像文件下载到NAND FLASH/EMMC中。
1.3、Pre-loader启动过程1.3.1 Pre-loader的功能pre-loader是MTK内置的loader,它的主要功能如下:(1) 负责在芯片组平台(chipset platform)上准备好可执行的环境(2) 如果外部工具有效,它会试图通过UART或是USB来和外部工具握手。
(3) 从NAND/EMMC加载U-Boot,并跳转到U-Boot。
(4) 使用工具握手,设备能够触发进入下载模式来下载需要的镜像,或是进入工厂/测试模式,比如META模式和ATE工厂模式,在这些模式下可以测试模块,或是通过传递引导参数给U-Boot和linux内核来校准设备(device calibration)1.3.2 Pre-loader中涉及的硬件部分当系统启动时,芯片组(chipset)内部的可引导ROM开始执行,并从可引导存储设备(NAND/EMMC等等)上拷贝pre-loader。
所以,需要通过初始化一些硬件模块来为软件创造必要的可执行环境(essential execution environment),所有这些硬件模块在接下来描述。
(1) PLL模块1) PLL模块用于调整处理器和外部内存的频率。
2) 在PLL模块初始化后,处理器和外部内存的频率可由26MHZ/26MHZ增加到1GHZ/192MHZ。
(2) UART模块1) UART模块用于调试或是META模式下的握手。
2) 默认情况下,UART4初始化波特率为9216000bps和用于调试信息的输出,UART1初始化为115200bps和作为UART META默认端口。
但也可以使用UART1作为调试或是UART META端口。
(3) 计时器(timer)模块这是个基本的模块,用来计算硬件模块所需要的延时或是超时时间。
(4) 内存模块1) Pre-loader由boot ROM加载和在芯片组内部的SRAM中执行,因为外部的DRAM还没有初始化。
2) 为了准备软件整个可执行环境,pre-loader采用内置的内存设置来初始化DRAM(DRAM is initialized upon pre-loader built-inmemory settigns)。
这样,U-Boot 就能够被加载到DRAM中并执行。
(5) GPIO模块(6) PMIC模块为了提供一些基本的硬件功能,比如控制外设电源,pre-loader初始化上层模块(upper modules)。
(7) RTC模块1) 当通过power按键开机后,pre-loader拉高RTC的PWBB来保持设备一直有电(keepthe device alive)和继续引导U-Boot。
2) RTC闹钟(alarm)有可能是设备开机的启动源,对于这种情况,设备部需要按power按键就可自动启动。
(8) USB模块当USB线插入时,它初始化来和外部工具通信,比如用于升级系统的下载工具或是META模式触发器的META工具。
(9) NAND模块(10) MSDC模块Pre-loader可以从NAND flash或是EMMC中加载U-Boot,这两者只能选择其中一种来启动。
1.3.3 Pre-loader的过程(procedure)和流程(flow)1.3.4 pre-loader的上电情景函数位置在:\mediatek\platform\mt6752\preloader\src\core\download.c定义。
1.3.6 具体的代码分析过程代码位置:\mediatek\platform\mt6752\preloader\src\core\main.c代码位置:mediatek\platform\mt6752\preloader\src\core\handshake_usb.c代码位置:mediatek\platform\mt6752\preloader\src\src\drivers\usbtty.c代码位置:\mediatek\platform\mt6752\preloader\src\core\handshake_usb.c代码位置:\mediatek\platform\mt6752\preloader\src\core\download.c 从Bus_hound分析工具,可以看到usb与flash tool工具的握手情况。
1.4、LK启动过程LK是little kernel的简称,是一种bootloader(作用同常见的u-boot差不多),是Travis Geiselbrecht开发的一个开源项目,github地址为git:///travisg/lk.git,而mtk的代码中就用到了LK。
它由pre-loader引导并执行。
从根本上来说(basically),pre-loader已经初始化了相关的硬件模块,而不需要在LK中重新配置这些模块了。
但一些模块在LK中被重新复位来配置硬件寄存器,这样可创造一个干净的环境。
比如计时器模块,在LK中,计时器重新复位清零硬件计数来对计时进行复位。
所有在LK中需要初始化的列在下面:(1) 计时器模块通过复位硬件寄存器来复位计时。
(2) 串口模块LK采用串口模块来配置它的输入/输出系统,在这个模块初始化后,我们可以使用LK提供的“printf(…)”等函数来使用串口功能。
(3) I2C模块(4) PWM模块(5) PMIC模块(6) RTC模块和计时器模块一样,在LKt中,I2C/PMIC/RTC重新复位寄存器来复位这些模块。