All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/4] partition parser for U-Boot's uImage.FIT
@ 2022-11-15 21:45 ` Daniel Golle
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:45 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Add uImage.FIT partition parser and wire it up to allow mounting
filesystem sub-images from uImage.FIT in GPT partitions as well as
mtdblock and ubiblock devices within Linux (e.g. as root filesystem).

Using uImage.FIT to store the root filesystem besides kernel and dtb has
several obvious advantages which are hard to obtain in any other way:
 * single image accross different storage types
 * dynamically sized partitions for kernel and rootfs
 * hash also for rootfs checked by U-Boot before launching kernel
 * images may include additional filesystems e.g. for localization or
   branding

For this to work, the image has to be created with external data and
sub-images aligned to the system's memory page boundaries, ie.
 mkimage -E -B 0x1000 -p 0x1000 ...

Booting such images has been supported by U-Boot since v2018.01.

A previous version of this partition parser is in production use on some
OpenWrt devices, eg. the BananaPi R64 where using the FIT parser allows
booting the very same image from eMMC, SD Card or SPI-NAND/UBI and also
using it as a firmware-upgrade image at the same time.
The Ubiquiti UniFi 6 LR access point served as a reference board with
SPI-NOR flash and use of the partition parser on top of a mtdblock
device.

As U-Boot by now also passes down the selected configuration node name
via device tree this allows the partition parser (or userspace process
via sysfs) to identify the selected image configuration.

Device Tree schema for that:
https://github.com/devicetree-org/dt-schema/commit/a24d97d43491e55d4def006213213a6c4045b646

In most cases this partition parser can be used without relying on the
bootloader to pass-down the configuration node name. The default
configuration node is used then.

Changes since v4:
 * use folio instead of page (requested by Matthew Wilcox)
 * remove unneeded checks (requested by Matthew Wilcox)
 * use strscpy instead of strlcpy (strlcpy is deprecated)
 * fix off-by-one string size limit label_min (discovered during tests)
 * use only a single config symbol MTD_BLOCK_PARTITION affecting both
   ubiblock and mtdblock (requested by Richard Weinberger)

Changes since v3:
 * use min_t(size_t, ...)

Changes since v2:
 * use returned length to limit all strings read from fit/dt
 * use __be32 type for 32-bit values read from fit/dt
Reported-by: kernel test robot <lkp@intel.com>
 * Kconfig: select LIBFDT for FIT_PARTITION
Reported-by: kernel test robot <lkp@intel.com>

Changes since v1:
 * Use again #ifdef's in partitions/efi to only build against FIT
   parser symbols if it is actually selected. Otherwise the efi/gpt
   would unconditionally depend on the FTT parser to be present.

Changes since RFC:
 * fixed wrong variable used in error path
 * introduced dedicated Kconfig options to enable partition
   parsers on mtdblock and ubiblock
 * drop #ifdef'ery, use IS_ENABLED(...) where needed

Daniel Golle (4):
  block: add new flag to add partitions read-only
  block: add partition parser for U-Boot uImage.FIT
  partitions/efi: add support for uImage.FIT sub-partitions
  mtd: add option to enable scanning for partitions

 MAINTAINERS               |   6 +
 block/blk.h               |   1 +
 block/partitions/Kconfig  |  15 ++
 block/partitions/Makefile |   1 +
 block/partitions/check.h  |   4 +
 block/partitions/core.c   |   6 +
 block/partitions/efi.c    |   9 +
 block/partitions/efi.h    |   3 +
 block/partitions/fit.c    | 346 ++++++++++++++++++++++++++++++++++++++
 drivers/mtd/Kconfig       |  11 ++
 drivers/mtd/mtd_blkdevs.c |   4 +-
 drivers/mtd/ubi/block.c   |   5 +-
 12 files changed, 409 insertions(+), 2 deletions(-)
 create mode 100644 block/partitions/fit.c

-- 
2.38.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 0/4] partition parser for U-Boot's uImage.FIT
@ 2022-11-15 21:45 ` Daniel Golle
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:45 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Add uImage.FIT partition parser and wire it up to allow mounting
filesystem sub-images from uImage.FIT in GPT partitions as well as
mtdblock and ubiblock devices within Linux (e.g. as root filesystem).

Using uImage.FIT to store the root filesystem besides kernel and dtb has
several obvious advantages which are hard to obtain in any other way:
 * single image accross different storage types
 * dynamically sized partitions for kernel and rootfs
 * hash also for rootfs checked by U-Boot before launching kernel
 * images may include additional filesystems e.g. for localization or
   branding

For this to work, the image has to be created with external data and
sub-images aligned to the system's memory page boundaries, ie.
 mkimage -E -B 0x1000 -p 0x1000 ...

Booting such images has been supported by U-Boot since v2018.01.

A previous version of this partition parser is in production use on some
OpenWrt devices, eg. the BananaPi R64 where using the FIT parser allows
booting the very same image from eMMC, SD Card or SPI-NAND/UBI and also
using it as a firmware-upgrade image at the same time.
The Ubiquiti UniFi 6 LR access point served as a reference board with
SPI-NOR flash and use of the partition parser on top of a mtdblock
device.

As U-Boot by now also passes down the selected configuration node name
via device tree this allows the partition parser (or userspace process
via sysfs) to identify the selected image configuration.

Device Tree schema for that:
https://github.com/devicetree-org/dt-schema/commit/a24d97d43491e55d4def006213213a6c4045b646

In most cases this partition parser can be used without relying on the
bootloader to pass-down the configuration node name. The default
configuration node is used then.

Changes since v4:
 * use folio instead of page (requested by Matthew Wilcox)
 * remove unneeded checks (requested by Matthew Wilcox)
 * use strscpy instead of strlcpy (strlcpy is deprecated)
 * fix off-by-one string size limit label_min (discovered during tests)
 * use only a single config symbol MTD_BLOCK_PARTITION affecting both
   ubiblock and mtdblock (requested by Richard Weinberger)

Changes since v3:
 * use min_t(size_t, ...)

Changes since v2:
 * use returned length to limit all strings read from fit/dt
 * use __be32 type for 32-bit values read from fit/dt
Reported-by: kernel test robot <lkp@intel.com>
 * Kconfig: select LIBFDT for FIT_PARTITION
Reported-by: kernel test robot <lkp@intel.com>

Changes since v1:
 * Use again #ifdef's in partitions/efi to only build against FIT
   parser symbols if it is actually selected. Otherwise the efi/gpt
   would unconditionally depend on the FTT parser to be present.

Changes since RFC:
 * fixed wrong variable used in error path
 * introduced dedicated Kconfig options to enable partition
   parsers on mtdblock and ubiblock
 * drop #ifdef'ery, use IS_ENABLED(...) where needed

Daniel Golle (4):
  block: add new flag to add partitions read-only
  block: add partition parser for U-Boot uImage.FIT
  partitions/efi: add support for uImage.FIT sub-partitions
  mtd: add option to enable scanning for partitions

 MAINTAINERS               |   6 +
 block/blk.h               |   1 +
 block/partitions/Kconfig  |  15 ++
 block/partitions/Makefile |   1 +
 block/partitions/check.h  |   4 +
 block/partitions/core.c   |   6 +
 block/partitions/efi.c    |   9 +
 block/partitions/efi.h    |   3 +
 block/partitions/fit.c    | 346 ++++++++++++++++++++++++++++++++++++++
 drivers/mtd/Kconfig       |  11 ++
 drivers/mtd/mtd_blkdevs.c |   4 +-
 drivers/mtd/ubi/block.c   |   5 +-
 12 files changed, 409 insertions(+), 2 deletions(-)
 create mode 100644 block/partitions/fit.c

-- 
2.38.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5 1/4] block: add new flag to add partitions read-only
  2022-11-15 21:45 ` Daniel Golle
@ 2022-11-15 21:45   ` Daniel Golle
  -1 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:45 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Add flag ADDPART_FLAG_READONLY to allow partition parsers marking a
partition to be set read-only.
This is needed for the uImage.FIT partition parser added by a follow-up
commit: we need to be sure the contents of uImage.FIT sub-images
remain unaltered they are validated using a hash within the uImage.FIT
structure which also serves as partition table.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 block/blk.h             | 1 +
 block/partitions/core.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/block/blk.h b/block/blk.h
index e85703ae81dd..05ac426350b2 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -414,6 +414,7 @@ void blk_free_ext_minor(unsigned int minor);
 #define ADDPART_FLAG_NONE	0
 #define ADDPART_FLAG_RAID	1
 #define ADDPART_FLAG_WHOLEDISK	2
+#define ADDPART_FLAG_READONLY	4
 int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
 		sector_t length);
 int bdev_del_partition(struct gendisk *disk, int partno);
diff --git a/block/partitions/core.c b/block/partitions/core.c
index b8112f52d388..355646b0707d 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -398,6 +398,9 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
 			goto out_del;
 	}
 
+	if (flags & ADDPART_FLAG_READONLY)
+		bdev->bd_read_only = true;
+
 	/* everything is up and running, commence */
 	err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
 	if (err)
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v5 1/4] block: add new flag to add partitions read-only
@ 2022-11-15 21:45   ` Daniel Golle
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:45 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Add flag ADDPART_FLAG_READONLY to allow partition parsers marking a
partition to be set read-only.
This is needed for the uImage.FIT partition parser added by a follow-up
commit: we need to be sure the contents of uImage.FIT sub-images
remain unaltered they are validated using a hash within the uImage.FIT
structure which also serves as partition table.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 block/blk.h             | 1 +
 block/partitions/core.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/block/blk.h b/block/blk.h
index e85703ae81dd..05ac426350b2 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -414,6 +414,7 @@ void blk_free_ext_minor(unsigned int minor);
 #define ADDPART_FLAG_NONE	0
 #define ADDPART_FLAG_RAID	1
 #define ADDPART_FLAG_WHOLEDISK	2
+#define ADDPART_FLAG_READONLY	4
 int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
 		sector_t length);
 int bdev_del_partition(struct gendisk *disk, int partno);
diff --git a/block/partitions/core.c b/block/partitions/core.c
index b8112f52d388..355646b0707d 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -398,6 +398,9 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
 			goto out_del;
 	}
 
+	if (flags & ADDPART_FLAG_READONLY)
+		bdev->bd_read_only = true;
+
 	/* everything is up and running, commence */
 	err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
 	if (err)
-- 
2.38.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v5 2/4] block: add partition parser for U-Boot uImage.FIT
  2022-11-15 21:45 ` Daniel Golle
@ 2022-11-15 21:46   ` Daniel Golle
  -1 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:46 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Introduce a new partition parser for U-Boot's Flattened-Image-Tree (FIT) in
order to allow Linux to mount the filesystem part of a uImage.FIT.

uImage.FIT needs to be created with external data and aligned to the
system's memory page size. e.g.
 mkimage -E -B 0x1000 -p 0x1000 ...

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS               |   6 +
 block/partitions/Kconfig  |  15 ++
 block/partitions/Makefile |   1 +
 block/partitions/check.h  |   4 +
 block/partitions/core.c   |   3 +
 block/partitions/fit.c    | 346 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 375 insertions(+)
 create mode 100644 block/partitions/fit.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 547ba994ea98..632672eb33ee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8059,6 +8059,12 @@ F:	Documentation/firmware_class/
 F:	drivers/base/firmware_loader/
 F:	include/linux/firmware.h
 
+FIT PARTITION TABLE (uImage.FIT)
+M:	Daniel Golle <daniel@makrotopia.org>
+L:	linux-block@vger.kernel.org
+S:	Maintained
+F:	block/partitions/fit.c
+
 FLEXTIMER FTM-QUADDEC DRIVER
 M:	Patrick Havelange <patrick.havelange@essensium.com>
 L:	linux-iio@vger.kernel.org
diff --git a/block/partitions/Kconfig b/block/partitions/Kconfig
index 7aff4eb81c60..77dc85d3797d 100644
--- a/block/partitions/Kconfig
+++ b/block/partitions/Kconfig
@@ -103,6 +103,21 @@ config ATARI_PARTITION
 	  Say Y here if you would like to use hard disks under Linux which
 	  were partitioned under the Atari OS.
 
+config FIT_PARTITION
+	bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
+	default n
+	select LIBFDT
+	help
+	  Say Y here if your system needs to mount the filesystem part of
+	  a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
+
+	  uImage.FIT needs to be created with external data and aligned to
+	  the systems memory page size. e.g.
+	    mkimage -E -B 0x1000 -p 0x1000 ...
+
+	  If your system doesn't use U-Boot or you don't need to mount uImage.FIT
+	  filesystem sub-images in Linux, say N.
+
 config IBM_PARTITION
 	bool "IBM disk label and partition support"
 	depends on PARTITION_ADVANCED && S390
diff --git a/block/partitions/Makefile b/block/partitions/Makefile
index a7f05cdb02a8..d319eb1deba9 100644
--- a/block/partitions/Makefile
+++ b/block/partitions/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
 obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
 obj-$(CONFIG_ATARI_PARTITION) += atari.o
 obj-$(CONFIG_AIX_PARTITION) += aix.o
+obj-$(CONFIG_FIT_PARTITION) += fit.o
 obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
 obj-$(CONFIG_MAC_PARTITION) += mac.o
 obj-$(CONFIG_LDM_PARTITION) += ldm.o
diff --git a/block/partitions/check.h b/block/partitions/check.h
index 8d70a880c372..76b006d3cb27 100644
--- a/block/partitions/check.h
+++ b/block/partitions/check.h
@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partitions *state);
 int atari_partition(struct parsed_partitions *state);
 int cmdline_partition(struct parsed_partitions *state);
 int efi_partition(struct parsed_partitions *state);
+int fit_partition(struct parsed_partitions *state);
 int ibm_partition(struct parsed_partitions *);
 int karma_partition(struct parsed_partitions *state);
 int ldm_partition(struct parsed_partitions *state);
@@ -67,3 +68,6 @@ int sgi_partition(struct parsed_partitions *state);
 int sun_partition(struct parsed_partitions *state);
 int sysv68_partition(struct parsed_partitions *state);
 int ultrix_partition(struct parsed_partitions *state);
+
+int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector,
+			 u64 sectors, int *slot, int max_slot, bool add_remain);
diff --git a/block/partitions/core.c b/block/partitions/core.c
index 355646b0707d..9d4bb8f48d35 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -43,6 +43,9 @@ static int (*check_part[])(struct parsed_partitions *) = {
 #ifdef CONFIG_CMDLINE_PARTITION
 	cmdline_partition,
 #endif
+#ifdef CONFIG_FIT_PARTITION
+	fit_partition,
+#endif
 #ifdef CONFIG_EFI_PARTITION
 	efi_partition,		/* this must come before msdos */
 #endif
diff --git a/block/partitions/fit.c b/block/partitions/fit.c
new file mode 100644
index 000000000000..1c19a250f8e6
--- /dev/null
+++ b/block/partitions/fit.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  fs/partitions/fit.c
+ *  Copyright (C) 2021  Daniel Golle
+ *
+ *  headers extracted from U-Boot mkimage sources
+ *  (C) Copyright 2008 Semihalf
+ *  (C) Copyright 2000-2005
+ *  Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ *  based on existing partition parsers
+ *  Copyright (C) 1991-1998  Linus Torvalds
+ *  Re-organised Feb 1998 Russell King
+ */
+
+#include <linux/libfdt.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_fdt.h>
+#include <linux/types.h>
+
+#include "check.h"
+
+#define FIT_IMAGES_PATH		"/images"
+#define FIT_CONFS_PATH		"/configurations"
+
+/* hash/signature/key node */
+#define FIT_HASH_NODENAME	"hash"
+#define FIT_ALGO_PROP		"algo"
+#define FIT_VALUE_PROP		"value"
+#define FIT_IGNORE_PROP		"uboot-ignore"
+#define FIT_SIG_NODENAME	"signature"
+#define FIT_KEY_REQUIRED	"required"
+#define FIT_KEY_HINT		"key-name-hint"
+
+/* cipher node */
+#define FIT_CIPHER_NODENAME	"cipher"
+#define FIT_ALGO_PROP		"algo"
+
+/* image node */
+#define FIT_DATA_PROP		"data"
+#define FIT_DATA_POSITION_PROP	"data-position"
+#define FIT_DATA_OFFSET_PROP	"data-offset"
+#define FIT_DATA_SIZE_PROP	"data-size"
+#define FIT_TIMESTAMP_PROP	"timestamp"
+#define FIT_DESC_PROP		"description"
+#define FIT_ARCH_PROP		"arch"
+#define FIT_TYPE_PROP		"type"
+#define FIT_OS_PROP		"os"
+#define FIT_COMP_PROP		"compression"
+#define FIT_ENTRY_PROP		"entry"
+#define FIT_LOAD_PROP		"load"
+
+/* configuration node */
+#define FIT_KERNEL_PROP		"kernel"
+#define FIT_FILESYSTEM_PROP	"filesystem"
+#define FIT_RAMDISK_PROP	"ramdisk"
+#define FIT_FDT_PROP		"fdt"
+#define FIT_LOADABLE_PROP	"loadables"
+#define FIT_DEFAULT_PROP	"default"
+#define FIT_SETUP_PROP		"setup"
+#define FIT_FPGA_PROP		"fpga"
+#define FIT_FIRMWARE_PROP	"firmware"
+#define FIT_STANDALONE_PROP	"standalone"
+
+#define MIN_FREE_SECT		16
+#define REMAIN_VOLNAME		"rootfs_data"
+#define MAX_FIT_LOADABLES	16
+
+/**
+ * parse_fit_partitions - map uImage.FIT filesystem sub-images into sub-partitions
+ * @state: pointer to partition parser state
+ * @fit_start_sector: start sector of the FIT structure on disk
+ * @sectors: number of sectors of the uImage.FIT partition or 0 if whole device
+ * @slot: pointer to the current partition slot number
+ * @add_remain: map unused sectors into additional partition
+ *
+ * To be called by other partition parsers on physical block devices or using
+ * wrapper function int fit_partition(struct parsed_partitions *state) for the
+ * whole disk, relevant typically for ubiblock or mtdblock devices.
+ */
+int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector,
+			 u64 sectors, int *slot, int max_slot, bool add_remain)
+{
+	struct block_device *bdev = state->disk->part0;
+	struct address_space *mapping = bdev->bd_inode->i_mapping;
+	struct folio *folio;
+	void *fit, *init_fit;
+	struct partition_meta_info *info;
+	char tmp[sizeof(info->volname) + 2]; /* 2 extra bytes for parentheses */
+	u64 dsize, dsectors, imgmaxsect = 0;
+	u32 size, image_pos, image_len;
+	const __be32 *image_offset_be, *image_len_be, *image_pos_be;
+	int ret = 1, node, images, config;
+	const char *image_name, *image_type, *image_description,
+		*config_default, *config_description, *config_loadables;
+	u32 image_name_len, image_type_len, image_description_len,
+		config_default_len, config_description_len,
+		config_loadables_len;
+	sector_t start_sect, nr_sects;
+	size_t label_min;
+	struct device_node *np = NULL;
+	const char *bootconf;
+	const char *loadable;
+	bool found;
+	int loadables_rem_len, loadable_len;
+	u16 loadcnt;
+
+	/* uImage.FIT should be aligned to page boundaries */
+	if (fit_start_sector % (1 << (PAGE_SHIFT - SECTOR_SHIFT)))
+		return 0;
+
+	/* map first page */
+	folio = read_mapping_folio(
+		mapping, fit_start_sector >> (PAGE_SHIFT - SECTOR_SHIFT), NULL);
+
+	if (IS_ERR(folio))
+		return PTR_ERR(folio);
+
+	init_fit = folio_address(folio) + offset_in_folio(folio, fit_start_sector * SECTOR_SIZE);
+
+	/* uImage.FIT is based on flattened device tree structure */
+	if (fdt_check_header(init_fit)) {
+		folio_put(folio);
+		return 0;
+	}
+
+	/* acquire disk or partition size */
+	dsectors = get_capacity(bdev->bd_disk);
+	if (sectors)
+		dsectors = min_t(u64, sectors, dsectors);
+
+	dsize = dsectors << SECTOR_SHIFT;
+	size = fdt_totalsize(init_fit);
+
+	/* silently skip non-external-data legacy uImage.FIT */
+	if (size > PAGE_SIZE) {
+		folio_put(folio);
+		return 0;
+	}
+
+	/* abort if FIT structure is larger than disk or partition size */
+	if (size >= dsize) {
+		state->access_beyond_eod = 1;
+		folio_put(folio);
+		return -EFBIG;
+	}
+
+	/*
+	 * copy FIT structure for further processing
+	 * this is necessary for libfdt to work
+	 */
+	fit = kmemdup(init_fit, size, GFP_KERNEL);
+	folio_put(folio);
+	if (!fit)
+		return -ENOMEM;
+
+	/* set boot config node name U-Boot may have added to the device tree */
+	np = of_find_node_by_path("/chosen");
+	if (np)
+		bootconf = of_get_property(np, "u-boot,bootconf", NULL);
+	else
+		bootconf = NULL;
+
+	/* find configuration path in uImage.FIT */
+	config = fdt_path_offset(fit, FIT_CONFS_PATH);
+	if (config < 0) {
+		pr_err("FIT: Cannot find %s node: %d\n",
+		       FIT_CONFS_PATH, config);
+		ret = -ENOENT;
+		goto ret_out;
+	}
+
+	/* get default configuration node name */
+	config_default =
+		fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len);
+
+	/* make sure we got either default or selected boot config node name */
+	if (!config_default && !bootconf) {
+		pr_err("FIT: Cannot find default configuration\n");
+		ret = -ENOENT;
+		goto ret_out;
+	}
+
+	/* find selected boot config node, fallback on default config node */
+	node = fdt_subnode_offset(fit, config, bootconf ?: config_default);
+	if (node < 0) {
+		pr_err("FIT: Cannot find %s node: %d\n",
+		       bootconf ?: config_default, node);
+		ret = -ENOENT;
+		goto ret_out;
+	}
+
+	/* get selected configuration data */
+	config_description =
+		fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len);
+	config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP,
+				       &config_loadables_len);
+
+	pr_info("FIT: %s configuration: \"%s\"%s%.*s%s\n",
+		bootconf ? "Selected" : "Default", bootconf ?: config_default,
+		config_description ? " (" : "",
+		config_description ? config_description_len : 0,
+		config_description ?: "",
+		config_description ? ")" : "");
+
+	if (!config_loadables || !config_loadables_len) {
+		pr_err("FIT: No loadables configured in \"%s\"\n",
+		       bootconf ?: config_default);
+		ret = -ENOENT;
+		goto ret_out;
+	}
+
+	/* get images path in uImage.FIT */
+	images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+	if (images < 0) {
+		pr_err("FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images);
+		ret = -EINVAL;
+		goto ret_out;
+	}
+
+	/* allocate one slot for mapping remaing space */
+	if (add_remain)
+		--max_slot;
+
+	/* iterate over images in uImage.FIT */
+	fdt_for_each_subnode(node, fit, images) {
+		image_name = fdt_get_name(fit, node, &image_name_len);
+		image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len);
+		image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL);
+		image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL);
+		image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL);
+
+		if (!image_name || !image_type || !image_len_be)
+			continue;
+
+		image_len = be32_to_cpu(*image_len_be);
+		if (!image_len)
+			continue;
+
+		if (image_offset_be)
+			image_pos = be32_to_cpu(*image_offset_be) + size;
+		else if (image_pos_be)
+			image_pos = be32_to_cpu(*image_pos_be);
+		else
+			continue;
+
+		image_description = fdt_getprop(fit, node, FIT_DESC_PROP,
+						&image_description_len);
+
+		pr_info("FIT: %16s sub-image 0x%08x..0x%08x \"%.*s\"%s%.*s%s\n",
+			image_type, image_pos, image_pos + image_len - 1,
+			image_name_len, image_name, image_description ? " (" : "",
+			image_description ? image_description_len : 0,
+			image_description ?: "", image_description ? ") " : "");
+
+		/* only 'filesystem' images should be mapped as partitions */
+		if (strncmp(image_type, FIT_FILESYSTEM_PROP, image_type_len))
+			continue;
+
+		/* check if sub-image is part of configured loadables */
+		found = false;
+		loadable = config_loadables;
+		loadables_rem_len = config_loadables_len;
+		for (loadcnt = 0; loadables_rem_len > 1 &&
+				  loadcnt < MAX_FIT_LOADABLES; ++loadcnt) {
+			loadable_len =
+				strnlen(loadable, loadables_rem_len - 1) + 1;
+			loadables_rem_len -= loadable_len;
+			if (!strncmp(image_name, loadable, loadable_len)) {
+				found = true;
+				break;
+			}
+			loadable += loadable_len;
+		}
+		if (!found)
+			continue;
+
+		if (image_pos % (1 << PAGE_SHIFT)) {
+			pr_err("FIT: image %.*s start not aligned to page boundaries, skipping\n",
+			       image_name_len, image_name);
+			continue;
+		}
+
+		if (image_len % (1 << PAGE_SHIFT)) {
+			pr_err("FIT: sub-image %.*s end not aligned to page boundaries, skipping\n",
+			       image_name_len, image_name);
+			continue;
+		}
+
+		start_sect = image_pos >> SECTOR_SHIFT;
+		nr_sects = image_len >> SECTOR_SHIFT;
+		imgmaxsect = (imgmaxsect < (start_sect + nr_sects)) ?
+				     (start_sect + nr_sects) :
+					   imgmaxsect;
+
+		if (start_sect + nr_sects > dsectors) {
+			state->access_beyond_eod = 1;
+			continue;
+		}
+
+		put_partition(state, *slot, fit_start_sector + start_sect,
+			      nr_sects);
+		state->parts[*slot].flags = ADDPART_FLAG_READONLY;
+		state->parts[*slot].has_info = true;
+		info = &state->parts[*slot].info;
+
+		label_min = min_t(size_t, sizeof(info->volname), image_name_len + 1);
+		strscpy(info->volname, image_name, label_min);
+
+		snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
+		strlcat(state->pp_buf, tmp, PAGE_SIZE);
+
+		if (++(*slot) > max_slot)
+			break;
+	}
+
+	/* in case uImage.FIT is stored in a partition, map the remaining space */
+	if (add_remain && (imgmaxsect + MIN_FREE_SECT) < dsectors) {
+		put_partition(state, *slot, fit_start_sector + imgmaxsect,
+			      dsectors - imgmaxsect);
+		state->parts[*slot].flags = 0;
+		info = &state->parts[*slot].info;
+		strcpy(info->volname, REMAIN_VOLNAME);
+		snprintf(tmp, sizeof(tmp), "(%s)", REMAIN_VOLNAME);
+		strlcat(state->pp_buf, tmp, PAGE_SIZE);
+		++(*slot);
+	}
+ret_out:
+	kfree(fit);
+	return ret;
+}
+
+/**
+ * fit_partition - map uImage.FIT filesystem sub-images into partitions
+ * @state: pointer to partition parser state
+ *
+ * Used to parse uImage.FIT structure for images directly stored on
+ * the whole block device (typically ubiblock or mtdblock).
+ */
+int fit_partition(struct parsed_partitions *state)
+{
+	int slot = 1;
+
+	return parse_fit_partitions(state, 0, 0, &slot, MAX_FIT_LOADABLES, false);
+}
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v5 2/4] block: add partition parser for U-Boot uImage.FIT
@ 2022-11-15 21:46   ` Daniel Golle
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:46 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Introduce a new partition parser for U-Boot's Flattened-Image-Tree (FIT) in
order to allow Linux to mount the filesystem part of a uImage.FIT.

uImage.FIT needs to be created with external data and aligned to the
system's memory page size. e.g.
 mkimage -E -B 0x1000 -p 0x1000 ...

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS               |   6 +
 block/partitions/Kconfig  |  15 ++
 block/partitions/Makefile |   1 +
 block/partitions/check.h  |   4 +
 block/partitions/core.c   |   3 +
 block/partitions/fit.c    | 346 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 375 insertions(+)
 create mode 100644 block/partitions/fit.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 547ba994ea98..632672eb33ee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8059,6 +8059,12 @@ F:	Documentation/firmware_class/
 F:	drivers/base/firmware_loader/
 F:	include/linux/firmware.h
 
+FIT PARTITION TABLE (uImage.FIT)
+M:	Daniel Golle <daniel@makrotopia.org>
+L:	linux-block@vger.kernel.org
+S:	Maintained
+F:	block/partitions/fit.c
+
 FLEXTIMER FTM-QUADDEC DRIVER
 M:	Patrick Havelange <patrick.havelange@essensium.com>
 L:	linux-iio@vger.kernel.org
diff --git a/block/partitions/Kconfig b/block/partitions/Kconfig
index 7aff4eb81c60..77dc85d3797d 100644
--- a/block/partitions/Kconfig
+++ b/block/partitions/Kconfig
@@ -103,6 +103,21 @@ config ATARI_PARTITION
 	  Say Y here if you would like to use hard disks under Linux which
 	  were partitioned under the Atari OS.
 
+config FIT_PARTITION
+	bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
+	default n
+	select LIBFDT
+	help
+	  Say Y here if your system needs to mount the filesystem part of
+	  a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
+
+	  uImage.FIT needs to be created with external data and aligned to
+	  the systems memory page size. e.g.
+	    mkimage -E -B 0x1000 -p 0x1000 ...
+
+	  If your system doesn't use U-Boot or you don't need to mount uImage.FIT
+	  filesystem sub-images in Linux, say N.
+
 config IBM_PARTITION
 	bool "IBM disk label and partition support"
 	depends on PARTITION_ADVANCED && S390
diff --git a/block/partitions/Makefile b/block/partitions/Makefile
index a7f05cdb02a8..d319eb1deba9 100644
--- a/block/partitions/Makefile
+++ b/block/partitions/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
 obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
 obj-$(CONFIG_ATARI_PARTITION) += atari.o
 obj-$(CONFIG_AIX_PARTITION) += aix.o
+obj-$(CONFIG_FIT_PARTITION) += fit.o
 obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
 obj-$(CONFIG_MAC_PARTITION) += mac.o
 obj-$(CONFIG_LDM_PARTITION) += ldm.o
diff --git a/block/partitions/check.h b/block/partitions/check.h
index 8d70a880c372..76b006d3cb27 100644
--- a/block/partitions/check.h
+++ b/block/partitions/check.h
@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partitions *state);
 int atari_partition(struct parsed_partitions *state);
 int cmdline_partition(struct parsed_partitions *state);
 int efi_partition(struct parsed_partitions *state);
+int fit_partition(struct parsed_partitions *state);
 int ibm_partition(struct parsed_partitions *);
 int karma_partition(struct parsed_partitions *state);
 int ldm_partition(struct parsed_partitions *state);
@@ -67,3 +68,6 @@ int sgi_partition(struct parsed_partitions *state);
 int sun_partition(struct parsed_partitions *state);
 int sysv68_partition(struct parsed_partitions *state);
 int ultrix_partition(struct parsed_partitions *state);
+
+int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector,
+			 u64 sectors, int *slot, int max_slot, bool add_remain);
diff --git a/block/partitions/core.c b/block/partitions/core.c
index 355646b0707d..9d4bb8f48d35 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -43,6 +43,9 @@ static int (*check_part[])(struct parsed_partitions *) = {
 #ifdef CONFIG_CMDLINE_PARTITION
 	cmdline_partition,
 #endif
+#ifdef CONFIG_FIT_PARTITION
+	fit_partition,
+#endif
 #ifdef CONFIG_EFI_PARTITION
 	efi_partition,		/* this must come before msdos */
 #endif
diff --git a/block/partitions/fit.c b/block/partitions/fit.c
new file mode 100644
index 000000000000..1c19a250f8e6
--- /dev/null
+++ b/block/partitions/fit.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  fs/partitions/fit.c
+ *  Copyright (C) 2021  Daniel Golle
+ *
+ *  headers extracted from U-Boot mkimage sources
+ *  (C) Copyright 2008 Semihalf
+ *  (C) Copyright 2000-2005
+ *  Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ *  based on existing partition parsers
+ *  Copyright (C) 1991-1998  Linus Torvalds
+ *  Re-organised Feb 1998 Russell King
+ */
+
+#include <linux/libfdt.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_fdt.h>
+#include <linux/types.h>
+
+#include "check.h"
+
+#define FIT_IMAGES_PATH		"/images"
+#define FIT_CONFS_PATH		"/configurations"
+
+/* hash/signature/key node */
+#define FIT_HASH_NODENAME	"hash"
+#define FIT_ALGO_PROP		"algo"
+#define FIT_VALUE_PROP		"value"
+#define FIT_IGNORE_PROP		"uboot-ignore"
+#define FIT_SIG_NODENAME	"signature"
+#define FIT_KEY_REQUIRED	"required"
+#define FIT_KEY_HINT		"key-name-hint"
+
+/* cipher node */
+#define FIT_CIPHER_NODENAME	"cipher"
+#define FIT_ALGO_PROP		"algo"
+
+/* image node */
+#define FIT_DATA_PROP		"data"
+#define FIT_DATA_POSITION_PROP	"data-position"
+#define FIT_DATA_OFFSET_PROP	"data-offset"
+#define FIT_DATA_SIZE_PROP	"data-size"
+#define FIT_TIMESTAMP_PROP	"timestamp"
+#define FIT_DESC_PROP		"description"
+#define FIT_ARCH_PROP		"arch"
+#define FIT_TYPE_PROP		"type"
+#define FIT_OS_PROP		"os"
+#define FIT_COMP_PROP		"compression"
+#define FIT_ENTRY_PROP		"entry"
+#define FIT_LOAD_PROP		"load"
+
+/* configuration node */
+#define FIT_KERNEL_PROP		"kernel"
+#define FIT_FILESYSTEM_PROP	"filesystem"
+#define FIT_RAMDISK_PROP	"ramdisk"
+#define FIT_FDT_PROP		"fdt"
+#define FIT_LOADABLE_PROP	"loadables"
+#define FIT_DEFAULT_PROP	"default"
+#define FIT_SETUP_PROP		"setup"
+#define FIT_FPGA_PROP		"fpga"
+#define FIT_FIRMWARE_PROP	"firmware"
+#define FIT_STANDALONE_PROP	"standalone"
+
+#define MIN_FREE_SECT		16
+#define REMAIN_VOLNAME		"rootfs_data"
+#define MAX_FIT_LOADABLES	16
+
+/**
+ * parse_fit_partitions - map uImage.FIT filesystem sub-images into sub-partitions
+ * @state: pointer to partition parser state
+ * @fit_start_sector: start sector of the FIT structure on disk
+ * @sectors: number of sectors of the uImage.FIT partition or 0 if whole device
+ * @slot: pointer to the current partition slot number
+ * @add_remain: map unused sectors into additional partition
+ *
+ * To be called by other partition parsers on physical block devices or using
+ * wrapper function int fit_partition(struct parsed_partitions *state) for the
+ * whole disk, relevant typically for ubiblock or mtdblock devices.
+ */
+int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector,
+			 u64 sectors, int *slot, int max_slot, bool add_remain)
+{
+	struct block_device *bdev = state->disk->part0;
+	struct address_space *mapping = bdev->bd_inode->i_mapping;
+	struct folio *folio;
+	void *fit, *init_fit;
+	struct partition_meta_info *info;
+	char tmp[sizeof(info->volname) + 2]; /* 2 extra bytes for parentheses */
+	u64 dsize, dsectors, imgmaxsect = 0;
+	u32 size, image_pos, image_len;
+	const __be32 *image_offset_be, *image_len_be, *image_pos_be;
+	int ret = 1, node, images, config;
+	const char *image_name, *image_type, *image_description,
+		*config_default, *config_description, *config_loadables;
+	u32 image_name_len, image_type_len, image_description_len,
+		config_default_len, config_description_len,
+		config_loadables_len;
+	sector_t start_sect, nr_sects;
+	size_t label_min;
+	struct device_node *np = NULL;
+	const char *bootconf;
+	const char *loadable;
+	bool found;
+	int loadables_rem_len, loadable_len;
+	u16 loadcnt;
+
+	/* uImage.FIT should be aligned to page boundaries */
+	if (fit_start_sector % (1 << (PAGE_SHIFT - SECTOR_SHIFT)))
+		return 0;
+
+	/* map first page */
+	folio = read_mapping_folio(
+		mapping, fit_start_sector >> (PAGE_SHIFT - SECTOR_SHIFT), NULL);
+
+	if (IS_ERR(folio))
+		return PTR_ERR(folio);
+
+	init_fit = folio_address(folio) + offset_in_folio(folio, fit_start_sector * SECTOR_SIZE);
+
+	/* uImage.FIT is based on flattened device tree structure */
+	if (fdt_check_header(init_fit)) {
+		folio_put(folio);
+		return 0;
+	}
+
+	/* acquire disk or partition size */
+	dsectors = get_capacity(bdev->bd_disk);
+	if (sectors)
+		dsectors = min_t(u64, sectors, dsectors);
+
+	dsize = dsectors << SECTOR_SHIFT;
+	size = fdt_totalsize(init_fit);
+
+	/* silently skip non-external-data legacy uImage.FIT */
+	if (size > PAGE_SIZE) {
+		folio_put(folio);
+		return 0;
+	}
+
+	/* abort if FIT structure is larger than disk or partition size */
+	if (size >= dsize) {
+		state->access_beyond_eod = 1;
+		folio_put(folio);
+		return -EFBIG;
+	}
+
+	/*
+	 * copy FIT structure for further processing
+	 * this is necessary for libfdt to work
+	 */
+	fit = kmemdup(init_fit, size, GFP_KERNEL);
+	folio_put(folio);
+	if (!fit)
+		return -ENOMEM;
+
+	/* set boot config node name U-Boot may have added to the device tree */
+	np = of_find_node_by_path("/chosen");
+	if (np)
+		bootconf = of_get_property(np, "u-boot,bootconf", NULL);
+	else
+		bootconf = NULL;
+
+	/* find configuration path in uImage.FIT */
+	config = fdt_path_offset(fit, FIT_CONFS_PATH);
+	if (config < 0) {
+		pr_err("FIT: Cannot find %s node: %d\n",
+		       FIT_CONFS_PATH, config);
+		ret = -ENOENT;
+		goto ret_out;
+	}
+
+	/* get default configuration node name */
+	config_default =
+		fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len);
+
+	/* make sure we got either default or selected boot config node name */
+	if (!config_default && !bootconf) {
+		pr_err("FIT: Cannot find default configuration\n");
+		ret = -ENOENT;
+		goto ret_out;
+	}
+
+	/* find selected boot config node, fallback on default config node */
+	node = fdt_subnode_offset(fit, config, bootconf ?: config_default);
+	if (node < 0) {
+		pr_err("FIT: Cannot find %s node: %d\n",
+		       bootconf ?: config_default, node);
+		ret = -ENOENT;
+		goto ret_out;
+	}
+
+	/* get selected configuration data */
+	config_description =
+		fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len);
+	config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP,
+				       &config_loadables_len);
+
+	pr_info("FIT: %s configuration: \"%s\"%s%.*s%s\n",
+		bootconf ? "Selected" : "Default", bootconf ?: config_default,
+		config_description ? " (" : "",
+		config_description ? config_description_len : 0,
+		config_description ?: "",
+		config_description ? ")" : "");
+
+	if (!config_loadables || !config_loadables_len) {
+		pr_err("FIT: No loadables configured in \"%s\"\n",
+		       bootconf ?: config_default);
+		ret = -ENOENT;
+		goto ret_out;
+	}
+
+	/* get images path in uImage.FIT */
+	images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+	if (images < 0) {
+		pr_err("FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images);
+		ret = -EINVAL;
+		goto ret_out;
+	}
+
+	/* allocate one slot for mapping remaing space */
+	if (add_remain)
+		--max_slot;
+
+	/* iterate over images in uImage.FIT */
+	fdt_for_each_subnode(node, fit, images) {
+		image_name = fdt_get_name(fit, node, &image_name_len);
+		image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len);
+		image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL);
+		image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL);
+		image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL);
+
+		if (!image_name || !image_type || !image_len_be)
+			continue;
+
+		image_len = be32_to_cpu(*image_len_be);
+		if (!image_len)
+			continue;
+
+		if (image_offset_be)
+			image_pos = be32_to_cpu(*image_offset_be) + size;
+		else if (image_pos_be)
+			image_pos = be32_to_cpu(*image_pos_be);
+		else
+			continue;
+
+		image_description = fdt_getprop(fit, node, FIT_DESC_PROP,
+						&image_description_len);
+
+		pr_info("FIT: %16s sub-image 0x%08x..0x%08x \"%.*s\"%s%.*s%s\n",
+			image_type, image_pos, image_pos + image_len - 1,
+			image_name_len, image_name, image_description ? " (" : "",
+			image_description ? image_description_len : 0,
+			image_description ?: "", image_description ? ") " : "");
+
+		/* only 'filesystem' images should be mapped as partitions */
+		if (strncmp(image_type, FIT_FILESYSTEM_PROP, image_type_len))
+			continue;
+
+		/* check if sub-image is part of configured loadables */
+		found = false;
+		loadable = config_loadables;
+		loadables_rem_len = config_loadables_len;
+		for (loadcnt = 0; loadables_rem_len > 1 &&
+				  loadcnt < MAX_FIT_LOADABLES; ++loadcnt) {
+			loadable_len =
+				strnlen(loadable, loadables_rem_len - 1) + 1;
+			loadables_rem_len -= loadable_len;
+			if (!strncmp(image_name, loadable, loadable_len)) {
+				found = true;
+				break;
+			}
+			loadable += loadable_len;
+		}
+		if (!found)
+			continue;
+
+		if (image_pos % (1 << PAGE_SHIFT)) {
+			pr_err("FIT: image %.*s start not aligned to page boundaries, skipping\n",
+			       image_name_len, image_name);
+			continue;
+		}
+
+		if (image_len % (1 << PAGE_SHIFT)) {
+			pr_err("FIT: sub-image %.*s end not aligned to page boundaries, skipping\n",
+			       image_name_len, image_name);
+			continue;
+		}
+
+		start_sect = image_pos >> SECTOR_SHIFT;
+		nr_sects = image_len >> SECTOR_SHIFT;
+		imgmaxsect = (imgmaxsect < (start_sect + nr_sects)) ?
+				     (start_sect + nr_sects) :
+					   imgmaxsect;
+
+		if (start_sect + nr_sects > dsectors) {
+			state->access_beyond_eod = 1;
+			continue;
+		}
+
+		put_partition(state, *slot, fit_start_sector + start_sect,
+			      nr_sects);
+		state->parts[*slot].flags = ADDPART_FLAG_READONLY;
+		state->parts[*slot].has_info = true;
+		info = &state->parts[*slot].info;
+
+		label_min = min_t(size_t, sizeof(info->volname), image_name_len + 1);
+		strscpy(info->volname, image_name, label_min);
+
+		snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
+		strlcat(state->pp_buf, tmp, PAGE_SIZE);
+
+		if (++(*slot) > max_slot)
+			break;
+	}
+
+	/* in case uImage.FIT is stored in a partition, map the remaining space */
+	if (add_remain && (imgmaxsect + MIN_FREE_SECT) < dsectors) {
+		put_partition(state, *slot, fit_start_sector + imgmaxsect,
+			      dsectors - imgmaxsect);
+		state->parts[*slot].flags = 0;
+		info = &state->parts[*slot].info;
+		strcpy(info->volname, REMAIN_VOLNAME);
+		snprintf(tmp, sizeof(tmp), "(%s)", REMAIN_VOLNAME);
+		strlcat(state->pp_buf, tmp, PAGE_SIZE);
+		++(*slot);
+	}
+ret_out:
+	kfree(fit);
+	return ret;
+}
+
+/**
+ * fit_partition - map uImage.FIT filesystem sub-images into partitions
+ * @state: pointer to partition parser state
+ *
+ * Used to parse uImage.FIT structure for images directly stored on
+ * the whole block device (typically ubiblock or mtdblock).
+ */
+int fit_partition(struct parsed_partitions *state)
+{
+	int slot = 1;
+
+	return parse_fit_partitions(state, 0, 0, &slot, MAX_FIT_LOADABLES, false);
+}
-- 
2.38.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
  2022-11-15 21:45 ` Daniel Golle
@ 2022-11-15 21:47   ` Daniel Golle
  -1 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:47 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Add new GUID allowing to parse uImage.FIT stored in a GPT partition
and map filesystem sub-image as sub-partitions.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 block/partitions/efi.c | 9 +++++++++
 block/partitions/efi.h | 3 +++
 2 files changed, 12 insertions(+)

diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 5e9be13a56a8..f4406b443f04 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitions *state)
 	gpt_entry *ptes = NULL;
 	u32 i;
 	unsigned ssz = queue_logical_block_size(state->disk->queue) / 512;
+#ifdef CONFIG_FIT_PARTITION
+	u32 extra_slot = 65;
+#endif
 
 	if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
 		kfree(gpt);
@@ -749,6 +752,12 @@ int efi_partition(struct parsed_partitions *state)
 				ARRAY_SIZE(ptes[i].partition_name));
 		utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
 		state->parts[i + 1].has_info = true;
+		/* If this is a U-Boot FIT volume it may have subpartitions */
+#ifdef CONFIG_FIT_PARTITION
+		if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
+			(void) parse_fit_partitions(state, start * ssz, size * ssz,
+						    &extra_slot, 127, 1);
+#endif
 	}
 	kfree(ptes);
 	kfree(gpt);
diff --git a/block/partitions/efi.h b/block/partitions/efi.h
index 84b9f36b9e47..06c11f6ae398 100644
--- a/block/partitions/efi.h
+++ b/block/partitions/efi.h
@@ -51,6 +51,9 @@
 #define PARTITION_LINUX_LVM_GUID \
     EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
               0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
+#define PARTITION_LINUX_FIT_GUID \
+    EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
+              0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
 
 typedef struct _gpt_header {
 	__le64 signature;
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
@ 2022-11-15 21:47   ` Daniel Golle
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:47 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Add new GUID allowing to parse uImage.FIT stored in a GPT partition
and map filesystem sub-image as sub-partitions.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 block/partitions/efi.c | 9 +++++++++
 block/partitions/efi.h | 3 +++
 2 files changed, 12 insertions(+)

diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 5e9be13a56a8..f4406b443f04 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitions *state)
 	gpt_entry *ptes = NULL;
 	u32 i;
 	unsigned ssz = queue_logical_block_size(state->disk->queue) / 512;
+#ifdef CONFIG_FIT_PARTITION
+	u32 extra_slot = 65;
+#endif
 
 	if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
 		kfree(gpt);
@@ -749,6 +752,12 @@ int efi_partition(struct parsed_partitions *state)
 				ARRAY_SIZE(ptes[i].partition_name));
 		utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
 		state->parts[i + 1].has_info = true;
+		/* If this is a U-Boot FIT volume it may have subpartitions */
+#ifdef CONFIG_FIT_PARTITION
+		if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
+			(void) parse_fit_partitions(state, start * ssz, size * ssz,
+						    &extra_slot, 127, 1);
+#endif
 	}
 	kfree(ptes);
 	kfree(gpt);
diff --git a/block/partitions/efi.h b/block/partitions/efi.h
index 84b9f36b9e47..06c11f6ae398 100644
--- a/block/partitions/efi.h
+++ b/block/partitions/efi.h
@@ -51,6 +51,9 @@
 #define PARTITION_LINUX_LVM_GUID \
     EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
               0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
+#define PARTITION_LINUX_FIT_GUID \
+    EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
+              0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
 
 typedef struct _gpt_header {
 	__le64 signature;
-- 
2.38.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v5 4/4] mtd: add option to enable scanning for partitions
  2022-11-15 21:45 ` Daniel Golle
@ 2022-11-15 21:47   ` Daniel Golle
  -1 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:47 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Add Kconfig boolean CONFIG_MTD_BLOCK_PARTITIONS and enable block
partition parsers on non-NAND mtdblock as well as ubiblock devices
in case it is selected.
Never scan partitions on NAND-backed mtdblock devices, ubiblock
should be used instead.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/Kconfig       | 11 +++++++++++
 drivers/mtd/mtd_blkdevs.c |  4 +++-
 drivers/mtd/ubi/block.c   |  5 ++++-
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 796a2eccbef0..12874dec1569 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -69,6 +69,17 @@ config MTD_BLOCK_RO
 	  You do not need this option for use with the DiskOnChip devices. For
 	  those, enable NFTL support (CONFIG_NFTL) instead.
 
+config MTD_BLOCK_PARTITIONS
+	bool "Scan for partitions on MTD block devices"
+	depends on MTD_BLOCK || MTD_BLOCK_RO
+	default y if FIT_PARTITION
+	help
+	  Scan MTD block devices for partitions (ie. MBR, GPT, uImage.FIT, ...).
+	  (NAND devices are omitted, ubiblock should be used instead when)
+
+	  Unless your MTD partitions contain sub-partitions mapped using a
+	  partition table, say no.
+
 comment "Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK."
 	depends on MTD_BLOCK || MTD_BLOCK_RO
 
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 60b222799871..e6f2e0888246 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -359,7 +359,9 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 	} else {
 		snprintf(gd->disk_name, sizeof(gd->disk_name),
 			 "%s%d", tr->name, new->devnum);
-		gd->flags |= GENHD_FL_NO_PART;
+
+		if (!IS_ENABLED(CONFIG_MTD_BLOCK_PARTITIONS) || mtd_type_is_nand(new->mtd))
+			gd->flags |= GENHD_FL_NO_PART;
 	}
 
 	set_capacity(gd, ((u64)new->size * tr->blksize) >> 9);
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index 75eaecc8639f..e617635ff6e6 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -430,7 +430,10 @@ int ubiblock_create(struct ubi_volume_info *vi)
 		ret = -ENODEV;
 		goto out_cleanup_disk;
 	}
-	gd->flags |= GENHD_FL_NO_PART;
+
+	if (!IS_ENABLED(CONFIG_MTD_BLOCK_PARTITIONS))
+		gd->flags |= GENHD_FL_NO_PART;
+
 	gd->private_data = dev;
 	sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
 	set_capacity(gd, disk_capacity);
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v5 4/4] mtd: add option to enable scanning for partitions
@ 2022-11-15 21:47   ` Daniel Golle
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-15 21:47 UTC (permalink / raw)
  To: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Daniel Golle,
	Martin K. Petersen, Chaitanya Kulkarni, Michal Orzel,
	linux-block, linux-kernel, linux-mtd

Add Kconfig boolean CONFIG_MTD_BLOCK_PARTITIONS and enable block
partition parsers on non-NAND mtdblock as well as ubiblock devices
in case it is selected.
Never scan partitions on NAND-backed mtdblock devices, ubiblock
should be used instead.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/Kconfig       | 11 +++++++++++
 drivers/mtd/mtd_blkdevs.c |  4 +++-
 drivers/mtd/ubi/block.c   |  5 ++++-
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 796a2eccbef0..12874dec1569 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -69,6 +69,17 @@ config MTD_BLOCK_RO
 	  You do not need this option for use with the DiskOnChip devices. For
 	  those, enable NFTL support (CONFIG_NFTL) instead.
 
+config MTD_BLOCK_PARTITIONS
+	bool "Scan for partitions on MTD block devices"
+	depends on MTD_BLOCK || MTD_BLOCK_RO
+	default y if FIT_PARTITION
+	help
+	  Scan MTD block devices for partitions (ie. MBR, GPT, uImage.FIT, ...).
+	  (NAND devices are omitted, ubiblock should be used instead when)
+
+	  Unless your MTD partitions contain sub-partitions mapped using a
+	  partition table, say no.
+
 comment "Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK."
 	depends on MTD_BLOCK || MTD_BLOCK_RO
 
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 60b222799871..e6f2e0888246 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -359,7 +359,9 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 	} else {
 		snprintf(gd->disk_name, sizeof(gd->disk_name),
 			 "%s%d", tr->name, new->devnum);
-		gd->flags |= GENHD_FL_NO_PART;
+
+		if (!IS_ENABLED(CONFIG_MTD_BLOCK_PARTITIONS) || mtd_type_is_nand(new->mtd))
+			gd->flags |= GENHD_FL_NO_PART;
 	}
 
 	set_capacity(gd, ((u64)new->size * tr->blksize) >> 9);
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index 75eaecc8639f..e617635ff6e6 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -430,7 +430,10 @@ int ubiblock_create(struct ubi_volume_info *vi)
 		ret = -ENODEV;
 		goto out_cleanup_disk;
 	}
-	gd->flags |= GENHD_FL_NO_PART;
+
+	if (!IS_ENABLED(CONFIG_MTD_BLOCK_PARTITIONS))
+		gd->flags |= GENHD_FL_NO_PART;
+
 	gd->private_data = dev;
 	sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
 	set_capacity(gd, disk_capacity);
-- 
2.38.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
  2022-11-15 21:47   ` Daniel Golle
@ 2022-11-16  6:01     ` Christoph Hellwig
  -1 siblings, 0 replies; 22+ messages in thread
From: Christoph Hellwig @ 2022-11-16  6:01 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

On Tue, Nov 15, 2022 at 09:47:06PM +0000, Daniel Golle wrote:
> Add new GUID allowing to parse uImage.FIT stored in a GPT partition
> and map filesystem sub-image as sub-partitions.

NAK, we should not go out from the partition code to parse random
weird image formats.  If you want to support uImage.FIT just write
a tinty stackable block driver or dm table for it.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
@ 2022-11-16  6:01     ` Christoph Hellwig
  0 siblings, 0 replies; 22+ messages in thread
From: Christoph Hellwig @ 2022-11-16  6:01 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

On Tue, Nov 15, 2022 at 09:47:06PM +0000, Daniel Golle wrote:
> Add new GUID allowing to parse uImage.FIT stored in a GPT partition
> and map filesystem sub-image as sub-partitions.

NAK, we should not go out from the partition code to parse random
weird image formats.  If you want to support uImage.FIT just write
a tinty stackable block driver or dm table for it.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
  2022-11-16  6:01     ` Christoph Hellwig
@ 2022-11-17  0:19       ` Daniel Golle
  -1 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-17  0:19 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

Hi Christoph,

On Tue, Nov 15, 2022 at 10:01:05PM -0800, Christoph Hellwig wrote:
> On Tue, Nov 15, 2022 at 09:47:06PM +0000, Daniel Golle wrote:
> > Add new GUID allowing to parse uImage.FIT stored in a GPT partition
> > and map filesystem sub-image as sub-partitions.
> 
> NAK, we should not go out from the partition code to parse random
> weird image formats.

While weirdness is certainly subjective, uImage.FIT is not just a
random image format but used by a great majority of headless embedded
Linux devices out there. It's the default image format of many of the
SDKs distributed by chip vendors such as Allwinner, Marvell, MediaTek,
NXP, Qualcomm/Atheros, ...

Having better support for it in Linux hence doesn't seem too far-fetched
to me, especially given that we got partition parsers for all sorts of
historic (Acorn, Amiga, Atari, ...) or actually exotic (Karma?) formats.
Even Microsoft Windows' Logical Disk Manager is supported natively by
the kernel...

> If you want to support uImage.FIT just write a tiny stackable block
> driver or dm table for it.

As this is used on rather tiny embedded devices my hope was to keep
things simple and not having to enable device mapper on systems which
have anyway only very small amounts of storage and won't ever need
most of the device mapper features.

Using a tiny block driver instead is an option, I've implemented this
approach in the past couple of hours and it works just as fine.

In this case I would introduce a new kernel cmdline option allowing
to specify which block device (ie. a partition on eMMC, or mtdblock
or ubiblock device) to launch the uImage.FIT parser on.

Allowing this new driver to add block partitions by exporting a new
helper functions for that in block/partition/core.c would greatly
simplify things, as then the existing partitioning code could still
be used (instead of basically having to re-implement loopdev and
introduce a whole new type of block devices).

I will post an RFC series illustrating this approach.

Please let me know if this sounds acceptable, so I won't put effort
into implementing something which will then be rejected again after 5
iterations on the mailing list for reasons which could have been
expressed from the beginning. An RFC for this series was posted on
2022-04-25 [1], I wouldn't have worked months to fix all requests of
other maintainers and tested it on a variety of different hardware
knowing that the whole approach will be NACK'ed...

And, of course, thank you anyway for reviewing!


Cheers


Daniel

[1]: https://patchwork.kernel.org/project/linux-block/list/?series=635369&state=*

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
@ 2022-11-17  0:19       ` Daniel Golle
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-17  0:19 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

Hi Christoph,

On Tue, Nov 15, 2022 at 10:01:05PM -0800, Christoph Hellwig wrote:
> On Tue, Nov 15, 2022 at 09:47:06PM +0000, Daniel Golle wrote:
> > Add new GUID allowing to parse uImage.FIT stored in a GPT partition
> > and map filesystem sub-image as sub-partitions.
> 
> NAK, we should not go out from the partition code to parse random
> weird image formats.

While weirdness is certainly subjective, uImage.FIT is not just a
random image format but used by a great majority of headless embedded
Linux devices out there. It's the default image format of many of the
SDKs distributed by chip vendors such as Allwinner, Marvell, MediaTek,
NXP, Qualcomm/Atheros, ...

Having better support for it in Linux hence doesn't seem too far-fetched
to me, especially given that we got partition parsers for all sorts of
historic (Acorn, Amiga, Atari, ...) or actually exotic (Karma?) formats.
Even Microsoft Windows' Logical Disk Manager is supported natively by
the kernel...

> If you want to support uImage.FIT just write a tiny stackable block
> driver or dm table for it.

As this is used on rather tiny embedded devices my hope was to keep
things simple and not having to enable device mapper on systems which
have anyway only very small amounts of storage and won't ever need
most of the device mapper features.

Using a tiny block driver instead is an option, I've implemented this
approach in the past couple of hours and it works just as fine.

In this case I would introduce a new kernel cmdline option allowing
to specify which block device (ie. a partition on eMMC, or mtdblock
or ubiblock device) to launch the uImage.FIT parser on.

Allowing this new driver to add block partitions by exporting a new
helper functions for that in block/partition/core.c would greatly
simplify things, as then the existing partitioning code could still
be used (instead of basically having to re-implement loopdev and
introduce a whole new type of block devices).

I will post an RFC series illustrating this approach.

Please let me know if this sounds acceptable, so I won't put effort
into implementing something which will then be rejected again after 5
iterations on the mailing list for reasons which could have been
expressed from the beginning. An RFC for this series was posted on
2022-04-25 [1], I wouldn't have worked months to fix all requests of
other maintainers and tested it on a variety of different hardware
knowing that the whole approach will be NACK'ed...

And, of course, thank you anyway for reviewing!


Cheers


Daniel

[1]: https://patchwork.kernel.org/project/linux-block/list/?series=635369&state=*

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
  2022-11-17  0:19       ` Daniel Golle
@ 2022-11-17  6:00         ` Christoph Hellwig
  -1 siblings, 0 replies; 22+ messages in thread
From: Christoph Hellwig @ 2022-11-17  6:00 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Christoph Hellwig, Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

On Thu, Nov 17, 2022 at 12:19:10AM +0000, Daniel Golle wrote:
> While weirdness is certainly subjective, uImage.FIT is not just a
> random image format but used by a great majority of headless embedded
> Linux devices out there. It's the default image format of many of the
> SDKs distributed by chip vendors such as Allwinner, Marvell, MediaTek,
> NXP, Qualcomm/Atheros, ...

"Look see, my weird format is used by all these companies building
crappy SOCs, it is not weird.."

> Please let me know if this sounds acceptable, so I won't put effort
> into implementing something which will then be rejected again after 5
> iterations on the mailing list for reasons which could have been
> expressed from the beginning. An RFC for this series was posted on
> 2022-04-25 [1], I wouldn't have worked months to fix all requests of
> other maintainers and tested it on a variety of different hardware
> knowing that the whole approach will be NACK'ed...

If people ignore something that is obviously broken they might just hope
for it to go away, becaue often it does.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
@ 2022-11-17  6:00         ` Christoph Hellwig
  0 siblings, 0 replies; 22+ messages in thread
From: Christoph Hellwig @ 2022-11-17  6:00 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Christoph Hellwig, Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

On Thu, Nov 17, 2022 at 12:19:10AM +0000, Daniel Golle wrote:
> While weirdness is certainly subjective, uImage.FIT is not just a
> random image format but used by a great majority of headless embedded
> Linux devices out there. It's the default image format of many of the
> SDKs distributed by chip vendors such as Allwinner, Marvell, MediaTek,
> NXP, Qualcomm/Atheros, ...

"Look see, my weird format is used by all these companies building
crappy SOCs, it is not weird.."

> Please let me know if this sounds acceptable, so I won't put effort
> into implementing something which will then be rejected again after 5
> iterations on the mailing list for reasons which could have been
> expressed from the beginning. An RFC for this series was posted on
> 2022-04-25 [1], I wouldn't have worked months to fix all requests of
> other maintainers and tested it on a variety of different hardware
> knowing that the whole approach will be NACK'ed...

If people ignore something that is obviously broken they might just hope
for it to go away, becaue often it does.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
  2022-11-17  6:00         ` Christoph Hellwig
@ 2022-11-17  6:50           ` Richard Weinberger
  -1 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2022-11-17  6:50 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Daniel Golle, Jens Axboe, Miquel Raynal, Vignesh Raghavendra,
	Matthew Wilcox, Martin K. Petersen, Chaitanya Kulkarni,
	Michal Orzel, linux-block, linux-kernel, linux-mtd

----- Ursprüngliche Mail -----
> Von: "Christoph Hellwig" <hch@infradead.org>
> On Thu, Nov 17, 2022 at 12:19:10AM +0000, Daniel Golle wrote:
>> While weirdness is certainly subjective, uImage.FIT is not just a
>> random image format but used by a great majority of headless embedded
>> Linux devices out there. It's the default image format of many of the
>> SDKs distributed by chip vendors such as Allwinner, Marvell, MediaTek,
>> NXP, Qualcomm/Atheros, ...
> 
> "Look see, my weird format is used by all these companies building
> crappy SOCs, it is not weird.."

Well, FIT is not something strange invented by SoC companies, it comes from u-boot
and is more or less a de-facto standard.
While I agree that using the block layer for partition parsing is questionable
I think supporting these images in Linux is a worthwhile goal.

Thanks,
//richard

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
@ 2022-11-17  6:50           ` Richard Weinberger
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2022-11-17  6:50 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Daniel Golle, Jens Axboe, Miquel Raynal, Vignesh Raghavendra,
	Matthew Wilcox, Martin K. Petersen, Chaitanya Kulkarni,
	Michal Orzel, linux-block, linux-kernel, linux-mtd

----- Ursprüngliche Mail -----
> Von: "Christoph Hellwig" <hch@infradead.org>
> On Thu, Nov 17, 2022 at 12:19:10AM +0000, Daniel Golle wrote:
>> While weirdness is certainly subjective, uImage.FIT is not just a
>> random image format but used by a great majority of headless embedded
>> Linux devices out there. It's the default image format of many of the
>> SDKs distributed by chip vendors such as Allwinner, Marvell, MediaTek,
>> NXP, Qualcomm/Atheros, ...
> 
> "Look see, my weird format is used by all these companies building
> crappy SOCs, it is not weird.."

Well, FIT is not something strange invented by SoC companies, it comes from u-boot
and is more or less a de-facto standard.
While I agree that using the block layer for partition parsing is questionable
I think supporting these images in Linux is a worthwhile goal.

Thanks,
//richard

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
  2022-11-17  6:50           ` Richard Weinberger
@ 2022-11-17  6:59             ` Christoph Hellwig
  -1 siblings, 0 replies; 22+ messages in thread
From: Christoph Hellwig @ 2022-11-17  6:59 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: Christoph Hellwig, Daniel Golle, Jens Axboe, Miquel Raynal,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

On Thu, Nov 17, 2022 at 07:50:08AM +0100, Richard Weinberger wrote:
> I think supporting these images in Linux is a worthwhile goal.

I never argued against that.  But it is not a fit for partitions.
So write a proper stacked block driver or dm driver for it if you
care enough.  The format is a complete mess and should be isolated
to not affect the rest of the kernel.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
@ 2022-11-17  6:59             ` Christoph Hellwig
  0 siblings, 0 replies; 22+ messages in thread
From: Christoph Hellwig @ 2022-11-17  6:59 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: Christoph Hellwig, Daniel Golle, Jens Axboe, Miquel Raynal,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

On Thu, Nov 17, 2022 at 07:50:08AM +0100, Richard Weinberger wrote:
> I think supporting these images in Linux is a worthwhile goal.

I never argued against that.  But it is not a fit for partitions.
So write a proper stacked block driver or dm driver for it if you
care enough.  The format is a complete mess and should be isolated
to not affect the rest of the kernel.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
  2022-11-17  6:00         ` Christoph Hellwig
@ 2022-11-17 13:59           ` Daniel Golle
  -1 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-17 13:59 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

On Wed, Nov 16, 2022 at 10:00:25PM -0800, Christoph Hellwig wrote:
> On Thu, Nov 17, 2022 at 12:19:10AM +0000, Daniel Golle wrote:
> > While weirdness is certainly subjective, uImage.FIT is not just a
> > random image format but used by a great majority of headless embedded
> > Linux devices out there. It's the default image format of many of the
> > SDKs distributed by chip vendors such as Allwinner, Marvell, MediaTek,
> > NXP, Qualcomm/Atheros, ...
> 
> "Look see, my weird format is used by all these companies building
> crappy SOCs, it is not weird.."

I didn't invent this, and it's just as broken and yet perdominant as,
let's say, MS LDM on x86.

> 
> > Please let me know if this sounds acceptable, so I won't put effort
> > into implementing something which will then be rejected again after 5
> > iterations on the mailing list for reasons which could have been
> > expressed from the beginning. An RFC for this series was posted on
> > 2022-04-25 [1], I wouldn't have worked months to fix all requests of
> > other maintainers and tested it on a variety of different hardware
> > knowing that the whole approach will be NACK'ed...
> 
> If people ignore something that is obviously broken they might just hope
> for it to go away, becaue often it does.

While I'm sure that strategy works seen from your perspective, it does
waste resources on the other end. In this case it might not have been
obvious to everybody, I did receive feedback from other maintainers,
as I said. It's not that everybody ignored this contribution. Hence,
looking at it from my end, the picture is a bit different. Anyway.
I would have appreciated an earlier explicite NACK, that's all I
wanted to say.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions
@ 2022-11-17 13:59           ` Daniel Golle
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Golle @ 2022-11-17 13:59 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jens Axboe, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Matthew Wilcox, Martin K. Petersen,
	Chaitanya Kulkarni, Michal Orzel, linux-block, linux-kernel,
	linux-mtd

On Wed, Nov 16, 2022 at 10:00:25PM -0800, Christoph Hellwig wrote:
> On Thu, Nov 17, 2022 at 12:19:10AM +0000, Daniel Golle wrote:
> > While weirdness is certainly subjective, uImage.FIT is not just a
> > random image format but used by a great majority of headless embedded
> > Linux devices out there. It's the default image format of many of the
> > SDKs distributed by chip vendors such as Allwinner, Marvell, MediaTek,
> > NXP, Qualcomm/Atheros, ...
> 
> "Look see, my weird format is used by all these companies building
> crappy SOCs, it is not weird.."

I didn't invent this, and it's just as broken and yet perdominant as,
let's say, MS LDM on x86.

> 
> > Please let me know if this sounds acceptable, so I won't put effort
> > into implementing something which will then be rejected again after 5
> > iterations on the mailing list for reasons which could have been
> > expressed from the beginning. An RFC for this series was posted on
> > 2022-04-25 [1], I wouldn't have worked months to fix all requests of
> > other maintainers and tested it on a variety of different hardware
> > knowing that the whole approach will be NACK'ed...
> 
> If people ignore something that is obviously broken they might just hope
> for it to go away, becaue often it does.

While I'm sure that strategy works seen from your perspective, it does
waste resources on the other end. In this case it might not have been
obvious to everybody, I did receive feedback from other maintainers,
as I said. It's not that everybody ignored this contribution. Hence,
looking at it from my end, the picture is a bit different. Anyway.
I would have appreciated an earlier explicite NACK, that's all I
wanted to say.


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2022-11-17 14:01 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-15 21:45 [PATCH v5 0/4] partition parser for U-Boot's uImage.FIT Daniel Golle
2022-11-15 21:45 ` Daniel Golle
2022-11-15 21:45 ` [PATCH v5 1/4] block: add new flag to add partitions read-only Daniel Golle
2022-11-15 21:45   ` Daniel Golle
2022-11-15 21:46 ` [PATCH v5 2/4] block: add partition parser for U-Boot uImage.FIT Daniel Golle
2022-11-15 21:46   ` Daniel Golle
2022-11-15 21:47 ` [PATCH v5 3/4] partitions/efi: add support for uImage.FIT sub-partitions Daniel Golle
2022-11-15 21:47   ` Daniel Golle
2022-11-16  6:01   ` Christoph Hellwig
2022-11-16  6:01     ` Christoph Hellwig
2022-11-17  0:19     ` Daniel Golle
2022-11-17  0:19       ` Daniel Golle
2022-11-17  6:00       ` Christoph Hellwig
2022-11-17  6:00         ` Christoph Hellwig
2022-11-17  6:50         ` Richard Weinberger
2022-11-17  6:50           ` Richard Weinberger
2022-11-17  6:59           ` Christoph Hellwig
2022-11-17  6:59             ` Christoph Hellwig
2022-11-17 13:59         ` Daniel Golle
2022-11-17 13:59           ` Daniel Golle
2022-11-15 21:47 ` [PATCH v5 4/4] mtd: add option to enable scanning for partitions Daniel Golle
2022-11-15 21:47   ` Daniel Golle

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.