MTK6577+Android启动----pre-loader
备注:
META mode:Mobile Engineering Test Architecture,移动工程师测试架构
ATE factory mode:automatic test environment,自动测试环境
ISRAM:internal system RAM
Bootloader能够准备一个至关重要的执行环境和引导linux操作系统及Android框架(framework)。
bootloader主要包括设置处理器和内存的频率、调试信息端口、可引导的存储设备等等。在可执行环境创建好之后,接下来把software装载到内存并执行。除了装载software,一个外部工具也能和bootloader握手(handshake),可指示设备进入不同的操作模式,比如USB下载模式和META模式。就算没有外部工具的握手,通过外部任何组合或是客户自定义按键,bootloader也能够进入这些模式。
因为bootloader的一部分和系统有关,所以MTK为了不同的应用将它分为两部分的bootloader:
(1) 第1部分bootloader,也就是MTK内部(in-house)的pre-loader,这部分依赖平台。
(2) 第2部分bootloader,也就是u-boot,这部分依赖操作系统,负责引导linux操作系统和Android框架。
1. Pre-loader源代码
1.1 源代码目录
(1) Pre-loader的代码在xxx\mediatek\platform\mt6577\preloader
Pre-loader核心和平台驱动源码。
(2) xxx\mediatek\custom\<project>\preloader
依赖于平台自定义文件的部分(platform dependent customization),比如EMI(external memory interface,外部存储器接口)设置。
Inc文件夹:
1) cust_bldr.h
pre-loader的一些定制的特征,比如是从SDMMC还是NAND启动、调试口选择(UART1或是UART4)和波特率的配置等宏定义。
2) cust_msdc.h
MSDC的自定义,比如包括MSDC的时钟频率、命令锁存跳变沿(上升沿或是下降沿)、数据锁存的跳变沿、高速或是全速模式等等。
3) cust_nand.h
定义了所支持的NAND FLASH信息,比如FLASH ID、多少块、一块多少页等信息,但这些被注释掉了,主要定义了默认的访问时间等
4) cust_rtc.h
RTC年月日的默认设置。
5) cust_sec_ctl.h
一些安全设置的定义,比如包括了项目名称(比如cust)、平台名称(MT6577)、S-Boot的一些属性等。
6) cust_usb.h.h
USB设置的宏定义,包括USB制造商、USB供应商ID(VID)、USB识别码ID(PID)等。
7) custom_emi.h
扩展存储器接口的寄存器和设置的结构体定义。
8) custom_MemoryDevice.h
定了采用的内存设备类型,比如H9TP32A4GDMCPR。
9) mt6577_emi.h
mt6577内存的一些函数原型,如:
extern voidmt6516_set_emi (void);
extern voidmt6516_256M_mem_setting (void);
10) mt6577_emi_reg.h
内存控制寄存器的宏定义。
11) mt6577_memory.h
内存的一些设置,比如用于内存测试的大小、E1和E2内存的大小和一些函数原型。
12) mt6577_nfi.h
nfi是Nand Flash Interface的缩写,和cust_nand.h内容一样。
(3) xxx\mediatek\source\preloader
开发工具,例如building、trace32 cmm文件等,pre-loader对象和镜像二进制输出文件
1.2 编译命令
Pre-loader单独的编译命令:./mk <$PROJECT> n pl
U-Boot单独的编译命令:./mk <$PROJECT> n ub
2. bootloader的工作流程
2.1 bootloader正常的启动流程
先来看启动流程图:
图1
正常启动的主要工作如下:
(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内核并执行。
2.2 bootloader正常的下载流程
先来看正常的下载流程图:
图2
正常的下载主要工作如下:
(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中。
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中。
3. 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)
对于安全的执行环境,安全引导程序会检查(checking)或是查证(verification),这样能够保护我们的芯片被攻击(hacked)。
4. Bootloader硬件环境
当设备上电后,bootloaders被加载到不同的内存区域并执行,如下图所示:
图3
Pre-loader在芯片内部系统(chipset’s internal system)RAM的0Xc2010000位置开始执行,U-Boot在外部RAM的0x01E00000处执行。当bootloaders执行时,初始化多种硬件模块来创建一个可执行的环境,具体是哪些硬件模块,下面有详细的描述。
4.1 pre-loaders中涉及的硬件部分
当系统启动时,芯片组(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来保持设备一直有电(keep the device alive)和继续引导U-Boot。
2) RTC闹钟(alarm)有可能是设备开机的启动源,对于这种情况,设备部需要按power按键就可自动启动。
(8) USB模块
当USB线插入时,它初始化来和外部工具通信,比如用于升级系统的下载工具或是META模式触发器的META工具。
(9) NAND模块
(10) MSDC模块
Pre-loader可以从NAND flash或是EMMC中加载U-Boot,这两者只能选择其中一种来启动。
4.2
5. Pre-loader的过程(procedure)和流程(flow)
如下图:
图4
具体的源代码后面再分析了。
6. Pre-loader的接口
主要描述pre-loader用到的主要结构体和接口。
6.1 上电情景(power on scenario)
当检测到按下power按键或是USB/充电线插入,pre-loader调用rtc_bbpu_power_on()函数来锁存RTC的PWBB来保持设备的一直供电,这样就算是松开power按键设备也不会关机。
此函数在xxx \mediatek\platform\mt6577\preloader\src\drivers\mt6577_rtc.c文件定义。
6.2 下载过程(download procedure)
Pre-loader检查下面的条件:
(1) 充电器已连接(charger is connected)
(2) USB已连接
(3) Flash工具的握手是否通过
如果满足上面这几种要求,pre-loader就会开始下载镜像。
接下来介绍下载的镜像定义,也允许增加我们要下载的镜像文件,这涉及的数据结构体和函数如下,在xxx\mediatek\platform\mt6577\preloader\src\core\inc中定义:
(1) 下载镜像类型定义
(2) 下载镜像枚举定义
(3) 下载镜像的主函数download_handler
Pre-loader接收到从flash工具传递进来的“DOWNLOAD”字符串时,download_handler函数开始下载镜像:
图5
此函数在xxx\mediatek\platform\mt6577\preloader\src\core\download_legacy.c定义。