public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Steve Rae <srae@broadcom.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2] fastboot: handle flash write to GPT partition
Date: Wed, 10 Dec 2014 17:48:19 -0800	[thread overview]
Message-ID: <5488F7E3.5090703@broadcom.com> (raw)
In-Reply-To: <20141209100559.0100a725@amdc2363>

Hi Lukasz,

On 14-12-09 01:05 AM, Lukasz Majewski wrote:
> Hi Steve,
>
>> Implement a feature to allow fastboot to write the downloaded image
>> to the space reserved for the Protective MBR and the Primary GUID
>> Partition Table.
>>
>> Signed-off-by: Steve Rae <srae@broadcom.com>
>> ---
>>
>> Changes in v2:
>> add validation of the GPT before writing to flash
>> (suggested by: Lukasz Majewski <l.majewski@samsung.com>)
>>
>>   README          |  7 +++++++
>>   common/fb_mmc.c | 26 +++++++++++++++++++++++---
>>   disk/part_efi.c | 37 +++++++++++++++++++++++++++++++++++++
>>   include/part.h  | 10 ++++++++++
>>   4 files changed, 77 insertions(+), 3 deletions(-)
>>
>> diff --git a/README b/README
>> index 4ca04d0..5f50cdd 100644
>> --- a/README
>> +++ b/README
>> @@ -1773,6 +1773,13 @@ The following options need to be configured:
>>   		regarding the non-volatile storage device. Define
>> this to the eMMC device that fastboot should use to store the image.
>>
>> +		CONFIG_FASTBOOT_GPT_NAME
>> +		The fastboot "flash" command supports writing the
>> downloaded
>> +		image to the Protective MBR and the Primary GUID
>> Partition
>> +		Table. This occurs when the specified "partition
>> name" on the
>> +		"fastboot flash" command line matches this value.
>> +		Default is GPT_ENTRY_NAME (currently "gpt") if
>> undefined. +
>>   - Journaling Flash filesystem support:
>>   		CONFIG_JFFS2_NAND, CONFIG_JFFS2_NAND_OFF,
>> CONFIG_JFFS2_NAND_SIZE, CONFIG_JFFS2_NAND_DEV
>> diff --git a/common/fb_mmc.c b/common/fb_mmc.c
>> index fb06d8a..a646a7b 100644
>> --- a/common/fb_mmc.c
>> +++ b/common/fb_mmc.c
>> @@ -4,12 +4,17 @@
>>    * SPDX-License-Identifier:	GPL-2.0+
>>    */
>>
>> +#include <config.h>
>>   #include <common.h>
>>   #include <fb_mmc.h>
>>   #include <part.h>
>>   #include <aboot.h>
>>   #include <sparse_format.h>
>>
>> +#ifndef CONFIG_FASTBOOT_GPT_NAME
>> +#define CONFIG_FASTBOOT_GPT_NAME GPT_ENTRY_NAME
>> +#endif
>> +
>>   /* The 64 defined bytes plus the '\0' */
>>   #define RESPONSE_LEN	(64 + 1)
>>
>> @@ -62,9 +67,9 @@ static void write_raw_image(block_dev_desc_t
>> *dev_desc, disk_partition_t *info, void fb_mmc_flash_write(const char
>> *cmd, void *download_buffer, unsigned int download_bytes, char
>> *response) {
>> -	int ret;
>>   	block_dev_desc_t *dev_desc;
>>   	disk_partition_t info;
>> +	lbaint_t blksz;
>>
>>   	/* initialize the response buffer */
>>   	response_str = response;
>> @@ -76,8 +81,23 @@ void fb_mmc_flash_write(const char *cmd, void
>> *download_buffer, return;
>>   	}
>>
>> -	ret = get_partition_info_efi_by_name(dev_desc, cmd, &info);
>> -	if (ret) {
>> +	if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
>> +		printf("%s: updating GUID Partition Table (including
>> MBR)\n",
>> +		       __func__);
>> +		/* start at Protective MBR */
>> +		info.start = (GPT_PRIMARY_PARTITION_TABLE_LBA - 1);
>> +		blksz = dev_desc->blksz;
>> +		info.blksz = blksz;
>> +		/* assume that the Partition Entry Array starts in
>> LBA 2 */
>> +		info.size = (2 + (GPT_ENTRY_NUMBERS *
>> GPT_ENTRY_SIZE) / blksz); +
>> +		if (is_valid_gpt_primary(download_buffer,
>> dev_desc->blksz)) {
>> +			printf("%s: invalid GPT - refusing to write
>> to flash\n",
>> +			       __func__);
>> +			fastboot_fail("invalid GPT partition");
>> +			return;
>> +		}
>
> IMHO some extra code to update secondary (backup) GPT is needed here.
>
> A good example may be at part_efi.c - print_part_efi() function [1].
>

OK -- added "prepare and write Backup GPT" in v3

>> +	} else if (get_partition_info_efi_by_name(dev_desc, cmd,
>> &info)) { error("cannot find partition: '%s'\n", cmd);
>>   		fastboot_fail("cannot find partition");
>>   		return;
>> diff --git a/disk/part_efi.c b/disk/part_efi.c
>> index efed58f..86cb160 100644
>> --- a/disk/part_efi.c
>> +++ b/disk/part_efi.c
>> @@ -455,6 +455,43 @@ err:
>>   	free(gpt_h);
>>   	return ret;
>>   }
>> +
>> +int is_valid_gpt_primary(void *buf, unsigned long blksz)
>
> The name is a bit misleading - I rather though about something like
> is_valid_gpt_buf() and write it in a similar way to is_valid_gpt()
> which would allow using it for both primary and secondary GPTs (like in
> [1]).

OK - I changed the name, however, it still can only handle a buffer 
which contains:
- 512 bytes of MBR, followed by
- 512 bytes of GPT Header, followed by
the GPT Entries at the specified offset (typically 2 * 512 bytes)
Thus, it cannot be used for the Backup GPT anyway....

>
>> +{
>> +	int rc = 0;
>> +	gpt_header *gpt_h;
>> +	gpt_entry *gpt_e;
>> +	gpt_header gpt_hdr;
>> +	uint32_t calc_crc32;
>> +
>> +	/* GPT Header starts at "LBA[1]" in the buffer */
>> +	gpt_h = buf + blksz;
>> +	if (gpt_h->signature != cpu_to_le64(GPT_HEADER_SIGNATURE)) {
>> +		printf("%s: 'signature' is invalid\n", __func__);
>> +		rc += 1;
>> +	}
>> +
>> +	memcpy(&gpt_hdr, gpt_h, sizeof(gpt_header));
>> +	gpt_hdr.header_crc32 = 0;
>> +	calc_crc32 = efi_crc32((const unsigned char *)&gpt_hdr,
>> +			       le32_to_cpu(gpt_h->header_size));
>> +	if (gpt_h->header_crc32 != cpu_to_le32(calc_crc32)) {
>> +		printf("%s: 'header_crc32' is invalid\n", __func__);
>> +		rc += 1;
>> +	}
>> +
>> +	/* GPT Entries start at "LBA[2]" in the buffer */
>> +	gpt_e = buf + (2 * blksz);
>> +	calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
>> +
>> le32_to_cpu(gpt_h->num_partition_entries) *
>> +
>> le32_to_cpu(gpt_h->sizeof_partition_entry));
>> +	if (gpt_h->partition_entry_array_crc32 !=
>> cpu_to_le32(calc_crc32)) {
>> +		printf("%s: 'partition_entry_array_crc32' is
>> invalid\n",
>> +		       __func__);
>> +		rc += 1;
>> +	}
>> +	return rc;
>> +}
>>   #endif
>>
>>   /*
>> diff --git a/include/part.h b/include/part.h
>> index a496a4a..9cfa4c9 100644
>> --- a/include/part.h
>> +++ b/include/part.h
>> @@ -244,6 +244,16 @@ int gpt_fill_header(block_dev_desc_t *dev_desc,
>> gpt_header *gpt_h, */
>>   int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
>>   		disk_partition_t *partitions, const int parts_count);
>> +
>> +/**
>> + * is_valid_gpt_primary() - Ensure that the Primary GPT information
>> is valid
>> + *
>> + * @param buf - buffer which contains the Primary GPT info
>> + * @param blksz -  block size (in bytes)
>> + *
>> + * @return - '0' on success, otherwise error
>> + */
>> +int is_valid_gpt_primary(void *buf, unsigned long blksz);
>>   #endif
>>
>>   #endif /* _PART_H */
>
>
>

  reply	other threads:[~2014-12-11  1:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-09  0:34 [U-Boot] [PATCH v2] fastboot: handle flash write to GPT partition Steve Rae
2014-12-09  9:05 ` Lukasz Majewski
2014-12-11  1:48   ` Steve Rae [this message]
2014-12-11 10:11     ` Lukasz Majewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5488F7E3.5090703@broadcom.com \
    --to=srae@broadcom.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox