MT2712 Boot Flow Introduction

 

  • Boot Flow Overview
  • BootROM Introduce
  • BL2 stage
  • TEE+ATF
  • BL33 stage
  • MT2712 Image Format

 

Boot Flow Overview

ARM64处理器上电以后,首先执行地址0x0000_0000的bootroom代码,bootrom将引导程序加载到内部SRAM执行。MTK平台使用little kernel (lk)作为引导程序,lk分为两个阶段运行,分别为bl2阶段和bl33阶段,其中bl2运行在内部SRAM(L2_cache 256K),bl2阶段完成DRAM和eMMC的初始化,然后将ATF和BL33加载到DRAM,接下来就跳转到对应的地址运行ATF或者BL33,在BL33的中将跳转到linux kernel的地址,释放CPU的控制权并运行linux kernel。

 

 

 

BootROM Introduce

  • BootROM Flow

 

  • BootROM Features

BootROM的主要任务是初始化配置CPU0从0地址运行,初始化L2_cache为bl2的运行搭好环境,BootROM中会根据硬件pin脚的配置来选择启动的设备,并且BootROM软件支持三种模式:

支持3种模式:normal boot、USB download、UART download

支持5种设备:eMMC boot 分区,eMMC user分区,SLC NAND,SPI NOR, SD 卡

通过配置I2SO1_DATA0、I2SO1_BCK来选择boot device,目前项目使用eMMC Boot Mode:

 

BL2 stage

MTK平台用LK作为bootloader,BL2是bootloader的第一阶段, BL33是bootloader的第二阶段。之所以将LK分为两个阶段因为BOOT ROM启动后,DRAM尚未初始化,ROM Code只将SOC的L2_Cache做了初始化,MTK将L2_Cache分出256K作为SRAM,而LK编译出来的完整镜像超过256K,所以BL2作为第一阶段bootloader运行在SRAM中,BL33作为第二阶段bootloader运行在DRAM中。

BL2最主要的功能是完成eMMC初始化、DRAM初始化、DRAM校校验、加载ATF和BL33。从lk/top/main.c中的lk_main()函数是BL2阶段的开始,遵循的初始化顺序:CPU 架构 -> 目标平台 -> 目标设备。

lk_main@main.c

arch_early_init(); 
... 
platform_early_init(); 
... 
target_early_init(); 
... 
heap_init(); 
... 
call_constructors(); 
... 
kernel_init(); 
... 
thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);

 

 

lk_main()函数最后会创建bootstrap2线程继续完成初始化任务,bootstrap2最后会调用到lk/app/app.c中的apps_init函数来完成应用功能初始化,apps_init() 遍历所有在__apps_start 到__apps_end段里的函数,并调用lk中所谓的app的init函数,然后调用start_app(app)来启动app。start_app()函数中调用thread_create来创建一个APP线程。

apps_init@lk/app/app.c

/* one time setup */
void apps_init(void)
{
    const struct app_descriptor *app;

    /* call all the init routines */
    for (app = __apps_start; app != __apps_end; app++) {
        if (app->init)
            app->init(app);
    }

    /* start any that want to start on boot */
    for (app = __apps_start; app != __apps_end; app++) {
        if (app->entry && (app->flags & APP_FLAG_DONT_START_ON_BOOT) == 0) {
            start_app(app);
        }
    }
}

 

static void start_app(const struct app_descriptor *app)
{
    uint32_t stack_size = (app->flags & APP_FLAG_CUSTOM_STACK_SIZE) ? app->stack_size : DEFAULT_STACK_SIZE;

    printf("starting app %s\n", app->name);
    thread_t *t = thread_create(app->name, &app_thread_entry, (void *)app, DEFAULT_PRIORITY, stack_size);
    thread_detach(t);
    thread_resume(t);
}

哪些app被放入 boot thread section, 则定义在 include/app.h 中的 APP_START(appname)。

比如apps_init()通过下面方式进入blxboot_task()函数:

APP_START(blxboot)
.entry = blxboot_task,
 .flags = 0,
 APP_END

blxboot_task函数中完成blxobj的创建,然后通过get_boot_mode函数来判断是download流程、normal boot流程还是recovery流程。get_suffix函数获取ab镜像后缀,启动image_a或者image_b(这里的image在BL2 和BL33阶段不一样)。get_overlay_image将会获取dtbo,dtbo会覆盖掉dtb中某些域,最终系统使用的dtb-in-use=dtb+dtbo。最后blxboot_task将会调用arch_chain_load来跳转到要执行的image。

 

BL2阶段将会加载TEE和BL33镜像:

 

TEE+ATF

arm-trusted-firmware 主要负责Non-Secure和Secure的切换,atf的初始化在vendor/mediatek/proprietary/trustzone/atf/v1.6/mt2xxxbl31/aarch64/bl31_entrypoint.S,保存BL2传递过来的参数,比较重要的是LK的入口地址保存到了BL33_START_ADDRESS中;设置异常限量表的基地址到VBAR中;早期平台初始化,这里面完成了Non-secure world与Secure world上下文的初始化;进入ATF的main函数中进行环境和服务的初始化;el3_exit退出ATF进入LK.

简单了解atf的作用即可,atf的详细流程暂时不介绍。

 

BL33 stage

BL33是MTK平台的第二阶段bootloader,和BL2共用同一套的代码,根据mk和config文件还有一些宏来做区分,BL33第一句log和BL2一样都是:Watchdog Status: 0 , boot from normal。

BL33和BL2的区别主要体现在运行的位置不一样,BL33运行在DRAM中,BL2运行在SOC内部的SRAM。在platform_early_init()函数会根据当前BLx选择不同的函数platform_early_init_blx()

另外需要注意的是在BL33阶段加载的image包括:boot、dtbo、vpd、vbmeta,这一点和BL2 stage不一样。BL33运行结束就会跳到地址0x4008_0000运行Linux Kernel,至此lk运行结束。

 

 

BL33阶段将会加载boot、dtbo、vpd、vbmeta镜像:

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值