image: extend FIT partition parser for use on eMMC/SDcard
Introduce a magic GUID_PARTITION_LINUX_FIT_GUID to designate a GPT partition to be interpreted by the FIT partition parser. In that way, sub-partitions for (external-data) uImage.FIT stored directly in a partition can be split, similar like we do for devices with raw flash storage. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
		| @@ -44,18 +44,26 @@ | ||||
|  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 | ||||
| @@ -10,6 +10,8 @@ | ||||
| @@ -10,6 +10,10 @@ | ||||
|  #include <linux/vmalloc.h> | ||||
|  #include <linux/blktrace_api.h> | ||||
|  #include <linux/raid/detect.h> | ||||
| +#ifdef CONFIG_FIT_PARTITION | ||||
| +#include <linux/root_dev.h> | ||||
| +#endif | ||||
| + | ||||
|  #include "check.h" | ||||
|   | ||||
|  static int (*check_part[])(struct parsed_partitions *) = { | ||||
| @@ -46,6 +48,9 @@ static int (*check_part[])(struct parsed | ||||
| @@ -46,6 +50,9 @@ static int (*check_part[])(struct parsed | ||||
|  #ifdef CONFIG_EFI_PARTITION | ||||
|  	efi_partition,		/* this must come before msdos */ | ||||
|  #endif | ||||
| @@ -65,12 +73,49 @@ | ||||
|  #ifdef CONFIG_SGI_PARTITION | ||||
|  	sgi_partition, | ||||
|  #endif | ||||
| @@ -694,6 +699,9 @@ static bool blk_add_partition(struct gen | ||||
| @@ -215,6 +222,18 @@ static ssize_t part_discard_alignment_sh | ||||
|  				p->start_sect)); | ||||
|  } | ||||
|   | ||||
| +static ssize_t part_name_show(struct device *dev, | ||||
| +			      struct device_attribute *attr, char *buf) | ||||
| +{ | ||||
| +	struct hd_struct *p = dev_to_part(dev); | ||||
| + | ||||
| +	if (p->info && p->info->volname) | ||||
| +		return sprintf(buf, "%s\n", p->info->volname); | ||||
| + | ||||
| +	buf[0] = '\0'; | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
|  static DEVICE_ATTR(partition, 0444, part_partition_show, NULL); | ||||
|  static DEVICE_ATTR(start, 0444, part_start_show, NULL); | ||||
|  static DEVICE_ATTR(size, 0444, part_size_show, NULL); | ||||
| @@ -223,6 +242,7 @@ static DEVICE_ATTR(alignment_offset, 044 | ||||
|  static DEVICE_ATTR(discard_alignment, 0444, part_discard_alignment_show, NULL); | ||||
|  static DEVICE_ATTR(stat, 0444, part_stat_show, NULL); | ||||
|  static DEVICE_ATTR(inflight, 0444, part_inflight_show, NULL); | ||||
| +static DEVICE_ATTR(name, 0444, part_name_show, NULL); | ||||
|  #ifdef CONFIG_FAIL_MAKE_REQUEST | ||||
|  static struct device_attribute dev_attr_fail = | ||||
|  	__ATTR(make-it-fail, 0644, part_fail_show, part_fail_store); | ||||
| @@ -237,6 +257,7 @@ static struct attribute *part_attrs[] = | ||||
|  	&dev_attr_discard_alignment.attr, | ||||
|  	&dev_attr_stat.attr, | ||||
|  	&dev_attr_inflight.attr, | ||||
| +	&dev_attr_name.attr, | ||||
|  #ifdef CONFIG_FAIL_MAKE_REQUEST | ||||
|  	&dev_attr_fail.attr, | ||||
|  #endif | ||||
| @@ -694,6 +715,11 @@ static bool blk_add_partition(struct gen | ||||
|  	    (state->parts[p].flags & ADDPART_FLAG_RAID)) | ||||
|  		md_autodetect_dev(part_to_dev(part)->devt); | ||||
|   | ||||
| +#ifdef CONFIG_FIT_PARTITION | ||||
| +	if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0) | ||||
| +		ROOT_DEV = part_to_dev(part)->devt; | ||||
| +#endif | ||||
| + | ||||
|  	return true; | ||||
|  } | ||||
| @@ -94,3 +139,62 @@ | ||||
|  	sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); | ||||
|  	set_capacity(gd, disk_capacity); | ||||
|  	dev->gd = gd; | ||||
| --- a/block/partitions/efi.c | ||||
| +++ b/block/partitions/efi.c | ||||
| @@ -704,7 +704,7 @@ int efi_partition(struct parsed_partitio | ||||
|  { | ||||
|  	gpt_header *gpt = NULL; | ||||
|  	gpt_entry *ptes = NULL; | ||||
| -	u32 i; | ||||
| +	u32 i, slot = 0; | ||||
|  	unsigned ssz = bdev_logical_block_size(state->bdev) / 512; | ||||
|   | ||||
|  	if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { | ||||
| @@ -722,23 +722,30 @@ int efi_partition(struct parsed_partitio | ||||
|  		u64 size = le64_to_cpu(ptes[i].ending_lba) - | ||||
|  			   le64_to_cpu(ptes[i].starting_lba) + 1ULL; | ||||
|   | ||||
| -		if (!is_pte_valid(&ptes[i], last_lba(state->bdev))) | ||||
| +		if (!is_pte_valid(&ptes[i], last_lba(state->bdev))) { | ||||
| +			++slot; | ||||
|  			continue; | ||||
| +		} | ||||
|   | ||||
| -		put_partition(state, i+1, start * ssz, size * ssz); | ||||
| +		put_partition(state, ++slot, start * ssz, size * ssz); | ||||
|   | ||||
|  		/* If this is a RAID volume, tell md */ | ||||
|  		if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID)) | ||||
| -			state->parts[i + 1].flags = ADDPART_FLAG_RAID; | ||||
| +			state->parts[slot].flags = ADDPART_FLAG_RAID; | ||||
|   | ||||
| -		info = &state->parts[i + 1].info; | ||||
| +		info = &state->parts[slot].info; | ||||
|  		efi_guid_to_str(&ptes[i].unique_partition_guid, info->uuid); | ||||
|   | ||||
|  		/* Naively convert UTF16-LE to 7 bits. */ | ||||
|  		label_max = min(ARRAY_SIZE(info->volname) - 1, | ||||
|  				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; | ||||
| +		state->parts[slot].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, &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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Daniel Golle
					Daniel Golle