这篇博客主要分析 init_sequence_f 函数指针数组中的initf_bootstage函数:
static int initf_bootstage(void)
{
bool from_spl = IS_ENABLED(CONFIG_SPL_BOOTSTAGE) &&IS_ENABLED(CONFIG_BOOTSTAGE_STASH);
//CONFIG_SPL_BOOTSTAGE和CONFIG_BOOTSTAGE_STASH都未定义,from_spl = false
int ret;
ret = bootstage_init(!from_spl);
int bootstage_init(bool first) //first=true
{
struct bootstage_data *data;
int size = sizeof(struct bootstage_data);
gd->bootstage = (struct bootstage_data *)malloc(size); //为gd->bootstage分配空间
if (!gd->bootstage)
return -ENOMEM;
data = gd->bootstage;
memset(data, ' ', size); //将gd->bootstage指向的空间清零
if (first) {
data->next_id = BOOTSTAGE_ID_USER; //将gd->bootstage的next_id的参数设置为BOOTSTAGE_ID_USER
bootstage_add_record(BOOTSTAGE_ID_AWAKE, "reset", 0, 0);
ulong bootstage_add_record(enum bootstage_id id, const char *name,int flags, ulong mark)
{
struct bootstage_data *data = gd->bootstage;
struct bootstage_record *rec;
if (flags & BOOTSTAGEF_ALLOC) //flags=0,不执行
id = data->next_id++;
rec = find_id(data, id); //gd->bootstage被清零,返回NULL
if (!rec && data->rec_count < RECORD_COUNT) {
rec = &data->record[data->rec_count++]; //初始化rec指向&data->record[0],并且data->rec_count=1
rec->time_us = mark; //初始化rec->time_us为0
rec->name = name; //初始化rec->name 为reset
rec->flags = flags; //初始化rec->flags 为0
rec->id = id; //初始化rec->id为BOOTSTAGE_ID_AWAKE
}
show_boot_progress(flags & BOOTSTAGEF_ERROR ? -id : id);
//等价于show_boot_progress(BOOTSTAGE_ID_AWAKE),啥也没干
return mark;
}
//bootstage_add_record的主要功能是初始化gd->bootstage->record[0]
}
return 0;
}
//bootstage_init的主要功能是为gd->bootstage分配空间,并初始化gd->bootstage->next_id和gd->bootstage->record[0]
if (ret) //ret=0,不执行
return ret;
if (from_spl) { //from_spl = false,不执行
const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR,
CONFIG_BOOTSTAGE_STASH_SIZE);
ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE);
if (ret && ret != -ENOENT) {
debug("Failed to unstash bootstage: err=%d
", ret);
return ret;
}
}
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");
ulong bootstage_mark_name(enum bootstage_id id, const char *name)
{
int flags = 0;
if (id == BOOTSTAGE_ID_ALLOC) //id=BOOTSTAGE_ID_START_UBOOT_F,不执行
flags = BOOTSTAGEF_ALLOC;
return bootstage_add_record(id, name, flags, timer_get_boot_us()); //初始化gd->bootstage->record[1]
}
//bootstage_mark_name的主要作用是初始化gd->bootstage->record[1]为board_init_f
return 0;
}
综上,initf_bootstage的主要作用就是为gd->bootstage分配空间,并初始化gd->bootstage,增加两条gd->bootstage->record,一条是reset,一条是board_init_f
————————————————
版权声明:本文为CSDN博主「yanggx0929」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yanggx0929/article/details/88834910