/************************* cmd/nvedit.c **************************************/
//解释:添加saveenv命令,该命令调用do_env_save(),进一步调用env_save()
U_BOOT_CMD(
saveenv, 1, 0, do_env_save,
"save environment variables to persistent storage",
""
);
static int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
return env_save() ? 1 : 0;
}
/************************* env/env.c **************************************/
//解释:基于gd->env_load_prio找到对应的驱动,然后调用drv->save()
//注:gd->env_load_prio在env_init时被设置,在zynq板中为CONFIG_ENV_IS_IN_SPI_FLASH
int env_save(void)
{
struct env_driver *drv;
drv = env_driver_lookup(ENVOP_SAVE, gd->env_load_prio);
if (drv) {
int ret;
if (!drv->save)
return -ENODEV;
if (!env_has_inited(drv->location))
return -ENODEV;
printf("drv->location:%08x, drv->init() = %08x>>>>>>>>>>>>\n", location_ny, init_ny);
printf("Saving Environment to %s... ", drv->name);
ret = drv->save();
if (ret)
printf("Failed (%d)\n", ret);
else
printf("OK\n");
if (!ret)
return 0;
}
return -ENODEV;
}
int env_init(void)
{
struct env_driver *drv;
int ret = -ENOENT;
int prio;
for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
printf("drv->location:%08x, drv->init() = %08x>>>>>>>>>>>> times_ny = %08x\n", drv->location, drv->init, prio);
if (!drv->init || !(ret = drv->init()))
env_set_inited(drv->location);
debug("%s: Environment %s init done (ret=%d)\n", __func__,
drv->name, ret);
}
if (!prio)
return -ENODEV;
if (ret == -ENOENT) {
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = ENV_VALID;
return 0;
}
return ret;
}
/************************* env/sf.c **************************************/
//解释:
//CONFIG_ENV_SECT_SIZE=0x20000
//CONFIG_ENV_SIZE=0x20000
//CONFIG_ENV_OFFSET=0xE0000
//
static int env_sf_save(void)
{
u32 saved_size, saved_offset, sector;
char *saved_buffer = NULL;
int ret = 1;
env_t env_new; //创建了存储空间
ret = setup_flash_device();
if (ret)
return ret;
/* Is the sector larger than the env (i.e. embedded) */
if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE;
saved_buffer = malloc(saved_size);
if (!saved_buffer)
goto done;
ret = spi_flash_read(env_flash, saved_offset,
saved_size, saved_buffer);
if (ret)
goto done;
}
ret = env_export(&env_new); //从env_htab导出到env_new
if (ret)
goto done;
sector = DIV_ROUND_UP(CONFIG_ENV_SIZE, CONFIG_ENV_SECT_SIZE);
puts("Erasing SPI flash...");
ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET,
sector * CONFIG_ENV_SECT_SIZE);
if (ret)
goto done;
puts("Writing to SPI flash...");
ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET,
CONFIG_ENV_SIZE, &env_new);
if (ret)
goto done;
if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
ret = spi_flash_write(env_flash, saved_offset,
saved_size, saved_buffer);
if (ret)
goto done;
}
ret = 0;
puts("done\n");
done:
if (saved_buffer)
free(saved_buffer);
return ret;
}