Skip to contentSkip to conversation

SPL: Lightweight UBI and UBI fastmap support

PATCH New Thomas Gleixner 4 participants 8 messages Jul 5, 2014 – Sep 30, 2014

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover SPL: Lightweight UBI and UBI fastmap support

Utilizing NAND FLASH requires proper wear leveling and bitflip management. Linux choice for this is UBI. The upstream UBI implementation is far too big for a SPL, but it is desired to load arbitrary payload including u-boot itself from a UBI managed NAND FLASH. That restricts the non-UBI managed part of the NAND flash to the first few eraseblocks which are reserved for the SoC boot ROM to load the SPL.

The following patches provide a lightweight and fast UBI attach and load code, which supports fastmap and full scan mode.

The text foot print on the board which I used for development is:

6854 0 0 6854 1abd drivers/mtd/ubispl/built-in.o

Attaching a NAND chip with 4096 physical eraseblocks (4 blocks are reserved for the SPL) takes:

In full scan mode: 1172ms
In fastmap mode: 95ms

With that and a moderate sized kernel image, I'm able to hand off to the kernel within less than 500ms.

The scan and logical to physical block mapping code is developed from scratch, while the fastmap functions are lifted from the linux kernel source and adjusted to fit the SPL needs.

The implementation is paranoid and carefully preserves the UBI robustness.

For now I keep a private copy of ubi-media.h which should be shared with the drivers/mtd/ubi/ one once Heiko has synced it to the 3.14 source.

There is room for more boot time optimizations:

- Implement sub page reads for nand_spl_simple

- Hand the UBI data from SPL to kernel to avoid rescan of the fastmap/flash

Thanks,

tglx

#1 lore raw

PATCH 1/2 nand_spl_simple: Add a simple flash read function

To support UBI in SPL we need a simple flash read function. Add one to nand_spl_simple and keep it as simple as it goes.

---
 drivers/mtd/nand/nand_spl_simple.c |   64 +++++++++++++++++++++++++++++++++++++
 include/nand.h                     |    1 
 2 files changed, 65 insertions(+)
drivers/mtd/nand/nand_spl_simple.c +64 -0
Index: u-boot/drivers/mtd/nand/nand_spl_simple.c
===================================================================
@@ -206,6 +206,70 @@ static int nand_read_page(int block, int
 }
 #endif
 
+#ifdef CONFIG_SPL_UBI
+/*
+ * Temporary storage for non NAND page aligned and non NAND page sized
+ * reads. Note: This does not support runtime detected FLASH yet, but
+ * that should be reasonably easy to fix by making the buffer large
+ * enough :)
+ */
+static u8 scratch_buf[CONFIG_SYS_NAND_PAGE_SIZE];
+
+/**
+ * nand_spl_read_flash - Read data from flash into a buffer
+ * @pnum:	Number of the physical eraseblock
+ * @offset:	Data offset from the start of @pnum
+ * @len:	Data size to read
+ * @dest:	Address of the destination buffer
+ *
+ * This could be further optimized if we'd have a subpage read
+ * function in the simple code. On NAND which allows subpage reads
+ * this would spare quite some time to readout e.g. the VID header of
+ * UBI.
+ *
+ * Notes:
+ *
+ *	@offset + @len are not allowed to be larger than a physical
+ *	erase block. No sanity check done for simplicity reasons.
+ *
+ * To support runtime detected flash this needs to be extended by
+ * information about the actual flash geometry, but thats beyond the
+ * scope of this effort and for most applications where fast boot is
+ * required its a non issue anyway.
+ */
+int nand_spl_read_flash(u32 pnum, u32 offset, u32 len, void *dest)
+{
+	u32 offs, page, read, toread = len;
+
+	/* Calculate the page number */
+	page = offset / CONFIG_SYS_NAND_PAGE_SIZE;
+
+	/* Offset to the start of a flash page */
+	offs = offset % CONFIG_SYS_NAND_PAGE_SIZE;
+
+	while (toread) {
+		/*
+		 * Non page aligned reads go to the scratch buffer.
+		 * Page aligned reads go directly to the destination.
+		 */
+		if (offs || toread < CONFIG_SYS_NAND_PAGE_SIZE) {
+			nand_read_page(pnum, page, scratch_buf);
+			read = min(len, toread);
+			read = min(read, CONFIG_SYS_NAND_PAGE_SIZE - offs);
+			memcpy(dest, scratch_buf + offs, read);
+			offs = 0;
+		} else {
+			nand_read_page(pnum, page, dest);
+			read = CONFIG_SYS_NAND_PAGE_SIZE;
+		}
+		page++;
+		toread -= read;
+		dest += read;
+	}
+	return 0;
+}
+#endif
+
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
 {
 	unsigned int block, lastblock;
include/nand.h +1 -0
Index: u-boot/include/nand.h
===================================================================
@@ -149,6 +149,7 @@ int nand_unlock(nand_info_t *meminfo, lo
 int nand_get_lock_status(nand_info_t *meminfo, loff_t offset);
 
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst);
+int nand_spl_read_flash(u32 pnum, u32 offset, u32 len, void *dest);
 void nand_deselect(void);
 
 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
#2 lore raw

PATCH 2/2 spl: Lightweight UBI and UBI fastmap support

In reply to Thomas Gleixner

Booting a payload out of NAND FLASH from the SPL is a crux today, as it requires hard partioned FLASH. Not a brilliant idea with the reliability of todays NAND FLASH chips.

The upstream UBI + UBI fastmap implementation which is about to brought to u-boot is too heavy weight for SPLs as it provides way more functionality than needed for a SPL and does not even fit into the restricted SPL areas which are loaded from the SoC boot ROM.

So this provides a fast and lightweight implementation of UBI scanning and UBI fastmap attach. The scan and logical to physical block mapping code is developed from scratch, while the fastmap implementation is lifted from the linux kernel source and stripped down to fit the SPL needs.

The text foot print on the board which I used for development is:

6854 0 0 6854 1abd drivers/mtd/ubispl/built-in.o

Attaching a NAND chip with 4096 physical eraseblocks (4 blocks are reserved for the SPL) takes:

In full scan mode: 1172ms
In fastmap mode: 95ms

The code requires quite some storage. The largest and unknown part of it is the number of fastmap blocks to read. Therefor the data structure is not put into the BSS. The code requires a pointer to free memory handed in which is initialized by the UBI attach code itself.

See doc/README.ubispl for further information on how to use it.

This shares the crc32 implementation of drivers/mtd/ubi and it should share ubi-media.h once u-boot is updated to the 3.14 ubi code. For now I keep a private copy of ubi-media.h as ubispl needs all the new fancy things from there. There is no way to share the fastmap code, as UBISPL only utilizes the slightly modified functions ubi_attach_fastmap() and ubi_scan_fastmap() from the original kernel ubi fastmap implementation.

---
 README                           |    4 
 doc/README.ubispl                |  144 ++++++
 drivers/mtd/ubispl/Makefile      |    1 
 drivers/mtd/ubispl/ubi-media.h   |  503 +++++++++++++++++++++
 drivers/mtd/ubispl/ubi-wrapper.h |  104 ++++
 drivers/mtd/ubispl/ubispl.c      |  920 +++++++++++++++++++++++++++++++++++++++
 drivers/mtd/ubispl/ubispl.h      |  136 +++++
 include/ubispl.h                 |   90 +++
 scripts/Makefile.spl             |    1 
 9 files changed, 1903 insertions(+)
README +4 -0
Index: u-boot/README
===================================================================
@@ -3456,6 +3456,10 @@ FIT uImage format:
 		Support for NAND boot using simple NAND drivers that
 		expose the cmd_ctrl() interface.
 
+		CONFIG_SPL_UBI
+		Support for a lightweight UBI (fastmap) scanner and
+		loader
+
 		CONFIG_SPL_MTD_SUPPORT
 		Support for the MTD subsystem within SPL.  Useful for
 		environment on NAND support within SPL.
doc/README.ubispl new file +144 -0

144 lines not on this page · raw message

drivers/mtd/ubispl/Makefile new file +1 -0
Index: u-boot/drivers/mtd/ubispl/Makefile
===================================================================
@@ -0,0 +1 @@
+obj-y += ubispl.o ../ubi/crc32.o
drivers/mtd/ubispl/ubi-media.h new file +503 -0

503 lines not on this page · raw message

drivers/mtd/ubispl/ubi-wrapper.h new file +104 -0

104 lines not on this page · raw message

drivers/mtd/ubispl/ubispl.c new file +920 -0

920 lines not on this page · raw message

drivers/mtd/ubispl/ubispl.h new file +136 -0

136 lines not on this page · raw message

include/ubispl.h new file +90 -0

90 lines not on this page · raw message

scripts/Makefile.spl +1 -0
Index: u-boot/scripts/Makefile.spl
===================================================================
@@ -105,6 +105,7 @@ libs-y += fs/
 libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
 libs-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/ drivers/power/pmic/
 libs-$(CONFIG_SPL_MTD_SUPPORT) += drivers/mtd/
+libs-$(CONFIG_SPL_UBI) += drivers/mtd/ubispl/
 libs-$(if $(CONFIG_CMD_NAND),$(CONFIG_SPL_NAND_SUPPORT)) += drivers/mtd/nand/
 libs-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += drivers/misc/
 libs-$(CONFIG_SPL_ONENAND_SUPPORT) += drivers/mtd/onenand/
#3 lore raw

PATCH 2/2 spl: Lightweight UBI and UBI fastmap support

Quoted 3 lines · Thomas Gleixner

Booting a payload out of NAND FLASH from the SPL is a crux today, as it requires hard partioned FLASH. Not a brilliant idea with the reliability of todays NAND FLASH chips.

[snip]

README FIT uImage format: · line 3461

Quoted 3 lines
README +3 -0
+		CONFIG_SPL_UBI
+		Support for a lightweight UBI (fastmap) scanner and
+		loader

... for the related options, please see doc/README.ubispl

Quoted 41 lines
doc/README.ubispl new file +41 -0
+Usage notes:
+
+In the board config file define for example:
+
+#define CONFIG_SPL_UBI
+#define CONFIG_SPL_UBI_MAX_VOL_LEBS	256
+#define CONFIG_SPL_UBI_MAX_PEB_SIZE	(256*1024)
+#define CONFIG_SPL_UBI_MAX_PEBS		4096
+#define CONFIG_SPL_UBI_VOL_IDS		8
+
+The size requirement is roughly as follows:
+
+    2k for the basic data structure
+  + CONFIG_SPL_UBI_VOL_IDS * CONFIG_SPL_UBI_MAX_VOL_LEBS * 8
+  + CONFIG_SPL_UBI_MAX_PEBS * 64
+  + CONFIG_SPL_UBI_MAX_PEB_SIZE * UBI_FM_MAX_BLOCKS
+
+The last one is big, but I really don't care in that stage. Real world
+implementations only use the first couple of blocks, but the code
+handles up to UBI_FM_MAX_BLOCKS.
+
+Given the above configuration example the requirement is about 5M
+which is usually not a problem to reserve in the RAM along with the
+other areas like the kernel/dts load address.
+
+So something like this will do the trick:
+
+#define SPL_FINFO_ADDR			0x80800000
+#define SPL_DTB_LOAD_ADDR		0x81800000
+#define SPL_KERNEL_LOAD_ADDR		0x82000000
+
+In the board file, implement the following:
+
+static struct ubispl_load myvolumes[] = {
+	{
+		.name		= "Kernel",
+		.vol_id		= 0,
+		.load_addr	= (void *)SPL_KERNEL_LOAD_ADDR,
+	},
+	{
+		.name		= "DTB",

doc/README.ubispl line 83

Quoted 10 lines
doc/README.ubispl new file +10 -0
+		.vol_id		= 1,
+		.load_addr	= (void *)SPL_DTB_LOAD_ADDR,
+	}
+};
+
+int spl_start_uboot(void)
+{
+	struct ubispl_info info;
+
+	info.ubi = (struct ubi_scan_info *) SPL_FINFO_ADDR;

OK, so here's some problems with the example. First, we can / should (and OK, after you posted the patch this went in) moved stack into DDR in some cases, so in the case of wanting to use this, DDR would have to be up in time for that to be a valid option, so we shoudl just do that. Second, we have CONFIG_SYS_SPL_ARGS_ADDR for where the DT would go and since Falcon supports uImages only (And if/when zImage is added, we'll have to sort something out generically) we don't need to hard-code in a load address for the kernel.

drivers/mtd/ubispl/ubispl.c line 68

Quoted 5 lines
drivers/mtd/ubispl/ubispl.c new file +5 -0
+	/*
+	 * Bad block, unrecoverable ECC error, skip the block
+	 */
+	if (res) {
+		ubi_dbg("Skipping bad or unreadable block %d", pnum);

Here and everywhere else, we have debug() please use that.

drivers/mtd/ubispl/ubispl.c line 476

Quoted 11 lines
drivers/mtd/ubispl/ubispl.c new file +11 -0
+#ifdef CHECKME
+	/*
+	 * If fastmap is leaking PEBs (must not happen), raise a
+	 * fat warning and fall back to scanning mode.
+	 * We do this here because in ubi_wl_init() it's too late
+	 * and we cannot fall back to scanning.
+	 */
+	if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count -
+		    ai->bad_peb_count - fm->used_blocks))
+		goto fail_bad;
+#endif

Use DEBUG here?

Quoted 16 lines
drivers/mtd/ubispl/ubispl.c new file +16 -0
+#ifdef LATER
+		int image_seq;
+		ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
+		if (ret && ret != UBI_IO_BITFLIPS) {
+			ubi_err("unable to read fastmap block# %i EC (PEB: %i)",
+				i, pnum);
+			if (ret > 0)
+				ret = UBI_BAD_FASTMAP;
+			goto free_hdr;
+		} else if (ret == UBI_IO_BITFLIPS)
+			fm->to_be_tortured[i] = 1;
+
+		image_seq = be32_to_cpu(ech->image_seq);
+		if (!ubi->image_seq)
+			ubi->image_seq = image_seq;
+		/*

drivers/mtd/ubispl/ubispl.c line 572

Quoted 10 lines
drivers/mtd/ubispl/ubispl.c new file +10 -0
+		 * Older UBI implementations have image_seq set to zero, so
+		 * we shouldn't fail if image_seq == 0.
+		 */
+		if (image_seq && (image_seq != ubi->image_seq)) {
+			ubi_err("wrong image seq:%d instead of %d",
+				be32_to_cpu(ech->image_seq), ubi->image_seq);
+			ret = UBI_BAD_FASTMAP;
+			goto free_hdr;
+		}
+#endif

What is LATER in this context? Missing functionality? Or debug code?

Thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140808/8655aa4d/attachment.pgp>
#4 lore raw

PATCH 2/2 spl: Lightweight UBI and UBI fastmap support

Quoted 11 lines · Tom Rini
Quoted 3 lines · Thomas Gleixner

Booting a payload out of NAND FLASH from the SPL is a crux today, as it requires hard partioned FLASH. Not a brilliant idea with the reliability of todays NAND FLASH chips.

[snip]

README FIT uImage format: · line 3461

Quoted 3 lines
README +3 -0
+		CONFIG_SPL_UBI
+		Support for a lightweight UBI (fastmap) scanner and
+		loader

... for the related options, please see doc/README.ubispl

Ok.

Quoted 48 lines
Quoted 48 lines
doc/README.ubispl new file +48 -0
+Usage notes:
+
+In the board config file define for example:
+
+#define CONFIG_SPL_UBI
+#define CONFIG_SPL_UBI_MAX_VOL_LEBS	256
+#define CONFIG_SPL_UBI_MAX_PEB_SIZE	(256*1024)
+#define CONFIG_SPL_UBI_MAX_PEBS		4096
+#define CONFIG_SPL_UBI_VOL_IDS		8
+
+The size requirement is roughly as follows:
+
+    2k for the basic data structure
+  + CONFIG_SPL_UBI_VOL_IDS * CONFIG_SPL_UBI_MAX_VOL_LEBS * 8
+  + CONFIG_SPL_UBI_MAX_PEBS * 64
+  + CONFIG_SPL_UBI_MAX_PEB_SIZE * UBI_FM_MAX_BLOCKS
+
+The last one is big, but I really don't care in that stage. Real world
+implementations only use the first couple of blocks, but the code
+handles up to UBI_FM_MAX_BLOCKS.
+
+Given the above configuration example the requirement is about 5M
+which is usually not a problem to reserve in the RAM along with the
+other areas like the kernel/dts load address.
+
+So something like this will do the trick:
+
+#define SPL_FINFO_ADDR			0x80800000
+#define SPL_DTB_LOAD_ADDR		0x81800000
+#define SPL_KERNEL_LOAD_ADDR		0x82000000
+
+In the board file, implement the following:
+
+static struct ubispl_load myvolumes[] = {
+	{
+		.name		= "Kernel",
+		.vol_id		= 0,
+		.load_addr	= (void *)SPL_KERNEL_LOAD_ADDR,
+	},
+	{
+		.name		= "DTB",
+		.vol_id		= 1,
+		.load_addr	= (void *)SPL_DTB_LOAD_ADDR,
+	}
+};
+
+int spl_start_uboot(void)
+{
Quoted 8 lines

doc/README.ubispl line 83

Quoted 3 lines
doc/README.ubispl new file +3 -0
+	struct ubispl_info info;
+
+	info.ubi = (struct ubi_scan_info *) SPL_FINFO_ADDR;

OK, so here's some problems with the example. First, we can / should (and OK, after you posted the patch this went in) moved stack into DDR in some cases, so in the case of wanting to use this, DDR would have to be up in time for that to be a valid option, so we shoudl just do that.

Well, the scan data structure is rather large, so you don't want to have it on stack.

Quoted 4 lines

Second, we have CONFIG_SYS_SPL_ARGS_ADDR for where the DT would go and since Falcon supports uImages only (And if/when zImage is added, we'll have to sort something out generically) we don't need to hard-code in a load address for the kernel.

Well, the way how this works is a bit different from the standard u-boot/uimage way.

The ubispl load code is oblivious of the payload. It just copies the data from the volume to a RAM address and checks the integrity of the payload with the UBI volume CRC.

I did this on purpose to avoid payload specific handling in the transfer code.

If we want to have uimage support there we'd need to tell that to the loader, e.g. by having a flag field in the volumes decriptor table.

That means, if the uImage flag is set we'd need to treat the first FLASH page of the payload differently:

1) copy it to a separate buffer
2) decode the uImage header and extract the load address
3) copy the kernel part which is in the first flash page from the separate buffer to the load address
4) Continue with the rest

That's doable, but I'm not sure if its worth the trouble. In my experience the load address almost never changes, so there is nothing wrong to hardcode it in the SPL.

Quoted 7 lines

drivers/mtd/ubispl/ubispl.c line 68

Quoted 5 lines
drivers/mtd/ubispl/ubispl.c new file +5 -0
+	/*
+	 * Bad block, unrecoverable ECC error, skip the block
+	 */
+	if (res) {
+		ubi_dbg("Skipping bad or unreadable block %d", pnum);

Here and everywhere else, we have debug() please use that.

I kept the original ubi_dbg() macros in the code which I lifted from mainline and wrapped them in the header to keep the changes minimal.

Quoted 5 lines
Quoted 5 lines
drivers/mtd/ubispl/ubispl.c new file +5 -0
+#ifdef CHECKME
+	/*
+	 * If fastmap is leaking PEBs (must not happen), raise a
+	 * fat warning and fall back to scanning mode.
+	 * We do this here because in ubi_wl_init() it's too late
Quoted 8 lines

drivers/mtd/ubispl/ubispl.c line 476

Quoted 6 lines
drivers/mtd/ubispl/ubispl.c new file +6 -0
+	 * and we cannot fall back to scanning.
+	 */
+	if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count -
+		    ai->bad_peb_count - fm->used_blocks))
+		goto fail_bad;
+#endif

Use DEBUG here?

That's a paranoia check in the UBI mainline code, which I can't keep as I have to do the accounting a bit different. I kept this as a reminder that we might revisit this if we feel paranoid enough, but we can surely replace it with a proper comment:

/*
* The upstream code has a paranoia accounting check for leaked
* PEBs. We cannot use the upstream code as we do not account for
* all volumes. With enforced error injection I was able to verify
* that even if that happens the load process will fail due to the
* integrity check of the payload volumes. When that happens the
* code falls back into full scanning mode.
*
* Upstream check:
* if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count -
* ai->bad_peb_count - fm->used_blocks))
* goto fail_bad;
*/

Quoted 20 lines
Quoted 20 lines
drivers/mtd/ubispl/ubispl.c new file +20 -0
+#ifdef LATER
+		int image_seq;
+		ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
+		if (ret && ret != UBI_IO_BITFLIPS) {
+			ubi_err("unable to read fastmap block# %i EC (PEB: %i)",
+				i, pnum);
+			if (ret > 0)
+				ret = UBI_BAD_FASTMAP;
+			goto free_hdr;
+		} else if (ret == UBI_IO_BITFLIPS)
+			fm->to_be_tortured[i] = 1;
+
+		image_seq = be32_to_cpu(ech->image_seq);
+		if (!ubi->image_seq)
+			ubi->image_seq = image_seq;
+		/*
+		 * Older UBI implementations have image_seq set to zero, so
+		 * we shouldn't fail if image_seq == 0.
+		 */
+		if (image_seq && (image_seq != ubi->image_seq)) {
Quoted 8 lines

drivers/mtd/ubispl/ubispl.c line 572

Quoted 6 lines
drivers/mtd/ubispl/ubispl.c new file +6 -0
+			ubi_err("wrong image seq:%d instead of %d",
+				be32_to_cpu(ech->image_seq), ubi->image_seq);
+			ret = UBI_BAD_FASTMAP;
+			goto free_hdr;
+		}
+#endif

What is LATER in this context? Missing functionality? Or debug code?

Yes, it's missing functionality to check the image sequence. I had a failure there in the first place and postponed it, then ran out of time ....

Thanks,

tglx

#5 lore raw

PATCH 2/2 spl: Lightweight UBI and UBI fastmap support

In reply to Thomas Gleixner

Am 05.07.2014 11:48, schrieb Thomas Gleixner:

Quoted 7 lines
drivers/mtd/ubispl/ubispl.c new file +7 -0
+/**
+ * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device.
+ * @ubi: UBI device description object
+ */
+static size_t ubi_calc_fm_size(struct ubi_scan_info *ubi)
+{
+	size_t size;

drivers/mtd/ubispl/ubispl.c line 34

Quoted 10 lines
drivers/mtd/ubispl/ubispl.c new file +10 -0
+
+	size = sizeof(struct ubi_fm_hdr) + \
+		sizeof(struct ubi_fm_scan_pool) + \
+		sizeof(struct ubi_fm_scan_pool) + \
+		(ubi->peb_count * sizeof(struct ubi_fm_ec)) + \
+		(sizeof(struct ubi_fm_eba) + \
+		(ubi->peb_count * sizeof(__be32))) + \
+		sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
+	return roundup(size, ubi->leb_size);
+}

The size calculation misses sizeof(struct ubi_fm_sb). I've found this issue while working on Linux fastmap support.

Thanks,
//richard

#6 lore raw

PATCH 2/2 spl: Lightweight UBI and UBI fastmap support

Hello Richard,

Am 30.09.2014 00:21, schrieb Richard Weinberger:

Quoted 13 lines

Am 05.07.2014 11:48, schrieb Thomas Gleixner:

Quoted 12 lines
drivers/mtd/ubispl/ubispl.c new file +12 -0
+/**
+ * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device.
+ * @ubi: UBI device description object
+ */
+static size_t ubi_calc_fm_size(struct ubi_scan_info *ubi)
+{
+	size_t size;
+
+	size = sizeof(struct ubi_fm_hdr) + \
+		sizeof(struct ubi_fm_scan_pool) + \
+		sizeof(struct ubi_fm_scan_pool) + \
+		(ubi->peb_count * sizeof(struct ubi_fm_ec)) + \
Quoted 8 lines

drivers/mtd/ubispl/ubispl.c line 34

Quoted 5 lines
drivers/mtd/ubispl/ubispl.c new file +5 -0
+		(sizeof(struct ubi_fm_eba) + \
+		(ubi->peb_count * sizeof(__be32))) + \
+		sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
+	return roundup(size, ubi->leb_size);
+}

The size calculation misses sizeof(struct ubi_fm_sb). I've found this issue while working on Linux fastmap support.

Thanks! I must admit, I did not found yet time to look deeper in this patchset, but I have them on my list ...

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#7 lore raw

cover SPL: Lightweight UBI and UBI fastmap support

In reply to Thomas Gleixner

Hello Thomas,

Am 05.07.2014 11:48, schrieb Thomas Gleixner:

Quoted 10 lines

Utilizing NAND FLASH requires proper wear leveling and bitflip management. Linux choice for this is UBI. The upstream UBI implementation is far too big for a SPL, but it is desired to load arbitrary payload including u-boot itself from a UBI managed NAND FLASH. That restricts the non-UBI managed part of the NAND flash to the first few eraseblocks which are reserved for the SoC boot ROM to load the SPL.

The following patches provide a lightweight and fast UBI attach and load code, which supports fastmap and full scan mode.

Thnaks for your work. I try to look into this patches ASAP...

Quoted 4 lines

The text foot print on the board which I used for development is:

6854 0 0 6854 1abd drivers/mtd/ubispl/built-in.o

Quoted 8 lines

Attaching a NAND chip with 4096 physical eraseblocks (4 blocks are reserved for the SPL) takes:

In full scan mode: 1172ms
In fastmap mode: 95ms

With that and a moderate sized kernel image, I'm able to hand off to the kernel within less than 500ms.

Great!

Quoted 10 lines

The scan and logical to physical block mapping code is developed from scratch, while the fastmap functions are lifted from the linux kernel source and adjusted to fit the SPL needs.

The implementation is paranoid and carefully preserves the UBI robustness.

For now I keep a private copy of ubi-media.h which should be shared with the drivers/mtd/ubi/ one once Heiko has synced it to the 3.14 source.

Yes, that was also my first thought, as I looked roughly over your patches.

Quoted 6 lines

There is room for more boot time optimizations:

- Implement sub page reads for nand_spl_simple

- Hand the UBI data from SPL to kernel to avoid rescan of the fastmap/flash

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany