From: Daniel Golle Date: Mon, 4 Dec 2023 23:25:12 +0000 (+0000) Subject: kernel: move uImage.FIT partition parser to mediatek target X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fstaging%2Fdangole.git;a=commitdiff_plain;h=c882abbce7d433a8d69a2449b0ffabcf409cf1e0 kernel: move uImage.FIT partition parser to mediatek target The partition parser approach has been rejected upstream, it will be replaced by a small block driver which is the solution suggestion by upstream maintainers. As the partition parser has only been used by the mediatek target, as a first step, move it there. Signed-off-by: Daniel Golle --- diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index bc2509ff478..5f82f0937d4 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -2071,7 +2071,6 @@ CONFIG_FILE_LOCKING=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_FIRMWARE_MEMMAP is not set -# CONFIG_FIT_PARTITION is not set # CONFIG_FIXED_PHY is not set CONFIG_FLATMEM=y CONFIG_FLATMEM_MANUAL=y diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 index 80214d1efd2..279cf0bf14f 100644 --- a/target/linux/generic/config-6.1 +++ b/target/linux/generic/config-6.1 @@ -2166,7 +2166,6 @@ CONFIG_FILE_LOCKING=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_FIRMWARE_MEMMAP is not set -# CONFIG_FIT_PARTITION is not set # CONFIG_FIXED_PHY is not set CONFIG_FLATMEM=y CONFIG_FLATMEM_MANUAL=y diff --git a/target/linux/generic/files/block/partitions/fit.c b/target/linux/generic/files/block/partitions/fit.c deleted file mode 100644 index 91b25e0581e..00000000000 --- a/target/linux/generic/files/block/partitions/fit.c +++ /dev/null @@ -1,303 +0,0 @@ -// 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 - */ - -#define pr_fmt(fmt) fmt - -#include -#include -#include -#include -#include -#include - -#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 FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE - -#define MIN_FREE_SECT 16 -#define REMAIN_VOLNAME "rootfs_data" - -int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector, u64 sectors, int *slot, int add_remain) -{ - struct block_device *bdev = state->disk->part0; - struct address_space *mapping = bdev->bd_inode->i_mapping; - struct page *page; - void *fit, *init_fit; - struct partition_meta_info *info; - char tmp[sizeof(info->volname)]; - u64 dsize, dsectors, imgmaxsect = 0; - u32 size, image_pos, image_len; - const u32 *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, *bootconf_c; - int image_name_len, image_type_len, image_description_len, config_default_len, - config_description_len, config_loadables_len, bootconf_len; - sector_t start_sect, nr_sects; - size_t label_min; - struct device_node *np = NULL; - char *bootconf = NULL, *bootconf_term; - const char *loadable; - const char *select_rootfs = NULL; - bool found; - int loadables_rem_len, loadable_len; - - if (fit_start_sector % (1<<(PAGE_SHIFT - SECTOR_SHIFT))) - return -ERANGE; - - page = read_mapping_page(mapping, fit_start_sector >> (PAGE_SHIFT - SECTOR_SHIFT), NULL); - if (IS_ERR(page)) - return -EFAULT; - - if (PageError(page)) - return -EFAULT; - - init_fit = page_address(page); - - if (!init_fit) { - put_page(page); - return -EFAULT; - } - - if (fdt_check_header(init_fit)) { - put_page(page); - return 0; - } - - dsectors = get_capacity(bdev->bd_disk); - if (sectors) - dsectors = (dsectors>sectors)?sectors:dsectors; - - dsize = dsectors << SECTOR_SHIFT; - size = fdt_totalsize(init_fit); - - /* silently skip non-external-data legacy FIT images */ - if (size > PAGE_SIZE) { - put_page(page); - return 0; - } - - if (size >= dsize) { - state->access_beyond_eod = 1; - put_page(page); - return -EFBIG; - } - - fit = kmemdup(init_fit, size, GFP_KERNEL); - put_page(page); - if (!fit) - return -ENOMEM; - - np = of_find_node_by_path("/chosen"); - if (np) { - bootconf_c = of_get_property(np, "u-boot,bootconf", &bootconf_len); - if (bootconf_c && bootconf_len) - bootconf = kmemdup_nul(bootconf_c, bootconf_len, GFP_KERNEL); - } - - if (bootconf) { - bootconf_term = strchr(bootconf, '#'); - if (bootconf_term) - *bootconf_term = '\0'; - } - - config = fdt_path_offset(fit, FIT_CONFS_PATH); - if (config < 0) { - printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_CONFS_PATH, images); - ret = -ENOENT; - goto ret_out; - } - - config_default = fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len); - - if (!config_default && !bootconf) { - printk(KERN_ERR "FIT: Cannot find default configuration\n"); - ret = -ENOENT; - goto ret_out; - } - - node = fdt_subnode_offset(fit, config, bootconf?:config_default); - if (node < 0) { - printk(KERN_ERR "FIT: Cannot find %s node: %d\n", bootconf?:config_default, node); - ret = -ENOENT; - goto ret_out; - } - - config_description = fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len); - config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, &config_loadables_len); - - printk(KERN_DEBUG "FIT: %s configuration: \"%s\"%s%s%s\n", - bootconf?"Selected":"Default", bootconf?:config_default, - config_description?" (":"", config_description?:"", config_description?")":""); - - if (!config_loadables || !config_loadables_len) { - printk(KERN_ERR "FIT: No loadables configured in \"%s\"\n", bootconf?:config_default); - ret = -ENOENT; - goto ret_out; - } - - images = fdt_path_offset(fit, FIT_IMAGES_PATH); - if (images < 0) { - printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images); - ret = -EINVAL; - goto ret_out; - } - - 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); - - printk(KERN_DEBUG "FIT: %16s sub-image 0x%08x..0x%08x \"%s\" %s%s%s\n", - image_type, image_pos, image_pos + image_len - 1, image_name, - image_description?"(":"", image_description?:"", image_description?") ":""); - - if (strcmp(image_type, FIT_FILESYSTEM_PROP)) - continue; - - /* check if sub-image is part of configured loadables */ - found = false; - loadable = config_loadables; - loadables_rem_len = config_loadables_len; - while (loadables_rem_len > 1) { - 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)-1)) { - printk(KERN_ERR "FIT: image %s start not aligned to page boundaries, skipping\n", image_name); - continue; - } - - if (image_len & ((1 << PAGE_SHIFT)-1)) { - printk(KERN_ERR "FIT: sub-image %s end not aligned to page boundaries, skipping\n", 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(int, sizeof(info->volname) - 1, image_name_len); - strncpy(info->volname, image_name, label_min); - info->volname[label_min] = '\0'; - - snprintf(tmp, sizeof(tmp), "(%s)", info->volname); - strlcat(state->pp_buf, tmp, PAGE_SIZE); - - /* Mark first loadable listed to be mounted as rootfs */ - if (!strcmp(image_name, config_loadables)) { - select_rootfs = image_name; - state->parts[*slot].flags |= ADDPART_FLAG_ROOTDEV; - } - } - - if (select_rootfs) - printk(KERN_DEBUG "FIT: selecting configured loadable \"%s\" to be root filesystem\n", select_rootfs); - - 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); - } -ret_out: - kfree(bootconf); - kfree(fit); - return ret; -} - -int fit_partition(struct parsed_partitions *state) { - int slot = 0; - return parse_fit_partitions(state, 0, 0, &slot, 0); -} diff --git a/target/linux/generic/hack-5.15/410-block-fit-partition-parser.patch b/target/linux/generic/hack-5.15/410-block-fit-partition-parser.patch deleted file mode 100644 index 13a16b6fa08..00000000000 --- a/target/linux/generic/hack-5.15/410-block-fit-partition-parser.patch +++ /dev/null @@ -1,214 +0,0 @@ -From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:37:33 +0200 -Subject: [PATCH] kernel: add block fit partition parser - ---- - block/blk.h | 2 ++ - block/partitions/Kconfig | 7 +++++++ - block/partitions/Makefile | 1 + - block/partitions/check.h | 3 +++ - block/partitions/core.c | 17 +++++++++++++++++ - block/partitions/efi.c | 8 ++++++++ - block/partitions/efi.h | 3 +++ - block/partitions/msdos.c | 10 ++++++++++ - drivers/mtd/mtd_blkdevs.c | 2 ++ - drivers/mtd/ubi/block.c | 3 +++ - include/linux/msdos_partition.h | 1 + - 11 files changed, 57 insertions(+) - ---- a/block/blk.h -+++ b/block/blk.h -@@ -354,6 +354,8 @@ void blk_free_ext_minor(unsigned int min - #define ADDPART_FLAG_NONE 0 - #define ADDPART_FLAG_RAID 1 - #define ADDPART_FLAG_WHOLEDISK 2 -+#define ADDPART_FLAG_READONLY 4 -+#define ADDPART_FLAG_ROOTDEV 8 - int bdev_add_partition(struct gendisk *disk, int partno, sector_t start, - sector_t length); - int bdev_del_partition(struct gendisk *disk, int partno); ---- a/block/partitions/Kconfig -+++ b/block/partitions/Kconfig -@@ -101,6 +101,13 @@ 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 -+ 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. -+ - config IBM_PARTITION - bool "IBM disk label and partition support" - depends on PARTITION_ADVANCED && S390 ---- 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 ---- a/block/partitions/check.h -+++ b/block/partitions/check.h -@@ -58,6 +58,7 @@ int amiga_partition(struct parsed_partit - 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); -@@ -68,3 +69,5 @@ int sgi_partition(struct parsed_partitio - 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 start_sector, u64 nr_sectors, int *slot, int add_remain); ---- a/block/partitions/core.c -+++ b/block/partitions/core.c -@@ -12,6 +12,10 @@ - #include - #include - #include -+#ifdef CONFIG_FIT_PARTITION -+#include -+#endif -+ - #include "check.h" - - static int (*check_part[])(struct parsed_partitions *) = { -@@ -48,6 +52,9 @@ static int (*check_part[])(struct parsed - #ifdef CONFIG_EFI_PARTITION - efi_partition, /* this must come before msdos */ - #endif -+#ifdef CONFIG_FIT_PARTITION -+ fit_partition, -+#endif - #ifdef CONFIG_SGI_PARTITION - sgi_partition, - #endif -@@ -408,6 +415,11 @@ static struct block_device *add_partitio - goto out_del; - } - -+#ifdef CONFIG_FIT_PARTITION -+ if (flags & ADDPART_FLAG_READONLY) -+ bdev->bd_read_only = true; -+#endif -+ - /* everything is up and running, commence */ - err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL); - if (err) -@@ -595,6 +607,11 @@ static bool blk_add_partition(struct gen - (state->parts[p].flags & ADDPART_FLAG_RAID)) - md_autodetect_dev(part->bd_dev); - -+#ifdef CONFIG_FIT_PARTITION -+ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0) -+ ROOT_DEV = part->bd_dev; -+#endif -+ - return true; - } - ---- a/block/partitions/efi.c -+++ b/block/partitions/efi.c -@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio - gpt_entry *ptes = NULL; - u32 i; - unsigned ssz = queue_logical_block_size(state->disk->queue) / 512; -+#ifdef CONFIG_FIT_PARTITION -+ u32 extra_slot = 64; -+#endif - - if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { - kfree(gpt); -@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio - 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; -+#ifdef CONFIG_FIT_PARTITION -+ /* If this is a U-Boot FIT volume it may have subpartitions */ -+ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID)) -+ (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1); -+#endif - } - kfree(ptes); - kfree(gpt); ---- a/block/partitions/efi.h -+++ b/block/partitions/efi.h -@@ -52,6 +52,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; ---- a/block/partitions/msdos.c -+++ b/block/partitions/msdos.c -@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa - #endif /* CONFIG_MINIX_SUBPARTITION */ - } - -+static void parse_fit_mbr(struct parsed_partitions *state, -+ sector_t offset, sector_t size, int origin) -+{ -+#ifdef CONFIG_FIT_PARTITION -+ u32 extra_slot = 64; -+ (void) parse_fit_partitions(state, offset, size, &extra_slot, 1); -+#endif /* CONFIG_FIT_PARTITION */ -+} -+ - static struct { - unsigned char id; - void (*parse)(struct parsed_partitions *, sector_t, sector_t, int); -@@ -575,6 +584,7 @@ static struct { - {UNIXWARE_PARTITION, parse_unixware}, - {SOLARIS_X86_PARTITION, parse_solaris_x86}, - {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86}, -+ {FIT_PARTITION, parse_fit_mbr}, - {0, NULL}, - }; - ---- a/drivers/mtd/mtd_blkdevs.c -+++ b/drivers/mtd/mtd_blkdevs.c -@@ -345,6 +345,8 @@ int add_mtd_blktrans_dev(struct mtd_blkt - gd->first_minor = (new->devnum) << tr->part_bits; - gd->minors = 1 << tr->part_bits; - gd->fops = &mtd_block_ops; -+ if (IS_ENABLED(CONFIG_FIT_PARTITION) && !mtd_type_is_nand(new->mtd)) -+ gd->flags |= GENHD_FL_EXT_DEVT; - - if (tr->part_bits) - if (new->devnum < 26) ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -428,6 +428,9 @@ int ubiblock_create(struct ubi_volume_in - goto out_cleanup_disk; - } - gd->private_data = dev; -+#ifdef CONFIG_FIT_PARTITION -+ gd->flags |= GENHD_FL_EXT_DEVT; -+#endif - sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); - set_capacity(gd, disk_capacity); - dev->gd = gd; ---- a/include/linux/msdos_partition.h -+++ b/include/linux/msdos_partition.h -@@ -31,6 +31,7 @@ enum msdos_sys_ind { - LINUX_LVM_PARTITION = 0x8e, - LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ - -+ FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */ - SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */ - NEW_SOLARIS_X86_PARTITION = 0xbf, - diff --git a/target/linux/generic/hack-6.1/410-block-fit-partition-parser.patch b/target/linux/generic/hack-6.1/410-block-fit-partition-parser.patch deleted file mode 100644 index 1258f64722a..00000000000 --- a/target/linux/generic/hack-6.1/410-block-fit-partition-parser.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:37:33 +0200 -Subject: [PATCH] kernel: add block fit partition parser - ---- - block/blk.h | 2 ++ - block/partitions/Kconfig | 7 +++++++ - block/partitions/Makefile | 1 + - block/partitions/check.h | 3 +++ - block/partitions/core.c | 17 +++++++++++++++++ - block/partitions/efi.c | 8 ++++++++ - block/partitions/efi.h | 3 +++ - block/partitions/msdos.c | 10 ++++++++++ - drivers/mtd/mtd_blkdevs.c | 2 ++ - drivers/mtd/ubi/block.c | 3 +++ - include/linux/msdos_partition.h | 1 + - 11 files changed, 57 insertions(+) - ---- a/block/blk.h -+++ b/block/blk.h -@@ -414,6 +414,8 @@ void blk_free_ext_minor(unsigned int min - #define ADDPART_FLAG_NONE 0 - #define ADDPART_FLAG_RAID 1 - #define ADDPART_FLAG_WHOLEDISK 2 -+#define ADDPART_FLAG_READONLY 4 -+#define ADDPART_FLAG_ROOTDEV 8 - int bdev_add_partition(struct gendisk *disk, int partno, sector_t start, - sector_t length); - int bdev_del_partition(struct gendisk *disk, int partno); ---- a/block/partitions/Kconfig -+++ b/block/partitions/Kconfig -@@ -103,6 +103,13 @@ 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 -+ 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. -+ - config IBM_PARTITION - bool "IBM disk label and partition support" - depends on PARTITION_ADVANCED && S390 ---- 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 ---- a/block/partitions/check.h -+++ b/block/partitions/check.h -@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partit - 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,5 @@ int sgi_partition(struct parsed_partitio - 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 start_sector, u64 nr_sectors, int *slot, int add_remain); ---- a/block/partitions/core.c -+++ b/block/partitions/core.c -@@ -10,6 +10,10 @@ - #include - #include - #include -+#ifdef CONFIG_FIT_PARTITION -+#include -+#endif -+ - #include "check.h" - - static int (*check_part[])(struct parsed_partitions *) = { -@@ -46,6 +50,9 @@ static int (*check_part[])(struct parsed - #ifdef CONFIG_EFI_PARTITION - efi_partition, /* this must come before msdos */ - #endif -+#ifdef CONFIG_FIT_PARTITION -+ fit_partition, -+#endif - #ifdef CONFIG_SGI_PARTITION - sgi_partition, - #endif -@@ -398,6 +405,11 @@ static struct block_device *add_partitio - goto out_del; - } - -+#ifdef CONFIG_FIT_PARTITION -+ if (flags & ADDPART_FLAG_READONLY) -+ bdev->bd_read_only = true; -+#endif -+ - /* everything is up and running, commence */ - err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL); - if (err) -@@ -585,6 +597,11 @@ static bool blk_add_partition(struct gen - (state->parts[p].flags & ADDPART_FLAG_RAID)) - md_autodetect_dev(part->bd_dev); - -+#ifdef CONFIG_FIT_PARTITION -+ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0) -+ ROOT_DEV = part->bd_dev; -+#endif -+ - return true; - } - ---- a/block/partitions/efi.c -+++ b/block/partitions/efi.c -@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio - gpt_entry *ptes = NULL; - u32 i; - unsigned ssz = queue_logical_block_size(state->disk->queue) / 512; -+#ifdef CONFIG_FIT_PARTITION -+ u32 extra_slot = 64; -+#endif - - if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { - kfree(gpt); -@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio - 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; -+#ifdef CONFIG_FIT_PARTITION -+ /* If this is a U-Boot FIT volume it may have subpartitions */ -+ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID)) -+ (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1); -+#endif - } - kfree(ptes); - kfree(gpt); ---- 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; ---- a/block/partitions/msdos.c -+++ b/block/partitions/msdos.c -@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa - #endif /* CONFIG_MINIX_SUBPARTITION */ - } - -+static void parse_fit_mbr(struct parsed_partitions *state, -+ sector_t offset, sector_t size, int origin) -+{ -+#ifdef CONFIG_FIT_PARTITION -+ u32 extra_slot = 64; -+ (void) parse_fit_partitions(state, offset, size, &extra_slot, 1); -+#endif /* CONFIG_FIT_PARTITION */ -+} -+ - static struct { - unsigned char id; - void (*parse)(struct parsed_partitions *, sector_t, sector_t, int); -@@ -575,6 +584,7 @@ static struct { - {UNIXWARE_PARTITION, parse_unixware}, - {SOLARIS_X86_PARTITION, parse_solaris_x86}, - {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86}, -+ {FIT_PARTITION, parse_fit_mbr}, - {0, NULL}, - }; - ---- a/drivers/mtd/mtd_blkdevs.c -+++ b/drivers/mtd/mtd_blkdevs.c -@@ -359,7 +359,9 @@ int add_mtd_blktrans_dev(struct mtd_blkt - } 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_FIT_PARTITION) || mtd_type_is_nand(new->mtd)) -+ gd->flags |= GENHD_FL_NO_PART; - } - - set_capacity(gd, ((u64)new->size * tr->blksize) >> 9); ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -431,7 +431,9 @@ int ubiblock_create(struct ubi_volume_in - ret = -ENODEV; - goto out_cleanup_disk; - } -- gd->flags |= GENHD_FL_NO_PART; -+ if (!IS_ENABLED(CONFIG_FIT_PARTITION)) -+ 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); ---- a/include/linux/msdos_partition.h -+++ b/include/linux/msdos_partition.h -@@ -31,6 +31,7 @@ enum msdos_sys_ind { - LINUX_LVM_PARTITION = 0x8e, - LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ - -+ FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */ - SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */ - NEW_SOLARIS_X86_PARTITION = 0xbf, - diff --git a/target/linux/mediatek/files/block/partitions/fit.c b/target/linux/mediatek/files/block/partitions/fit.c new file mode 100644 index 00000000000..91b25e0581e --- /dev/null +++ b/target/linux/mediatek/files/block/partitions/fit.c @@ -0,0 +1,303 @@ +// 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 + */ + +#define pr_fmt(fmt) fmt + +#include +#include +#include +#include +#include +#include + +#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 FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE + +#define MIN_FREE_SECT 16 +#define REMAIN_VOLNAME "rootfs_data" + +int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector, u64 sectors, int *slot, int add_remain) +{ + struct block_device *bdev = state->disk->part0; + struct address_space *mapping = bdev->bd_inode->i_mapping; + struct page *page; + void *fit, *init_fit; + struct partition_meta_info *info; + char tmp[sizeof(info->volname)]; + u64 dsize, dsectors, imgmaxsect = 0; + u32 size, image_pos, image_len; + const u32 *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, *bootconf_c; + int image_name_len, image_type_len, image_description_len, config_default_len, + config_description_len, config_loadables_len, bootconf_len; + sector_t start_sect, nr_sects; + size_t label_min; + struct device_node *np = NULL; + char *bootconf = NULL, *bootconf_term; + const char *loadable; + const char *select_rootfs = NULL; + bool found; + int loadables_rem_len, loadable_len; + + if (fit_start_sector % (1<<(PAGE_SHIFT - SECTOR_SHIFT))) + return -ERANGE; + + page = read_mapping_page(mapping, fit_start_sector >> (PAGE_SHIFT - SECTOR_SHIFT), NULL); + if (IS_ERR(page)) + return -EFAULT; + + if (PageError(page)) + return -EFAULT; + + init_fit = page_address(page); + + if (!init_fit) { + put_page(page); + return -EFAULT; + } + + if (fdt_check_header(init_fit)) { + put_page(page); + return 0; + } + + dsectors = get_capacity(bdev->bd_disk); + if (sectors) + dsectors = (dsectors>sectors)?sectors:dsectors; + + dsize = dsectors << SECTOR_SHIFT; + size = fdt_totalsize(init_fit); + + /* silently skip non-external-data legacy FIT images */ + if (size > PAGE_SIZE) { + put_page(page); + return 0; + } + + if (size >= dsize) { + state->access_beyond_eod = 1; + put_page(page); + return -EFBIG; + } + + fit = kmemdup(init_fit, size, GFP_KERNEL); + put_page(page); + if (!fit) + return -ENOMEM; + + np = of_find_node_by_path("/chosen"); + if (np) { + bootconf_c = of_get_property(np, "u-boot,bootconf", &bootconf_len); + if (bootconf_c && bootconf_len) + bootconf = kmemdup_nul(bootconf_c, bootconf_len, GFP_KERNEL); + } + + if (bootconf) { + bootconf_term = strchr(bootconf, '#'); + if (bootconf_term) + *bootconf_term = '\0'; + } + + config = fdt_path_offset(fit, FIT_CONFS_PATH); + if (config < 0) { + printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_CONFS_PATH, images); + ret = -ENOENT; + goto ret_out; + } + + config_default = fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len); + + if (!config_default && !bootconf) { + printk(KERN_ERR "FIT: Cannot find default configuration\n"); + ret = -ENOENT; + goto ret_out; + } + + node = fdt_subnode_offset(fit, config, bootconf?:config_default); + if (node < 0) { + printk(KERN_ERR "FIT: Cannot find %s node: %d\n", bootconf?:config_default, node); + ret = -ENOENT; + goto ret_out; + } + + config_description = fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len); + config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, &config_loadables_len); + + printk(KERN_DEBUG "FIT: %s configuration: \"%s\"%s%s%s\n", + bootconf?"Selected":"Default", bootconf?:config_default, + config_description?" (":"", config_description?:"", config_description?")":""); + + if (!config_loadables || !config_loadables_len) { + printk(KERN_ERR "FIT: No loadables configured in \"%s\"\n", bootconf?:config_default); + ret = -ENOENT; + goto ret_out; + } + + images = fdt_path_offset(fit, FIT_IMAGES_PATH); + if (images < 0) { + printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images); + ret = -EINVAL; + goto ret_out; + } + + 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); + + printk(KERN_DEBUG "FIT: %16s sub-image 0x%08x..0x%08x \"%s\" %s%s%s\n", + image_type, image_pos, image_pos + image_len - 1, image_name, + image_description?"(":"", image_description?:"", image_description?") ":""); + + if (strcmp(image_type, FIT_FILESYSTEM_PROP)) + continue; + + /* check if sub-image is part of configured loadables */ + found = false; + loadable = config_loadables; + loadables_rem_len = config_loadables_len; + while (loadables_rem_len > 1) { + 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)-1)) { + printk(KERN_ERR "FIT: image %s start not aligned to page boundaries, skipping\n", image_name); + continue; + } + + if (image_len & ((1 << PAGE_SHIFT)-1)) { + printk(KERN_ERR "FIT: sub-image %s end not aligned to page boundaries, skipping\n", 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(int, sizeof(info->volname) - 1, image_name_len); + strncpy(info->volname, image_name, label_min); + info->volname[label_min] = '\0'; + + snprintf(tmp, sizeof(tmp), "(%s)", info->volname); + strlcat(state->pp_buf, tmp, PAGE_SIZE); + + /* Mark first loadable listed to be mounted as rootfs */ + if (!strcmp(image_name, config_loadables)) { + select_rootfs = image_name; + state->parts[*slot].flags |= ADDPART_FLAG_ROOTDEV; + } + } + + if (select_rootfs) + printk(KERN_DEBUG "FIT: selecting configured loadable \"%s\" to be root filesystem\n", select_rootfs); + + 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); + } +ret_out: + kfree(bootconf); + kfree(fit); + return ret; +} + +int fit_partition(struct parsed_partitions *state) { + int slot = 0; + return parse_fit_partitions(state, 0, 0, &slot, 0); +} diff --git a/target/linux/mediatek/mt7629/config-5.15 b/target/linux/mediatek/mt7629/config-5.15 index 8cddb04d667..c42ada6d230 100644 --- a/target/linux/mediatek/mt7629/config-5.15 +++ b/target/linux/mediatek/mt7629/config-5.15 @@ -95,6 +95,7 @@ CONFIG_DTC=y CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y CONFIG_EINT_MTK=y +# CONFIG_FIT_PARTITION is not set CONFIG_FIXED_PHY=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_FWNODE_MDIO=y diff --git a/target/linux/mediatek/mt7629/config-6.1 b/target/linux/mediatek/mt7629/config-6.1 index ad79b5ba9ec..d8dc50a67ac 100644 --- a/target/linux/mediatek/mt7629/config-6.1 +++ b/target/linux/mediatek/mt7629/config-6.1 @@ -107,6 +107,7 @@ CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y CONFIG_EINT_MTK=y CONFIG_EXCLUSIVE_SYSTEM_RAM=y +# CONFIG_FIT_PARTITION is not set CONFIG_FIXED_PHY=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_FRAME_WARN=1024 diff --git a/target/linux/mediatek/patches-5.15/041-block-fit-partition-parser.patch b/target/linux/mediatek/patches-5.15/041-block-fit-partition-parser.patch new file mode 100644 index 00000000000..13a16b6fa08 --- /dev/null +++ b/target/linux/mediatek/patches-5.15/041-block-fit-partition-parser.patch @@ -0,0 +1,214 @@ +From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:37:33 +0200 +Subject: [PATCH] kernel: add block fit partition parser + +--- + block/blk.h | 2 ++ + block/partitions/Kconfig | 7 +++++++ + block/partitions/Makefile | 1 + + block/partitions/check.h | 3 +++ + block/partitions/core.c | 17 +++++++++++++++++ + block/partitions/efi.c | 8 ++++++++ + block/partitions/efi.h | 3 +++ + block/partitions/msdos.c | 10 ++++++++++ + drivers/mtd/mtd_blkdevs.c | 2 ++ + drivers/mtd/ubi/block.c | 3 +++ + include/linux/msdos_partition.h | 1 + + 11 files changed, 57 insertions(+) + +--- a/block/blk.h ++++ b/block/blk.h +@@ -354,6 +354,8 @@ void blk_free_ext_minor(unsigned int min + #define ADDPART_FLAG_NONE 0 + #define ADDPART_FLAG_RAID 1 + #define ADDPART_FLAG_WHOLEDISK 2 ++#define ADDPART_FLAG_READONLY 4 ++#define ADDPART_FLAG_ROOTDEV 8 + int bdev_add_partition(struct gendisk *disk, int partno, sector_t start, + sector_t length); + int bdev_del_partition(struct gendisk *disk, int partno); +--- a/block/partitions/Kconfig ++++ b/block/partitions/Kconfig +@@ -101,6 +101,13 @@ 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 ++ 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. ++ + config IBM_PARTITION + bool "IBM disk label and partition support" + depends on PARTITION_ADVANCED && S390 +--- 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 +--- a/block/partitions/check.h ++++ b/block/partitions/check.h +@@ -58,6 +58,7 @@ int amiga_partition(struct parsed_partit + 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); +@@ -68,3 +69,5 @@ int sgi_partition(struct parsed_partitio + 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 start_sector, u64 nr_sectors, int *slot, int add_remain); +--- a/block/partitions/core.c ++++ b/block/partitions/core.c +@@ -12,6 +12,10 @@ + #include + #include + #include ++#ifdef CONFIG_FIT_PARTITION ++#include ++#endif ++ + #include "check.h" + + static int (*check_part[])(struct parsed_partitions *) = { +@@ -48,6 +52,9 @@ static int (*check_part[])(struct parsed + #ifdef CONFIG_EFI_PARTITION + efi_partition, /* this must come before msdos */ + #endif ++#ifdef CONFIG_FIT_PARTITION ++ fit_partition, ++#endif + #ifdef CONFIG_SGI_PARTITION + sgi_partition, + #endif +@@ -408,6 +415,11 @@ static struct block_device *add_partitio + goto out_del; + } + ++#ifdef CONFIG_FIT_PARTITION ++ if (flags & ADDPART_FLAG_READONLY) ++ bdev->bd_read_only = true; ++#endif ++ + /* everything is up and running, commence */ + err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL); + if (err) +@@ -595,6 +607,11 @@ static bool blk_add_partition(struct gen + (state->parts[p].flags & ADDPART_FLAG_RAID)) + md_autodetect_dev(part->bd_dev); + ++#ifdef CONFIG_FIT_PARTITION ++ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0) ++ ROOT_DEV = part->bd_dev; ++#endif ++ + return true; + } + +--- a/block/partitions/efi.c ++++ b/block/partitions/efi.c +@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio + gpt_entry *ptes = NULL; + u32 i; + unsigned ssz = queue_logical_block_size(state->disk->queue) / 512; ++#ifdef CONFIG_FIT_PARTITION ++ u32 extra_slot = 64; ++#endif + + if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { + kfree(gpt); +@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio + 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; ++#ifdef CONFIG_FIT_PARTITION ++ /* If this is a U-Boot FIT volume it may have subpartitions */ ++ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID)) ++ (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1); ++#endif + } + kfree(ptes); + kfree(gpt); +--- a/block/partitions/efi.h ++++ b/block/partitions/efi.h +@@ -52,6 +52,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; +--- a/block/partitions/msdos.c ++++ b/block/partitions/msdos.c +@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa + #endif /* CONFIG_MINIX_SUBPARTITION */ + } + ++static void parse_fit_mbr(struct parsed_partitions *state, ++ sector_t offset, sector_t size, int origin) ++{ ++#ifdef CONFIG_FIT_PARTITION ++ u32 extra_slot = 64; ++ (void) parse_fit_partitions(state, offset, size, &extra_slot, 1); ++#endif /* CONFIG_FIT_PARTITION */ ++} ++ + static struct { + unsigned char id; + void (*parse)(struct parsed_partitions *, sector_t, sector_t, int); +@@ -575,6 +584,7 @@ static struct { + {UNIXWARE_PARTITION, parse_unixware}, + {SOLARIS_X86_PARTITION, parse_solaris_x86}, + {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86}, ++ {FIT_PARTITION, parse_fit_mbr}, + {0, NULL}, + }; + +--- a/drivers/mtd/mtd_blkdevs.c ++++ b/drivers/mtd/mtd_blkdevs.c +@@ -345,6 +345,8 @@ int add_mtd_blktrans_dev(struct mtd_blkt + gd->first_minor = (new->devnum) << tr->part_bits; + gd->minors = 1 << tr->part_bits; + gd->fops = &mtd_block_ops; ++ if (IS_ENABLED(CONFIG_FIT_PARTITION) && !mtd_type_is_nand(new->mtd)) ++ gd->flags |= GENHD_FL_EXT_DEVT; + + if (tr->part_bits) + if (new->devnum < 26) +--- a/drivers/mtd/ubi/block.c ++++ b/drivers/mtd/ubi/block.c +@@ -428,6 +428,9 @@ int ubiblock_create(struct ubi_volume_in + goto out_cleanup_disk; + } + gd->private_data = dev; ++#ifdef CONFIG_FIT_PARTITION ++ gd->flags |= GENHD_FL_EXT_DEVT; ++#endif + sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); + set_capacity(gd, disk_capacity); + dev->gd = gd; +--- a/include/linux/msdos_partition.h ++++ b/include/linux/msdos_partition.h +@@ -31,6 +31,7 @@ enum msdos_sys_ind { + LINUX_LVM_PARTITION = 0x8e, + LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ + ++ FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */ + SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */ + NEW_SOLARIS_X86_PARTITION = 0xbf, + diff --git a/target/linux/mediatek/patches-6.1/041-block-fit-partition-parser.patch b/target/linux/mediatek/patches-6.1/041-block-fit-partition-parser.patch new file mode 100644 index 00000000000..1258f64722a --- /dev/null +++ b/target/linux/mediatek/patches-6.1/041-block-fit-partition-parser.patch @@ -0,0 +1,217 @@ +From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:37:33 +0200 +Subject: [PATCH] kernel: add block fit partition parser + +--- + block/blk.h | 2 ++ + block/partitions/Kconfig | 7 +++++++ + block/partitions/Makefile | 1 + + block/partitions/check.h | 3 +++ + block/partitions/core.c | 17 +++++++++++++++++ + block/partitions/efi.c | 8 ++++++++ + block/partitions/efi.h | 3 +++ + block/partitions/msdos.c | 10 ++++++++++ + drivers/mtd/mtd_blkdevs.c | 2 ++ + drivers/mtd/ubi/block.c | 3 +++ + include/linux/msdos_partition.h | 1 + + 11 files changed, 57 insertions(+) + +--- a/block/blk.h ++++ b/block/blk.h +@@ -414,6 +414,8 @@ void blk_free_ext_minor(unsigned int min + #define ADDPART_FLAG_NONE 0 + #define ADDPART_FLAG_RAID 1 + #define ADDPART_FLAG_WHOLEDISK 2 ++#define ADDPART_FLAG_READONLY 4 ++#define ADDPART_FLAG_ROOTDEV 8 + int bdev_add_partition(struct gendisk *disk, int partno, sector_t start, + sector_t length); + int bdev_del_partition(struct gendisk *disk, int partno); +--- a/block/partitions/Kconfig ++++ b/block/partitions/Kconfig +@@ -103,6 +103,13 @@ 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 ++ 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. ++ + config IBM_PARTITION + bool "IBM disk label and partition support" + depends on PARTITION_ADVANCED && S390 +--- 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 +--- a/block/partitions/check.h ++++ b/block/partitions/check.h +@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partit + 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,5 @@ int sgi_partition(struct parsed_partitio + 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 start_sector, u64 nr_sectors, int *slot, int add_remain); +--- a/block/partitions/core.c ++++ b/block/partitions/core.c +@@ -10,6 +10,10 @@ + #include + #include + #include ++#ifdef CONFIG_FIT_PARTITION ++#include ++#endif ++ + #include "check.h" + + static int (*check_part[])(struct parsed_partitions *) = { +@@ -46,6 +50,9 @@ static int (*check_part[])(struct parsed + #ifdef CONFIG_EFI_PARTITION + efi_partition, /* this must come before msdos */ + #endif ++#ifdef CONFIG_FIT_PARTITION ++ fit_partition, ++#endif + #ifdef CONFIG_SGI_PARTITION + sgi_partition, + #endif +@@ -398,6 +405,11 @@ static struct block_device *add_partitio + goto out_del; + } + ++#ifdef CONFIG_FIT_PARTITION ++ if (flags & ADDPART_FLAG_READONLY) ++ bdev->bd_read_only = true; ++#endif ++ + /* everything is up and running, commence */ + err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL); + if (err) +@@ -585,6 +597,11 @@ static bool blk_add_partition(struct gen + (state->parts[p].flags & ADDPART_FLAG_RAID)) + md_autodetect_dev(part->bd_dev); + ++#ifdef CONFIG_FIT_PARTITION ++ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0) ++ ROOT_DEV = part->bd_dev; ++#endif ++ + return true; + } + +--- a/block/partitions/efi.c ++++ b/block/partitions/efi.c +@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio + gpt_entry *ptes = NULL; + u32 i; + unsigned ssz = queue_logical_block_size(state->disk->queue) / 512; ++#ifdef CONFIG_FIT_PARTITION ++ u32 extra_slot = 64; ++#endif + + if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { + kfree(gpt); +@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio + 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; ++#ifdef CONFIG_FIT_PARTITION ++ /* If this is a U-Boot FIT volume it may have subpartitions */ ++ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID)) ++ (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1); ++#endif + } + kfree(ptes); + kfree(gpt); +--- 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; +--- a/block/partitions/msdos.c ++++ b/block/partitions/msdos.c +@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa + #endif /* CONFIG_MINIX_SUBPARTITION */ + } + ++static void parse_fit_mbr(struct parsed_partitions *state, ++ sector_t offset, sector_t size, int origin) ++{ ++#ifdef CONFIG_FIT_PARTITION ++ u32 extra_slot = 64; ++ (void) parse_fit_partitions(state, offset, size, &extra_slot, 1); ++#endif /* CONFIG_FIT_PARTITION */ ++} ++ + static struct { + unsigned char id; + void (*parse)(struct parsed_partitions *, sector_t, sector_t, int); +@@ -575,6 +584,7 @@ static struct { + {UNIXWARE_PARTITION, parse_unixware}, + {SOLARIS_X86_PARTITION, parse_solaris_x86}, + {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86}, ++ {FIT_PARTITION, parse_fit_mbr}, + {0, NULL}, + }; + +--- a/drivers/mtd/mtd_blkdevs.c ++++ b/drivers/mtd/mtd_blkdevs.c +@@ -359,7 +359,9 @@ int add_mtd_blktrans_dev(struct mtd_blkt + } 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_FIT_PARTITION) || mtd_type_is_nand(new->mtd)) ++ gd->flags |= GENHD_FL_NO_PART; + } + + set_capacity(gd, ((u64)new->size * tr->blksize) >> 9); +--- a/drivers/mtd/ubi/block.c ++++ b/drivers/mtd/ubi/block.c +@@ -431,7 +431,9 @@ int ubiblock_create(struct ubi_volume_in + ret = -ENODEV; + goto out_cleanup_disk; + } +- gd->flags |= GENHD_FL_NO_PART; ++ if (!IS_ENABLED(CONFIG_FIT_PARTITION)) ++ 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); +--- a/include/linux/msdos_partition.h ++++ b/include/linux/msdos_partition.h +@@ -31,6 +31,7 @@ enum msdos_sys_ind { + LINUX_LVM_PARTITION = 0x8e, + LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ + ++ FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */ + SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */ + NEW_SOLARIS_X86_PARTITION = 0xbf, +