這篇博客主要分析 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 中的函數。