diff options
Diffstat (limited to 'target/linux/generic')
7 files changed, 438 insertions, 2 deletions
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 <linux/types.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_fdt.h> +#include <linux/libfdt.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 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 <linux/vmalloc.h> + #include <linux/blktrace_api.h> + #include <linux/raid/detect.h> ++#include <linux/root_dev.h> ++ + #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 <linux/ctype.h> + #include <linux/genhd.h> + #include <linux/blktrace_api.h> ++#include <linux/root_dev.h> + + #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 <daniel@makrotopia.org> --- 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 <daniel@makrotopia.org> + 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 <daniel@makrotopia.org> --- 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 <daniel@makrotopia.org> + 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); |