一、preloader流程简介
1、启动流程
(1)设备上电起来后,跳转到Boot ROM(不是flash)中的bootcode中执行把pre-loader加载起到ISRAM, 因为当前DRAM(RAM分SRAM跟DRAM,简单来说SRAM就是cache,DRAM就是普通内存)还没有准备好,所以要先把pre-loaderload到芯片内部的ISRAM(Internal SRAM)中。
(2)preloder的主要工作是初始化环境,包括c环境,timer,gpio,pmic,uart,i2c等以及装载LK镜像至DRAM中。
(3)如果实现了ATF,preloader加载完lk分区后,还会加载tee分区,在设置好环境后,会先跳转到EL3。
(4)EL3回到lk,执行lk流程,preloader流程结束。
2、下载流程
preloader除了具有启动功能之外,还具有下载功能。首先还是需要明确的是mtk芯片都的有个boot rom,如果没有这个rom那么,那么程序是无法被下载到nandflash中的,然后此时的flash上是为空的,没有任何数据的。系统在上电之后它会检测是启动模式还是下载模式,如果是下载模式,它会初始化一个usb的串口,将preloader加载到内部的SRAM中,跳转到preloader中去执行,初始化好flash和外部RAM之后,依次将preloader、lk、kernel、android下载到nand flash中去。
二、主要流程
void main(u32 *arg)
{…..
mtk_uart_init(UART_SRC_CLK_FRQ,CFG_LOG_BAUDRATE);
/*初始化平台环境,比如Timer、PLL、UART、PMIC、Memory、BootableStorage等。*/
bldr_pre_process();
/*和外部工具通过UART或者USB方式握手,确定启动模式。*/
bldr_handshake(&handler);
/*安全相关的初始化*/
#if CFG_ATF_SUPPORT
trustzone_pre_init();
#endif
/*加载LK镜像到DRAM中(SecureBoot)*/
if (0 != bldr_load_images(&jump_addr)){
print("%s Second Bootloader Load Failed\n", MOD);
goto error;
}
/*初始化所有的环境。*/
bldr_post_process();
/*初始化所有的安全相关环境。*/
#if CFG_ATF_SUPPORT
trustzone_post_init();
#endif
/*设置向lk传递参数的地址*/
#if CFG_BOOT_ARGUMENT_BY_ATAG
jump_arg = (u32)&(g_dram_buf->boottag);
#else
jump_arg = (u32)&bootarg;
#endif
#if CFG_ATF_SUPPORT
……
/*支持ATF,跳转到EL3,然后再跳转到lk*/
bldr_jump64(jump_addr,jump_arg, sizeof(boot_arg_t));
#else
/*跳转到lk*/
bldr_jump(jump_addr,jump_arg, sizeof(boot_arg_t));
#endif
error:
platform_error_handler();
}
三、详细流程
1、初始化
(1)link_descriptor.ld
文件路径:/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735
在该文件中定义了入口,会跳转到_start中执行:
2)init.s
文件路径:
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/init
在该文件中会执行_start,然后跳转到resethandler执行,主要作用是配置c运行环境(寄存器、堆栈、BSS等) BSS静态内存段(未初始化)、数据段(初始化)、堆段、栈段
以及设置cpu为管理模式,关中断。
结束后会跳转到main开始执行:
(3)main.c
文件路径:
/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/core
初始化外部DRAM的timer、时钟、UART、EMI(DRAM防静电干扰)。
bldr_pre_process()完成各种的平台硬件(timer,pmic,gpio,wdt...)初始化工作。
static void bldr_pre_process(void)
{ …..
/* 重要的硬件初始化timer,pll, uart... */
platform_pre_init();
/* 平台初始化*/
platform_init();
/* 分区初始化*/
part_init();