在 u-boot 中, env 有两套机制
在 board_init_f 中有一套
在 board_init_r 中有一套
u-boot 进入 cmdline 或者 bootcmd 时 采用 board_init_r 的那一套
u-boot 运行过程中
board_init_f
// board_init_f 之前就已经初始化好了 gd->env_buf
// 初始化 gd 结构体变量 地址的时候 初始化的 gd->env_buf
// 因为 gd_t 结构体 如此声明env_buf : char env_buf[32];
// gd->env_buf 用来装 env_get_ulong->env_get 时,获取的字符串
env_init
env_driver_lookup
env_get_location
return env_locations[prio] ; // ENVL_MMC
_env_driver_lookup
n_ents = xxx
in section .u_boot_list_2_env_driver ,根据 ENVL_MMC 找到对应的 驱动对应的结构体 struct env_driver
drv->init // drv 为找到的结构体 struct env_driver _u_boot_list_2_env_driver_2_mmc 中没有 init 成员
env_set_inited(drv->location)
gd->env_has_init |= (1UL << ENVL_MMC);
// 环境变量的地址
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = ENV_VALID;
消费者
init_baud_rate
gd->baudrate = env_get_ulong("baudrate", 10, CONFIG_BAUDRATE);
// 找到的是 include/env_default.h L23 中 const uchar default_environment[] 的 "baudrate=" __stringify(CONFIG_BAUDRATE) " "
env_get
env_get_f
env_get_char
env_get_char_spec
*(uchar *)(gd->env_addr + index)
board_init_r
initr_env
env_relocate();
env_load
drv = env_driver_lookup(ENVOP_LOAD, prio));
printf("Loading Environment from %s... ", drv->name);
drv->load();/env_mmc_load// 将 mmc 中的变量加载到内存中
// env_mmc_load 在 env/mmc.c
// ENV_IS_IN_MMC 决定了 env/mmc.c 编入u-boot
// ENV_IS_IN_MMC 依赖 MMC(mmc的驱动)
struct mmc *mmc = find_mmc_device(dev);
init_mmc_for_env(mmc);
mmc_get_env_addr(mmc, 0, &offset) // offset的单位是字节
// 1. 设备树中分析dt_prop.partition,如果不行再分析下一个
// 2. 设备树中分析dt_prop.offset,如果不行再分析下一个
// 3. CONFIG_ENV_OFFSET
// 该值应该是一个 u64,因为u32最多支持4G
// 但是u-boot在这一个变量的定义处有bug(有的是s64,有的是s32)
// 这个offset的值和u-boot移植人员相关,u-boot移植人员想让其指向什么位置就让其指向什么位置
// 但是要注意mmc的布局
// 我现在用的是一张32G的microsd卡,62410752个sector
// 按照 之前ENV的布局,其实sector是 62409678, 起始字节是 62409678*512 = 0x770979c00
// 单位 : sector
// | 32 | 16 | 1 |1025 |
// |ENV | BL1|SIGN |RESERVED|
read_env(mmc, CONFIG_ENV_SIZE, offset, buf)
env_import(buf, 1, H_EXTERNAL) // 导入到 env_htab 中
// mmc 的env 地址处是空的
if (crc32(0, ep->data, ENV_SIZE) != crc)
env_set_default("bad CRC", 0);
printf("*** Warning - %s, " "using default environmentnn", s);
// 做一次转换
himport_r(&env_htab, (char *)default_environment, sizeof(default_environment), '