From 1197954d5896f431716a61b4242c98c336753948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 21 Feb 2026 11:00:06 +0100 Subject: [PATCH 1/6] fw_env: use "erasesize" variable in writing loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use "erasesize" instead of "blocklen" in flash_write_buf()'s loop. This change touches code executed for bad NAND blocks so it doesn't affect any behaviour (for NAND flashes "blocklen" and "erasesize" are equal). This just makes code a bit more consistent as "erasesize" is what is used all around inside the writing loop. Signed-off-by: Rafał Miłecki --- tools/env/fw_env.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 425faf380fb..c69da0b926a 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -1096,7 +1096,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) } if (rc) { /* block is bad */ - blockstart += blocklen; + blockstart += erasesize; continue; } From d80d88cb87d7f291c7abc9168d69f30f994b852f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 21 Feb 2026 11:00:07 +0100 Subject: [PATCH 2/6] fw_env: allocate buffer of proper size in flash_write_buf() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When dealing with env data not aligned to flash blocks flash_write_buf() has to use an extra buffer. It reads existing flash content to it, modifies required part and writes it back. While reading and writing a size stored in "write_total" is used. It's what should be used when allocating the buffer too. In some cases allocating memory of "erase_len" size could result in allocating too big buffer. That wouldn't break anything but it was making code less intuitive. Signed-off-by: Rafał Miłecki --- tools/env/fw_env.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index c69da0b926a..fcbe09ea981 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -1037,11 +1037,11 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) * block back again. */ if (write_total > count) { - data = malloc(erase_len); + data = malloc(write_total); if (!data) { fprintf(stderr, "Cannot malloc %zu bytes: %s\n", - erase_len, strerror(errno)); + write_total, strerror(errno)); return -1; } From 2f28f4116a173891f5c88e1ae3de374241bb1121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 21 Feb 2026 11:00:08 +0100 Subject: [PATCH 3/6] fw_env: add ROUND_UP() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already have DIV_ROUND_UP() to simplify code so add ROUND_UP() as well. This makes code in flash_write_buf() easier to follow. Signed-off-by: Rafał Miłecki --- tools/env/fw_env.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index fcbe09ea981..c369bda1b85 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -50,6 +50,7 @@ struct env_opts default_opts = { }; #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +#define ROUND_UP(x, y) (DIV_ROUND_UP(x, y) * (y)) #define min(x, y) ({ \ typeof(x) _min1 = (x); \ @@ -1027,8 +1028,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) * to the start of the data, then count bytes of data, and * to the end of the block */ - write_total = ((block_seek + count + blocklen - 1) / - blocklen) * blocklen; + write_total = ROUND_UP(block_seek + count, blocklen); } /* From 1d175b2108d7e0aa74a182ac1ebde58a4f129371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 21 Feb 2026 11:00:09 +0100 Subject: [PATCH 4/6] fw_env: unify calculation of "blockstart" in flash_write_buf() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In both code paths "blockstart" is calculated the same way. Unify it. Signed-off-by: Rafał Miłecki Reviewed-by: Tom Rini --- tools/env/fw_env.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index c369bda1b85..8ca6a3e5478 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -1007,7 +1007,6 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) if (DEVTYPE(dev) == MTD_ABSENT) { blocklen = count; erase_len = blocklen; - blockstart = DEVOFFSET(dev); block_seek = 0; write_total = blocklen; } else { @@ -1018,8 +1017,6 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) /* Maximum area we may use */ erase_len = environment_end(dev) - erase_offset; - blockstart = erase_offset; - /* Offset inside a block */ block_seek = DEVOFFSET(dev) - erase_offset; @@ -1085,6 +1082,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) erase.length = erasesize; /* This only runs once on NOR flash and SPI-dataflash */ + blockstart = DEVOFFSET(dev); while (processed < write_total) { rc = flash_bad_block(fd, DEVTYPE(dev), blockstart); if (rc < 0) /* block test failed */ From ffd8024efcb9868b654b319b29949347e6fe92ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 21 Feb 2026 11:00:10 +0100 Subject: [PATCH 5/6] fw_env: move "erasesize" calculation up in a code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calculate "erasesize" in the same place where other offsets and lengths / sizes are calculated. It makes code more consistent and will allow further cleanups. Signed-off-by: Rafał Miłecki --- tools/env/fw_env.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 8ca6a3e5478..de3a33a380d 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -1007,6 +1007,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) if (DEVTYPE(dev) == MTD_ABSENT) { blocklen = count; erase_len = blocklen; + erasesize = erase_len; block_seek = 0; write_total = blocklen; } else { @@ -1016,6 +1017,15 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) /* Maximum area we may use */ erase_len = environment_end(dev) - erase_offset; + if (DEVTYPE(dev) == MTD_NANDFLASH) { + /* + * NAND: calculate which blocks we are writing. We have + * to write one block at a time to skip bad blocks. + */ + erasesize = blocklen; + } else { + erasesize = erase_len; + } /* Offset inside a block */ block_seek = DEVOFFSET(dev) - erase_offset; @@ -1069,16 +1079,6 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) data = buf; } - if (DEVTYPE(dev) == MTD_NANDFLASH) { - /* - * NAND: calculate which blocks we are writing. We have - * to write one block at a time to skip bad blocks. - */ - erasesize = blocklen; - } else { - erasesize = erase_len; - } - erase.length = erasesize; /* This only runs once on NOR flash and SPI-dataflash */ From 667fa1a1cd52abe8f96ce903d58322b7b126d9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 21 Feb 2026 11:00:11 +0100 Subject: [PATCH 6/6] fw_env: drop unneeded variables from flash_write_buf() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recent cleanups made some variables redundant. Both: "blocklen" and "erase_len" ended up being used as temporary variables used locally in some short code paths. Signed-off-by: Rafał Miłecki Reviewed-by: Tom Rini --- tools/env/fw_env.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index de3a33a380d..49a068d91cc 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -984,9 +984,6 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) { void *data; struct erase_info_user erase; - size_t blocklen; /* length of NAND block / NOR erase sector */ - size_t erase_len; /* whole area that can be erased - may include - bad blocks */ size_t erasesize; /* erase / write length - one block on NAND, whole area on NOR */ size_t processed = 0; /* progress counter */ @@ -1005,26 +1002,20 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) * For mtd devices only offset and size of the environment do matter */ if (DEVTYPE(dev) == MTD_ABSENT) { - blocklen = count; - erase_len = blocklen; - erasesize = erase_len; + erasesize = count; block_seek = 0; - write_total = blocklen; + write_total = count; } else { - blocklen = DEVESIZE(dev); - erase_offset = DEVOFFSET(dev); - /* Maximum area we may use */ - erase_len = environment_end(dev) - erase_offset; if (DEVTYPE(dev) == MTD_NANDFLASH) { /* * NAND: calculate which blocks we are writing. We have * to write one block at a time to skip bad blocks. */ - erasesize = blocklen; + erasesize = DEVESIZE(dev); } else { - erasesize = erase_len; + erasesize = environment_end(dev) - erase_offset; } /* Offset inside a block */ @@ -1035,7 +1026,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) * to the start of the data, then count bytes of data, and * to the end of the block */ - write_total = ROUND_UP(block_seek + count, blocklen); + write_total = ROUND_UP(block_seek + count, DEVESIZE(dev)); } /* @@ -1074,7 +1065,7 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) } else { /* * We get here, iff offset is block-aligned and count is a - * multiple of blocklen - see write_total calculation above + * multiple of erase size - see write_total calculation above */ data = buf; }