IMX8 UBOOT源碼分析(十三)initf_dm函數分析

這篇博客主要分析 init_sequence_f 函數指針數組中的initf_dm函數:

#ifdef CONFIG_BLOBLIST              //CONFIG_BLOBLIST在.config中設置爲未定義
    bloblist_init,
#endif
    setup_spl_handoff,

static int setup_spl_handoff(void)
{
#if CONFIG_IS_ENABLED(HANDOFF)                         //未定義,不執行
    gd->spl_handoff = bloblist_find(BLOBLISTT_SPL_HANDOFF,
                    sizeof(struct spl_handoff));
    debug("Found SPL hand-off info %p\n", gd->spl_handoff);
#endif

    return 0;
}

setup_spl_handoff函數什麼也沒做

initf_console_record,

static int initf_console_record(void)
{
#if defined(CONFIG_CONSOLE_RECORD) && CONFIG_VAL(SYS_MALLOC_F_LEN)   

//CONFIG_CONSOLE_RECORD在.config中設置爲未定義,不執行
    return console_record_init();
#else
    return 0;
#endif
}

initf_console_record函數什麼也沒做

#if defined(CONFIG_HAVE_FSP)       //CONFIG_HAVE_FSP未定義,不執行
    arch_fsp_init,
#endif

arch_cpu_init,

int arch_cpu_init(void)
{
#ifdef CONFIG_SPL_BUILD                            //CONFIG_SPL_BUILD未定義,不執行
    struct pass_over_info_t *pass_over;

    if (is_soc_rev(CHIP_REV_A)) {
        pass_over = get_pass_over_info();
        if (pass_over && pass_over->g_ap_mu == 0) {
            /*
             * When ap_mu is 0, means the U-Boot booted
             * from first container
             */
            sc_misc_boot_status(-1, SC_MISC_BOOT_STATUS_SUCCESS);
        }
    }
#endif

    return 0;
}

arch_cpu_init函數什麼也沒做

mach_cpu_init,

__weak int mach_cpu_init(void)
{
    return 0;
}

mach_cpu_init函數什麼也沒做,用戶可自己定義

initf_dm,

static int initf_dm(void)
{
#if defined(CONFIG_DM) && CONFIG_VAL(SYS_MALLOC_F_LEN)   

//CONFIG_DM和CONFIG_SYS_MALLOC_F_LEN都有定義
    int ret;

    bootstage_start(BOOTSTATE_ID_ACCUM_DM_F, "dm_f");

    uint32_t bootstage_start(enum bootstage_id id, const char *name)
    {
        struct bootstage_data *data = gd->bootstage;                 
//data指向gd->bootstage
        struct bootstage_record *rec = ensure_id(data, id);

         struct bootstage_record *ensure_id(struct bootstage_data *data,enum bootstage_id id)
         {
             struct bootstage_record *rec;

             rec = find_id(data, id);                 

             //去gd->bootstage->record的查找有沒有匹配BOOTSTATE_ID_ACCUM_DM_F的記錄

             //有上篇博客可知目前record中只有BOOTSTAGE_ID_AWAKE和BOOTSTAGE_ID_START_UBOOT_F兩個記錄
             if (!rec && data->rec_count < RECORD_COUNT) {
                 rec = &data->record[data->rec_count++];                   
//rec指向gd->bootstage->record[2]
                 rec->id = id;                                                                  //rec->id初始化爲BOOTSTATE_ID_ACCUM_DM_F
                 return rec;
             }

             return rec;
         }


        ulong start_us = timer_get_boot_us();                                 //獲取當前的boot時間

        if (rec) {
            rec->start_us = start_us;
            rec->name = name;
        }

        return start_us;
    }

    //bootstage_start的主要功能是向gd->bootstage->record[2]中增加名字爲dm_f的記錄

    ret = dm_init_and_scan(true);

     這裏參考函數說明:該函數初始化驅動樹和uclass樹,然後從平臺數據和FDT中掃描和綁定可用的設備。當輸入參數爲true時,僅綁定含有DM_FLAG_PRE_RELOC標誌位和特殊設備樹特性的節點。

    bootstage_accum(BOOTSTATE_ID_ACCUM_DM_F);

     在先前的bootstage_start標記一項活動爲開始狀態後,調用bootstage_accum標記該任務爲結束狀態
    if (ret)
        return ret;
#endif
#ifdef CONFIG_TIMER_EARLY                 //未定義,不執行
    ret = dm_timer_init();
    if (ret)
        return ret;
#endif

    return 0;
}

本文主要分析了initf_dm的功能,主要是初始化驅動樹和uclass樹,並綁定含有DM_FLAG_PRE_RELOC標誌位和特殊設備樹特性的節點。下篇博客將繼續分析init_sequence_f 中的函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章