这里简单介绍了preloader的启动流程,ATF的实现部分可参考https://blog.csdn.net/chenying126/article/details/78638944
1.链接器脚本link_descriptor.ld定义了preloader的入口函数
OUTPUT_ARCH(arm)
ENTRY(_start)
2.init.S定义了_start,并跳转到main执行
.globl _start
_start:
b resethandler
/*
* 设置svc32模式
* 禁止中断fiq&irq
* clear BSS
* setup stack
* 跳转main执行
*/
......
entry :
LDR r0, =bldr_args_addr
B main
3.main函数,截取了部分代码
void main(u32 *arg)
{/* get the bldr argument */
p_bldr_param = &bldr_param;
//_start函数中将bldr_args_addr作为参数传给main,这里为0
memcpy((void *) p_bldr_param,(void *) *arg, sizeof(bl_param_t));
//必要的硬件初始化
mtk_uart_init(UART_SRC_CLK_FRQ, CFG_LOG_BAUDRATE);
bldr_pre_process();
//usb/uart握手,没深入看
handler.priv = NULL;
handler.attr = 0;
handler.cb = bldr_cmd_handler;
bldr_handshake(&handler);
//trustzone初始化1
trustzone_pre_init();
//加载ATF&LK镜像
bldr_load_images(&jump_addr)
//检测电池是否插上,并且初始化bootarg
bldr_post_process();
//trustzone初始化2,初始化atf_boot_arg
trustzone_post_init();
//jump_arg定义,作为参数传给bldr_jump64
jump_arg = (u32)&(g_dram_buf->boottag);
//跳转到ATF,lk执行后续流程
bldr_jump64(jump_addr, jump_arg, sizeof(boot_arg_t));
}
- bldr_pre_process
static void bldr_pre_process(void) { //初始化必要的硬件设备,timer/uart/pll/pmic等 platform_pre_init(); g_boot_mode = NORMAL_BOOT; //初始化wdt、keypad、DRAM、mmc platform_init(); //启动设备分区初始化 part_init(); part_dump(); //初始化security lib sec_lib_init(); }
void platform_init(void) { mtk_wdt_init(); --看门狗初始化 set_kpd_pmic_mode(); --keypad pmic mode support g_boot_reason = reason = platform_boot_status(); --检测启动状态 if (reason == BR_RTC || reason == BR_POWER_KEY || reason == BR_USB || reason == BR_WDT || reason == BR_WDT_BY_PASS_PWK || reason == BR_2SEC_REBOOT) rtc_bbpu_power_on(); --bbpu指baseband power-up,调用该函数锁存RTC的PWBB来保持设备的一直供电,power键抬起也不会关机 mt_mem_init(); --DRAM init_dram_buffer(); --DRAM buffer ram_console_init(); --ram console ret = boot_device_init(); --emmc mt_usb_phy_init(); --usb mt_usb11_phy_savecurrent(); bootarg.dram_rank_num = get_dram_rank_nr(); --保存DRAM信息到bootarg中 get_dram_rank_size(bootarg.dram_rank_size); get_orig_dram_rank_info(&bootarg.orig_dram_info); setup_mblock_info(&bootarg.mblock_info, &bootarg.orig_dram_info, &bootarg.lca_reserved_mem); }
void platform_pre_init(void) { mtk_timer_init(); --timer mt_pll_init(); --pll mtk_uart_init(UART_SRC_CLK_FRQ, CFG_LOG_BAUDRATE); --uart pwrap_init_preloader(); --pwrap i2c_hw_init(); --i2c pmic_ret = pmic_init(); --pmic mt_pll_post_init(); --post pll PMIC_enable_long_press_reboot(); --长按重启 }
- bldr_load_images
static int bldr_load_images(u32 *jump_addr) {
//加载lk到DRAM,CFG_UBOOT_MEMADDR在default.mak中定义,CFG_UBOOT_MEMADDR :=0x46000000
//lk入口地址设置为CFG_UBOOT_MEMADDR #elif CFG_LOAD_UBOOT addr = CFG_UBOOT_MEMADDR; ret = bldr_load_part_lk(bootdev, &addr, &size);*jump_addr = addr; #endif //加载ATF到SRAM,default.mak中定义CFG_ATF_ROM_MEMADDR :=0x00101000-0x800-0x240
//tee_entry_addr设置为CFG_ATF_ROM_MEMADDR
#if CFG_ATF_SUPPORT addr = CFG_ATF_ROM_MEMADDR; ret = bldr_load_tee_part("tee1", bootdev, &addr, 0, &size); addr = CFG_ATF_ROM_MEMADDR; ret = bldr_load_tee_part("tee2", bootdev, &addr, 0, &size);#endif } - bldr_post_process
static void bldr_post_process(void) { platform_post_init(); }
-
void platform_post_init(void) { #if CFG_BATTERY_DETECT //normal boot电池检测 if (g_boot_mode == NORMAL_BOOT && !hw_check_battery() && usb_accessory_in()) { //关闭pre charger led pl_close_pre_chr_led(); //使能强制充电模式 pl_charging(1); do { mdelay(300); //循环检测电池是否存在 if (hw_check_battery()) break; //喂狗 platform_wdt_all_kick(); } while(1); //关闭强制充电模式 pl_charging(0); } #endif
//设置bootarg,作为传参给lk
platform_set_boot_args();
} - bldr_jump64
void bldr_jump64(u32 addr, u32 arg1, u32 arg2) { //喂狗,防止超时重启 platform_wdt_kick(); //调用jumparch64跳转到ATF,之后跳转lk,开始lk之旅 //jumparch64在init.S中定义 trustzone_jump(addr, arg1, arg2); }
4.preloader阶段一些常用设置
- 串口设置
cut_bldr.mak中定义输出串口 CFG_UART_LOG :=UART2 default.mak中定义了串口波特率 CFG_LOG_BAUDRATE :=921600
- 打开调试时间戳,查看每个阶段的运行时间
在platform/<platform>/makefile.mak中添加 C_OPTION += -DPL_PROFILING
- 配置mcp
在custome/<project>/inc/cust_Memorydevice.h中 #define CS_PART_NUMBER[0] xxx0 #define CS_PART_NUMBER[1] xxx1
mcp型号在preloader\tools\emigen\MT6755\MemoryDeviceList_<platform>.xls的Part_Number中,这里兼容两种不同类型flash选型时选用mtk验证过的芯片
来源:oschina
链接:https://my.oschina.net/u/4332051/blog/3960137