mtk-preloader代碼分析


這里簡單介紹了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驗證過的芯片

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM