The flash environment driver has load, save and init operations but no erase.
Erase the environment sector the way env_flash_save prepares it for a write: unprotect it, erase it and protect it again. When the sector is larger than the environment, the rest of the sector is saved before the erase and written back afterwards, as the save path does. With a redundant copy, both sectors are erased: the active copy alternates between them on every save, so erasing only one can leave a valid environment behind. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Clément Le Goffic <[email protected]> --- env/flash.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/env/flash.c b/env/flash.c index 31dd1656e721..4b402437eb77 100644 --- a/env/flash.c +++ b/env/flash.c @@ -310,6 +310,66 @@ done: #endif /* CONFIG_ENV_ADDR_REDUND */ +#ifdef CMD_SAVEENV +static int env_flash_erase_sect(ulong addr, ulong end) +{ + char *saved_data = NULL; + int rc = 1; +#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE + ulong tail_size = end + 1 - (addr + CONFIG_ENV_SIZE); + + debug("Sector tail to keep 0x%lx\n", tail_size); + if (tail_size) { + saved_data = malloc(tail_size); + if (!saved_data) { + printf("Unable to save the rest of sector (%lu)\n", + tail_size); + return 1; + } + memcpy(saved_data, (void *)(addr + CONFIG_ENV_SIZE), tail_size); + } +#endif /* CONFIG_ENV_SECT_SIZE */ + + debug("Protect off %08lX ... %08lX\n", addr, end); + + if (flash_sect_protect(0, addr, end)) + goto done; + + if (flash_sect_erase(addr, end)) + goto done; + +#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE + if (tail_size) { /* restore the rest of sector */ + debug("Restoring the rest of data to 0x%lx len 0x%lx\n", + addr + CONFIG_ENV_SIZE, tail_size); + rc = flash_write(saved_data, addr + CONFIG_ENV_SIZE, tail_size); + if (rc) { + flash_perror(rc); + goto done; + } + } +#endif + rc = 0; +done: + free(saved_data); + /* try to re-protect */ + flash_sect_protect(1, addr, end); + + return rc; +} + +static int env_flash_erase(void) +{ +#ifdef CONFIG_ENV_ADDR_REDUND + int rc = env_flash_erase_sect((ulong)flash_addr_new, end_addr_new); + + if (rc) + return rc; +#endif + return env_flash_erase_sect((ulong)flash_addr, end_addr); +} +#endif /* CMD_SAVEENV */ + #ifdef LOADENV static int env_flash_load(void) { @@ -366,6 +426,7 @@ U_BOOT_ENV_LOCATION(flash) = { #endif #ifdef CMD_SAVEENV .save = env_save_ptr(env_flash_save), + .erase = ENV_ERASE_PTR(env_flash_erase), #endif #ifdef INITENV .init = env_flash_init, -- 2.56.0
