- 分析代码,了解Uboot environment variable.
1.重要结构体
env可以保存在不同的介质中,如下所示:
179 enum env_location {
180 ENVL_UNKNOWN,
181 ENVL_EEPROM,
182 ENVL_EXT4,
183 ENVL_FAT,
184 ENVL_FLASH,
185 ENVL_MMC,
186 ENVL_NAND,
187 ENVL_NVRAM,
188 ENVL_ONENAND,
189 ENVL_REMOTE,
190 ENVL_SPI_FLASH,
191 ENVL_UBI,
192 ENVL_NOWHERE,
193
194 ENVL_COUNT,
195 };
include/environment.h:
205 struct env_driver {
206 const char *name;
207 enum env_location location;
208
217 int (*load)(void);
226 int (*save)(void);
236 int (*init)(void);
237 };
如上所示,该结构体调用 U_BOOT_ENV_LOCATION注册到系统,如下所示:
env/mmc.c:
348 U_BOOT_ENV_LOCATION(mmc) = {
349 .location = ENVL_MMC,
350 ENV_NAME("MMC")
351 .load = env_mmc_load,
352 #ifndef CONFIG_SPL_BUILD
353 .save = env_save_ptr(env_mmc_save),
354 #endif
355 };
env/nand.c:
385 U_BOOT_ENV_LOCATION(nand) = {
386 .location = ENVL_NAND,
387 ENV_NAME("NAND")
388 .load = env_nand_load,
389 #if defined(CMD_SAVEENV)
390 .save = env_save_ptr(env_nand_save),
391 #endif
392 .init = env_nand_init,
393 };
2.初始化
分两个阶段:
- common/board_f.c :
257 int env_init(void)
258 {
259 struct env_driver *drv;
260 int ret = -ENOENT;
261 int prio;
262
263 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
264 if (!drv->init || !(ret = drv->init()))
265 env_set_inited(drv->location);
266
267 debug("%s: Environment %s init done (ret=%d)\n", __func__,
268 drv->name, ret);
269 }
274 if (ret == -ENOENT) {
275 gd->env_addr = (ulong)&default_environment[0];
276 gd->env_valid = ENV_VALID;
277
278 return 0;
279 }
280
281 return ret;
282 }
- common/board_r.c:
441 static int initr_env(void)
442 {
443 /* initialize environment */
444 if (should_load_env())
445 env_relocate();
446 else
447 set_default_env(NULL, 0);
448 #ifdef CONFIG_OF_CONTROL
449 env_set_hex("fdtcontroladdr",
450 (unsigned long)map_to_sysmem(gd->fdt_blob));
451 #endif
452
453 /* Initialize from environment */
454 load_addr = env_get_ulong("loadaddr", 16, load_addr);
455
456 return 0;
457 }
调用流程:
initr_env-> env_relocate-> env_load-> ret = drv->load();
最后调用load函数,即注册的 env_mmc_load、env_nand_load等。
3.配置
env/Kconfig:
146 config ENV_IS_IN_MMC
147 bool "Environment in an MMC device"
148 depends on !CHAIN_OF_TRUST
149 depends on MMC
150 default y if ARCH_EXYNOS4
151 default y if MX6SX || MX7D
152 default y if TEGRA30 || TEGRA124
153 default y if TEGRA_ARMV8_COMMON
154 help
155 Define this if you have an MMC device which you want to use for the
156 environment.
4.相关命令
1).printenv - print environment variables
To print all environment variables type “printenv” or just “pri” at the u-boot prompt.
The printenv command prints one, several or all variables of the U-Boot environment. When argumens are given, these are interpreted as the names of environment variables which will be printed with their values:
INCA-IP # printenv ipaddr hostname netmask
ipaddr=192.168.3.65
hostname=inca
netmask=255.255.255.0
INCA-IP #
2).saveenv - save environment variables to persistent storage
Any time that variables are created or modified they must be saved to NAND with the “saveenv” command. The “setenv” command sets the variable but the variable is only in SRAM until it is saved to NAND with the “saveenv” command.
To modify the U-Boot environment you have to use the setenv command. When called wih exactly one argument, it will delete any variable of that name from U-Boot’s environment, if such a variable exists. Any storage occupied for such a variable will be automatically reclaimed:
setenv name value ...
- set environment variable 'name' to 'value ...'
setenv name
- delete environment variable 'name'
INCA-IP # printenv foo
foo=This is an example value.
INCA-IP # setenv foo
INCA-IP # printenv foo
## Error: "foo" not defined
INCA-IP #
3).setenv - set environment variables
To create a new environment variable use the command “setenv”. This command can also be used to save a copy of an existing environment variable. Here is an example where “bootcmd” is saved off to another name and a new “bootcmd” is generated.
参考:
http://www.denx.de/wiki/publish/DULG/to-delete/UBootCmdGroupEnvironment.html