diff --git a/include/image-commands.mk b/include/image-commands.mk index 51e745958e..3377680a07 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -200,11 +200,13 @@ define Build/fit $(TOPDIR)/scripts/mkits.sh \ -D $(DEVICE_NAME) -o $@.its -k $@ \ $(if $(word 2,$(1)),-d $(word 2,$(1))) -C $(word 1,$(1)) \ + $(if $(findstring with-rootfs,$(word 3,$(1))),-r $(IMAGE_ROOTFS)) \ -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ $(if $(DEVICE_FDT_NUM),-n $(DEVICE_FDT_NUM)) \ -c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \ -A $(LINUX_KARCH) -v $(LINUX_VERSION) - PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new + PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(findstring external,$(word 3,$(1))),\ + -E -B 0x1000 $(if $(findstring static,$(word 3,$(1))),-p 0x1000)) -f $@.its $@.new @mv $@.new $@ endef diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh index e6f58df4f5..7cf95c0139 100644 --- a/package/base-files/files/lib/upgrade/nand.sh +++ b/package/base-files/files/lib/upgrade/nand.sh @@ -3,13 +3,13 @@ . /lib/functions.sh -# 'kernel' partition on NAND contains the kernel +# 'kernel' partition or UBI volume on NAND contains the kernel CI_KERNPART="${CI_KERNPART:-kernel}" # 'ubi' partition on NAND contains UBI CI_UBIPART="${CI_UBIPART:-ubi}" -# 'rootfs' partition on NAND contains the rootfs +# 'rootfs' UBI volume on NAND contains the rootfs CI_ROOTPART="${CI_ROOTPART:-rootfs}" ubi_mknod() { @@ -117,9 +117,11 @@ nand_restore_config() { nand_upgrade_prepare_ubi() { local rootfs_length="$1" local rootfs_type="$2" - local has_kernel="${3:-0}" + local kernel_length="$3" local has_env="${4:-0}" + [ -n "$rootfs_length" -o -n "$kernel_length" ] || return 1 + local mtdnum="$( find_mtd_index "$CI_UBIPART" )" if [ ! "$mtdnum" ]; then echo "cannot find ubi mtd partition $CI_UBIPART" @@ -148,23 +150,24 @@ nand_upgrade_prepare_ubi() { local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )" local data_ubivol="$( nand_find_volume $ubidev rootfs_data )" - # remove ubiblock device of rootfs - local root_ubiblk="ubiblock${root_ubivol:3}" - if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then - echo "removing $root_ubiblk" - if ! ubiblock -r /dev/$root_ubivol; then - echo "cannot remove $root_ubiblk" - return 1; + local ubiblk ubiblkvol + for ubiblk in /dev/ubiblock*_? ; do + [ -e "$ubiblk" ] || continue + echo "removing ubiblock${ubiblk:13}" + ubiblkvol=ubi${ubiblk:13} + if ! ubiblock -r /dev/$ubiblkvol; then + echo "cannot remove $ubiblk" + return 1 fi - fi + done # kill volumes [ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true - [ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true + [ "$root_ubivol" -a "$root_ubivol" != "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true [ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true # update kernel - if [ "$has_kernel" = "1" ]; then + if [ -n "$kernel_length" ]; then if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then echo "cannot create kernel volume" return 1; @@ -172,15 +175,17 @@ nand_upgrade_prepare_ubi() { fi # update rootfs - local root_size_param - if [ "$rootfs_type" = "ubifs" ]; then - root_size_param="-m" - else - root_size_param="-s $rootfs_length" - fi - if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $root_size_param; then - echo "cannot create rootfs volume" - return 1; + if [ -n "$rootfs_length" ]; then + local root_size_param + if [ "$rootfs_type" = "ubifs" ]; then + root_size_param="-m" + else + root_size_param="-s $rootfs_length" + fi + if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $rootfs_size_param; then + echo "cannot create rootfs volume" + return 1; + fi fi # create rootfs_data for non-ubifs rootfs @@ -232,7 +237,7 @@ nand_upgrade_ubinized() { nand_upgrade_ubifs() { local rootfs_length=$( (cat $1 | wc -c) 2> /dev/null) - nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0" + nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "" "" local ubidev="$( nand_find_ubi "$CI_UBIPART" )" local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)" @@ -241,39 +246,59 @@ nand_upgrade_ubifs() { nand_do_upgrade_success } +nand_upgrade_fit() { + local fit_file="$1" + local fit_length="$(wc -c < "$fit_file")" + + nand_upgrade_prepare_ubi "" "" "$fit_length" "1" + + local fit_ubidev="$(nand_find_ubi "$CI_UBIPART")" + local fit_ubivol="$(nand_find_volume $fit_ubidev "$CI_KERNPART")" + ubiupdatevol /dev/$fit_ubivol -s $fit_length $fit_file + + nand_do_upgrade_success +} + nand_upgrade_tar() { local tar_file="$1" local kernel_mtd="$(find_mtd_index $CI_KERNPART)" - local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$') + local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$') board_dir=${board_dir%/} - local kernel_length=$( (tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null) - local rootfs_length=$( (tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null) + kernel_length=$( (tar xf "$tar_file" ${board_dir}/kernel -O | wc -c) 2> /dev/null) + local has_rootfs=0 + local rootfs_length + local rootfs_type - local rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)" + tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1 + [ "$has_rootfs" = "1" ] && { + rootfs_length=$( (tar xf "$tar_file" ${board_dir}/root -O | wc -c) 2> /dev/null) + rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)" + } local has_kernel=1 local has_env=0 [ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && { - tar xf $tar_file ${board_dir}/kernel -O | mtd write - $CI_KERNPART + tar xf "$tar_file" ${board_dir}/kernel -O | mtd write - $CI_KERNPART } - [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0 + [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel= - nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env" + nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "${has_kernel:+$kernel_length}" "$has_env" local ubidev="$( nand_find_ubi "$CI_UBIPART" )" [ "$has_kernel" = "1" ] && { - local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" - tar xf $tar_file ${board_dir}/kernel -O | \ + local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )" + tar xf "$tar_file" ${board_dir}/kernel -O | \ ubiupdatevol /dev/$kern_ubivol -s $kernel_length - } - local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)" - tar xf $tar_file ${board_dir}/root -O | \ - ubiupdatevol /dev/$root_ubivol -s $rootfs_length - - + [ "$has_rootfs" = "1" ] && { + local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )" + tar xf "$tar_file" ${board_dir}/root -O | \ + ubiupdatevol /dev/$root_ubivol -s $rootfs_length - + } nand_do_upgrade_success } @@ -284,6 +309,7 @@ nand_do_upgrade() { [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs" case "$file_type" in + "fit") nand_upgrade_fit $1;; "ubi") nand_upgrade_ubinized $1;; "ubifs") nand_upgrade_ubifs $1;; *) nand_upgrade_tar $1;; @@ -309,7 +335,7 @@ nand_do_platform_check() { local control_length=$( (tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null) local file_type="$(identify $2)" - [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && { + [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" -a "$file_type" != "fit" ] && { echo "Invalid sysupgrade file." return 1 } diff --git a/scripts/mkits.sh b/scripts/mkits.sh index bb629d6fca..59ff3a2d15 100755 --- a/scripts/mkits.sh +++ b/scripts/mkits.sh @@ -23,18 +23,24 @@ usage() { printf "\n\t-c ==> set config name 'config'" printf "\n\t-a ==> set load address to 'addr' (hex)" printf "\n\t-e ==> set entry point to 'entry' (hex)" + printf "\n\t-f ==> set device tree compatible string" printf "\n\t-v ==> set kernel version to 'version'" printf "\n\t-k ==> include kernel image 'kernel'" printf "\n\t-D ==> human friendly Device Tree Blob 'name'" printf "\n\t-n ==> fdt unit-address 'address'" printf "\n\t-d ==> include Device Tree Blob 'dtb'" + printf "\n\t-r ==> include RootFS blob 'rootfs'" + printf "\n\t-H ==> specify hash algo instead of SHA1" printf "\n\t-o ==> create output file 'its_file'\n" exit 1 } FDTNUM=1 +ROOTFSNUM=1 +HASH=sha1 +LOADABLES= -while getopts ":A:a:c:C:D:d:e:k:n:o:v:" OPTION +while getopts ":A:a:c:C:D:d:e:f:k:n:o:v:r:S" OPTION do case $OPTION in A ) ARCH=$OPTARG;; @@ -44,9 +50,12 @@ do D ) DEVICE=$OPTARG;; d ) DTB=$OPTARG;; e ) ENTRY_ADDR=$OPTARG;; + f ) COMPATIBLE=$OPTARG;; k ) KERNEL=$OPTARG;; n ) FDTNUM=$OPTARG;; o ) OUTPUT=$OPTARG;; + r ) ROOTFS=$OPTARG;; + S ) HASH=$OPTARG;; v ) VERSION=$OPTARG;; * ) echo "Invalid option passed to '$0' (options:$*)" usage;; @@ -62,11 +71,16 @@ fi ARCH_UPPER=$(echo "$ARCH" | tr '[:lower:]' '[:upper:]') +if [ -n "${COMPATIBLE}" ]; then + COMPATIBLE_PROP="compatible = \"${COMPATIBLE}\";" +fi + # Conditionally create fdt information if [ -n "${DTB}" ]; then FDT_NODE=" fdt@$FDTNUM { description = \"${ARCH_UPPER} OpenWrt ${DEVICE} device tree blob\"; + ${COMPATIBLE_PROP} data = /incbin/(\"${DTB}\"); type = \"flat_dt\"; arch = \"${ARCH}\"; @@ -75,13 +89,34 @@ if [ -n "${DTB}" ]; then algo = \"crc32\"; }; hash@2 { - algo = \"sha1\"; + algo = \"${HASH}\"; }; }; " FDT_PROP="fdt = \"fdt@$FDTNUM\";" fi +if [ -n "${ROOTFS}" ]; then + dd if="${ROOTFS}" of="${ROOTFS}.pagesync" bs=4096 conv=sync + ROOTFS_NODE=" + rootfs@$ROOTFSNUM { + description = \"${ARCH_UPPER} OpenWrt ${DEVICE} rootfs\"; + ${COMPATIBLE_PROP} + data = /incbin/(\"${ROOTFS}.pagesync\"); + type = \"filesystem\"; + arch = \"${ARCH}\"; + compression = \"none\"; + hash@1 { + algo = \"crc32\"; + }; + hash@2 { + algo = \"${HASH}\"; + }; + }; +" + LOADABLES="${LOADABLES:+$LOADABLES, }\"rootfs@${ROOTFSNUM}\"" +fi + # Create a default, fully populated DTS file DATA="/dts-v1/; @@ -103,18 +138,21 @@ DATA="/dts-v1/; algo = \"crc32\"; }; hash@2 { - algo = \"sha1\"; + algo = \"$HASH\"; }; }; ${FDT_NODE} +${ROOTFS_NODE} }; configurations { default = \"${CONFIG}\"; ${CONFIG} { - description = \"OpenWrt\"; + description = \"OpenWrt ${DEVICE}\"; kernel = \"kernel@1\"; ${FDT_PROP} + ${LOADABLES:+loadables = ${LOADABLES};} + ${COMPATIBLE_PROP} }; }; };" diff --git a/target/linux/generic/config-5.10 b/target/linux/generic/config-5.10 index d8c5017083..d88c0de17f 100644 --- a/target/linux/generic/config-5.10 +++ b/target/linux/generic/config-5.10 @@ -1871,6 +1871,7 @@ CONFIG_FIB_RULES=y # CONFIG_FIELDBUS_DEV is not set CONFIG_FILE_LOCKING=y # CONFIG_FIND_BIT_BENCHMARK is not set +# CONFIG_FIT_PARTITION is not set # CONFIG_FIREWIRE is not set # CONFIG_FIREWIRE_NOSY is not set # CONFIG_FIREWIRE_SERIAL is not set diff --git a/target/linux/generic/config-5.4 b/target/linux/generic/config-5.4 index 4ace100b01..9755c9658a 100644 --- a/target/linux/generic/config-5.4 +++ b/target/linux/generic/config-5.4 @@ -1665,6 +1665,7 @@ 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 new file mode 100644 index 0000000000..8ccbcf2fc2 --- /dev/null +++ b/target/linux/generic/files/block/partitions/fit.c @@ -0,0 +1,233 @@ +// 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 "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 + +int fit_partition(struct parsed_partitions *state) +{ + struct address_space *mapping = state->bdev->bd_inode->i_mapping; + struct page *page = read_mapping_page(mapping, 0, NULL); + void *fit, *init_fit; + struct partition_meta_info *info; + char tmp[sizeof(info->volname)]; + u64 dsize, dsectors; + u32 size, image_pos, image_len; + const u32 *image_offset_be, *image_len_be, *image_pos_be; + int ret = 1, node, images, config, slot; + const char *image_name, *image_type, *image_description, *config_default, + *config_description, *config_loadables; + int 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; + + if (!page) + return -ENOMEM; + + 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(state->bdev->bd_disk); + dsize = dsectors << SECTOR_SHIFT; + printk(KERN_DEBUG "FIT: volume size: %llu sectors (%llu bytes)\n", dsectors, dsize); + + size = fdt_totalsize(init_fit); + printk(KERN_DEBUG "FIT: FDT structure size: %u bytes\n", size); + if (size > PAGE_SIZE) { + printk(KERN_ERR "FIT: FDT structure beyond page boundaries, use 'mkimage -E ...'!\n"); + put_page(page); + return -ENOTSUPP; + } + + if (size >= dsize) { + put_page(page); + state->access_beyond_eod = (size >= dsize); + return 0; + } + + fit = kmemdup(init_fit, size, GFP_KERNEL); + put_page(page); + if (!fit) + return -ENOMEM; + + 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) { + printk(KERN_ERR "FIT: Cannot find default configuration\n"); + ret = -ENOENT; + goto ret_out; + } + + node = fdt_subnode_offset(fit, config, config_default); + if (node < 0) { + printk(KERN_ERR "FIT: Cannot find %s node: %d\n", 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: Default configuration: %s%s%s%s\n", config_default, + config_description?" (":"", config_description?:"", config_description?")":""); + + 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; + } + + slot = 1; + 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, image_name, + image_description?"(":"", image_description?:"", image_description?") ":""); + + if (strcmp(image_type, FIT_FILESYSTEM_PROP)) + 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; + + if (start_sect + nr_sects > dsectors) { + state->access_beyond_eod = 1; + continue; + } + + put_partition(state, slot, start_sect, nr_sects); + state->parts[slot].flags = 0; + 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); + + state->parts[slot].has_info = true; + + if (config_loadables && !strcmp(image_name, config_loadables)) { + printk(KERN_DEBUG "FIT: selecting configured loadable %s to be root filesystem\n", image_name); + state->parts[slot].flags |= ADDPART_FLAG_ROOTDEV; + } + + ++slot; + } + +ret_out: + kfree(fit); + return ret; +} diff --git a/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch b/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch new file mode 100644 index 0000000000..9eaf8637d0 --- /dev/null +++ b/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch @@ -0,0 +1,96 @@ +--- a/block/blk.h ++++ b/block/blk.h +@@ -357,6 +357,7 @@ char *disk_name(struct gendisk *hd, int + #define ADDPART_FLAG_NONE 0 + #define ADDPART_FLAG_RAID 1 + #define ADDPART_FLAG_WHOLEDISK 2 ++#define ADDPART_FLAG_ROOTDEV 4 + void delete_partition(struct hd_struct *part); + int bdev_add_partition(struct block_device *bdev, int partno, + sector_t start, sector_t length); +--- 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); +--- a/block/partitions/core.c ++++ b/block/partitions/core.c +@@ -10,6 +10,8 @@ + #include + #include + #include ++#include ++ + #include "check.h" + + static int (*check_part[])(struct parsed_partitions *) = { +@@ -46,6 +48,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 +@@ -694,6 +699,9 @@ static bool blk_add_partition(struct gen + (state->parts[p].flags & ADDPART_FLAG_RAID)) + md_autodetect_dev(part_to_dev(part)->devt); + ++ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0) ++ ROOT_DEV = part_to_dev(part)->devt; ++ + return true; + } + +--- a/drivers/mtd/ubi/block.c ++++ b/drivers/mtd/ubi/block.c +@@ -396,7 +396,7 @@ int ubiblock_create(struct ubi_volume_in + dev->leb_size = vi->usable_leb_size; + + /* Initialize the gendisk of this ubiblock device */ +- gd = alloc_disk(1); ++ gd = alloc_disk(0); + if (!gd) { + pr_err("UBI: block: alloc_disk failed\n"); + ret = -ENODEV; +@@ -413,6 +413,7 @@ int ubiblock_create(struct ubi_volume_in + goto out_put_disk; + } + gd->private_data = dev; ++ gd->flags |= GENHD_FL_EXT_DEVT; + sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); + set_capacity(gd, disk_capacity); + dev->gd = gd; diff --git a/target/linux/generic/hack-5.4/400-block-fit-partition-parser.patch b/target/linux/generic/hack-5.4/400-block-fit-partition-parser.patch new file mode 100644 index 0000000000..13cf5e8ca0 --- /dev/null +++ b/target/linux/generic/hack-5.4/400-block-fit-partition-parser.patch @@ -0,0 +1,99 @@ +--- 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 +@@ -9,6 +9,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/drivers/mtd/ubi/block.c ++++ b/drivers/mtd/ubi/block.c +@@ -396,7 +396,7 @@ int ubiblock_create(struct ubi_volume_in + dev->leb_size = vi->usable_leb_size; + + /* Initialize the gendisk of this ubiblock device */ +- gd = alloc_disk(1); ++ gd = alloc_disk(0); + if (!gd) { + pr_err("UBI: block: alloc_disk failed\n"); + ret = -ENODEV; +@@ -413,6 +413,7 @@ int ubiblock_create(struct ubi_volume_in + goto out_put_disk; + } + gd->private_data = dev; ++ gd->flags |= GENHD_FL_EXT_DEVT; + sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); + set_capacity(gd, disk_capacity); + dev->gd = gd; +--- a/block/partition-generic.c ++++ b/block/partition-generic.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #include "partitions/check.h" + +@@ -634,6 +635,8 @@ rescan: + if (state->parts[p].flags & ADDPART_FLAG_RAID) + md_autodetect_dev(part_to_dev(part)->devt); + #endif ++ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0) ++ ROOT_DEV = part_to_dev(part)->devt; + } + free_partitions(state); + return 0; +--- a/block/partitions/check.c ++++ b/block/partitions/check.c +@@ -33,6 +33,7 @@ + #include "ibm.h" + #include "ultrix.h" + #include "efi.h" ++#include "fit.h" + #include "karma.h" + #include "sysv68.h" + #include "cmdline.h" +@@ -73,6 +74,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 +--- a/include/linux/genhd.h ++++ b/include/linux/genhd.h +@@ -614,6 +614,7 @@ struct unixware_disklabel { + #define ADDPART_FLAG_NONE 0 + #define ADDPART_FLAG_RAID 1 + #define ADDPART_FLAG_WHOLEDISK 2 ++#define ADDPART_FLAG_ROOTDEV 4 + + extern int blk_alloc_devt(struct hd_struct *part, dev_t *devt); + extern void blk_free_devt(dev_t devt); +--- /dev/null ++++ b/block/partitions/fit.h +@@ -0,0 +1,2 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++int fit_partition(struct parsed_partitions *); diff --git a/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch index e5ee2c8656..a2b48fd4fc 100644 --- a/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +++ b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch @@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c -@@ -652,6 +652,44 @@ static void __init ubiblock_create_from_ +@@ -652,6 +652,47 @@ static void __init ubiblock_create_from_ } } @@ -33,6 +33,9 @@ Signed-off-by: Daniel Golle + for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { + desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); + if (IS_ERR(desc)) ++ desc = ubi_open_volume_nm(ubi_num, "fit", UBI_READONLY);; ++ ++ if (IS_ERR(desc)) + continue; + + ubi_get_volume_info(desc, &vi); diff --git a/target/linux/generic/pending-5.4/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.4/491-ubi-auto-create-ubiblock-device-for-rootfs.patch index 61fcbac92e..88d609d996 100644 --- a/target/linux/generic/pending-5.4/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +++ b/target/linux/generic/pending-5.4/491-ubi-auto-create-ubiblock-device-for-rootfs.patch @@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c -@@ -652,6 +652,44 @@ static void __init ubiblock_create_from_ +@@ -652,6 +652,47 @@ static void __init ubiblock_create_from_ } } @@ -33,6 +33,9 @@ Signed-off-by: Daniel Golle + for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { + desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); + if (IS_ERR(desc)) ++ desc = ubi_open_volume_nm(ubi_num, "fit", UBI_READONLY);; ++ ++ if (IS_ERR(desc)) + continue; + + ubi_get_volume_info(desc, &vi);