uboot 环境变量加载过程分析
在uboot的初始化过程中,环境变量的初始化加载过程如下:
board_r.c/initr_env() ---> env/common.c/env_relocate() ---> env/env.c/env_load()
在env_load()函数中,会根据启动介质(mmc spi)去选择env存储位置,然后调用相应介质的load函数将环境变量读取到系统中。
具体调用过程如下:
int env_load(void)
{
/*省略不重要代码*/
for (prio = 0; (drv = env_driver_lookup(ENVOP_LOAD, prio)); prio++) {
ret = drv->load(); //如果从存储介质中读取了env,直接返回
if (!ret) {
printf("OK\n");
return 0;
}
}
/*省略不重要代码*/
return -ENODEV;
}
1、获取drv的过程如下:
调用env_driver_lookup(),该函数根据参数prio,获取env位置loc,再根据loc去获取drv
static struct env_driver *env_driver_lookup(enum env_operation op, int prio)
{
enum env_location loc = env_get_location(op, prio);
struct env_driver *drv;
if (loc == ENVL_UNKNOWN)
return NULL;
drv = _env_driver_lookup(loc);
if (!drv) {
debug("%s: No environment driver for location %d\n", __func__,
loc);
return NULL;
}
return drv;
}
调用env_get_location(),该函数先获取启动位置,然后选择env位置,只有prio=0有效,否则就返回ENVL_UNKNOWN,所以env_driver_lookup()函数只会执行一次。
enum env_location env_get_location(enum env_operation op, int prio)
{
enum boot_src src = get_boot_src(); //根据硬件获取启动位置(spi mmc等)
if (prio) //如果prio不是0,就直接返回ENVL_UNKNOWN
return ENVL_UNKNOWN;
switch (src) { //根据启动位置确定env的位置
case BOOT_SOURCE_XSPI_NAND:
env_loc = ENVL_NAND;
break;
case BOOT_SOURCE_XSPI_NOR:
env_loc = ENVL_SPI_FLASH;
break;
default:
break;
}