[PATCH] UBI: support EOF block marking end of ubinized image

Rafał Miłecki zajec5 at gmail.com
Fri Mar 18 08:53:04 PDT 2022


From: Rafał Miłecki <rafal at milecki.pl>

On home routers UBI is often used with UBI unaware bootloaders. In such
case an ubinized image needs to be created & flashed.

The problem is many such bootloaders are poorly written and they don't
erase whole flash (partition) before writing an image. Only part of
flash required to fit new image gets erased. It results in UBI
complaining about flash garbage content, e.g.:

ubi0: attaching mtd2
ubi0 error: ubi_attach: bad image sequence number 1646161998 in PEB 119, expected 524503983
Erase counter header dump:
         magic          0x55424923
         version        1
         ec             1
         vid_hdr_offset 2048
         data_offset    4096
         image_seq      1646161998
         hdr_crc        0x1eb28994
erase counter header hexdump:
ubi0 error: ubi_attach_mtd_dev: failed to attach mtd2, error -22
UBI error: cannot attach mtd2

To fix up such flashed images it's required to identify the end of
ubinized image on flash and erase remaining blocks.

Idea of extending on-disk UBI format to mark end of ubinized image was
rejected, see:
[PATCH RFC 2/2] ubi: add support for UBI_EC_FLAG_ERASE_FROM_HERE
https://patchwork.ozlabs.org/project/linux-mtd/patch/20161230171151.13448-2-zajec5@gmail.com/

This patch implements support for a simple "EOF" text content (block)
appended to the ubinized image instead. It doesn't require changing
on-disk format and still allows simple integration into ubi code.

Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 drivers/mtd/ubi/attach.c | 19 +++++++++++++++++++
 drivers/mtd/ubi/ubi.h    |  1 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index ae5abe492b52..8bea4bbcfbd9 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -958,9 +958,28 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
 		return 0;
 	}
 
+	if (ai->eof_found) {
+		ai->empty_peb_count += 1;
+		return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
+				   UBI_UNKNOWN, 0, &ai->erase);
+	}
+
 	err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
 	if (err < 0)
 		return err;
+
+	if (err == UBI_IO_BAD_HDR) {
+		uint8_t eof[] = { 'E', 'O', 'F' };
+		uint8_t *data = (uint8_t *)ech;
+
+		if (!memcmp(data, eof, sizeof(eof))) {
+			ai->eof_found = true;
+			ai->empty_peb_count += 1;
+			return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
+					   UBI_UNKNOWN, 0, &ai->erase);
+		}
+	}
+
 	switch (err) {
 	case 0:
 		break;
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 7c083ad58274..218c7dfedfc0 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -783,6 +783,7 @@ struct ubi_attach_info {
 	struct kmem_cache *aeb_slab_cache;
 	struct ubi_ec_hdr *ech;
 	struct ubi_vid_io_buf *vidb;
+	bool eof_found;
 };
 
 /**
-- 
2.34.1




More information about the linux-mtd mailing list