disk: part_efi: move code to static functions
PATCH v4 1/2 disk: part_efi: move code to static functions
---
Changes in v4:
- move common code to static functions
Changes in v3: None
Changes in v2: None
disk/part_efi.c | 175 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 73 deletions(-)
disk/part_efi.c +102 -73
@@ -69,6 +69,105 @@ static inline int is_bootable(gpt_entry *p) sizeof(efi_guid_t)); } +static int validate_gpt_header (gpt_header *gpt_h,lbaint_t lba, +lbaint_t lastlba) +{ +uint32_t crc32_backup =0 ; +uint32_t calc_crc32; + +/* Check the GPT header signature */ +if (le64_to_cpu (gpt_h->signature) !=GPT_HEADER_SIGNATURE ) { +printf ("%s signature is wrong: 0x%llX != 0x%llX\n" , +"GUID Partition Table Header" , +le64_to_cpu (gpt_h->signature), +GPT_HEADER_SIGNATURE ); +return -1 ; + } + +/* Check the GUID Partition Table CRC */ +memcpy (&crc32_backup, &gpt_h->header_crc32,sizeof (crc32_backup)); +memset (&gpt_h->header_crc32,0 ,sizeof (gpt_h->header_crc32)); + + calc_crc32 =efi_crc32 ((const unsigned char *)gpt_h, +le32_to_cpu (gpt_h->header_size)); + +memcpy (&gpt_h->header_crc32, &crc32_backup,sizeof (crc32_backup)); + +if (calc_crc32 !=le32_to_cpu (crc32_backup)) { +printf ("%s CRC is wrong: 0x%x != 0x%x\n" , +"GUID Partition Table Header" , +le32_to_cpu (crc32_backup), calc_crc32); +return -1 ; + } + +/* +* Check that the my_lba entry points to the LBA that contains the GPT +*/ +if (le64_to_cpu (gpt_h->my_lba) != lba) { +printf ("GPT: my_lba incorrect: %llX != " LBAF "\n" , +le64_to_cpu (gpt_h->my_lba), + lba); +return -1 ; + } + +/* +* Check that the first_usable_lba and that the last_usable_lba are +* within the disk. +*/ +if (le64_to_cpu (gpt_h->first_usable_lba) > lastlba) { +printf ("GPT: first_usable_lba incorrect: %llX > " LBAF "\n" , +le64_to_cpu (gpt_h->first_usable_lba), lastlba); +return -1 ; + } +if (le64_to_cpu (gpt_h->last_usable_lba) > lastlba) { +printf ("GPT: last_usable_lba incorrect: %llX > " LBAF "\n" , +le64_to_cpu (gpt_h->last_usable_lba), lastlba); +return -1 ; + } + +debug ("GPT: first_usable_lba: %llX last_usable_lba: %llX last lba: " +LBAF "\n" ,le64_to_cpu (gpt_h->first_usable_lba), +le64_to_cpu (gpt_h->last_usable_lba), lastlba); + +return 0 ; +} + +static int validate_gpt_entries (gpt_header *gpt_h,gpt_entry *gpt_e) +{ +uint32_t calc_crc32; + +/* Check the GUID Partition Table Entry Array CRC */ + 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 (calc_crc32 !=le32_to_cpu (gpt_h->partition_entry_array_crc32)) { +printf ("%s: 0x%x != 0x%x\n" , +"GUID Partition Table Entry Array CRC is wrong" , +le32_to_cpu (gpt_h->partition_entry_array_crc32), + calc_crc32); +return -1 ; + } + +return 0 ; +} + +static void prepare_backup_gpt_header (gpt_header *gpt_h) +{ +uint32_t calc_crc32; +uint64_t val; + +/* recalculate the values for the Backup GPT Header */ + val =le64_to_cpu (gpt_h->my_lba); + gpt_h->my_lba = gpt_h->alternate_lba; + gpt_h->alternate_lba =cpu_to_le64 (val); + gpt_h->header_crc32 =0 ; + + calc_crc32 =efi_crc32 ((const unsigned char *)gpt_h, +le32_to_cpu (gpt_h->header_size)); + gpt_h->header_crc32 =cpu_to_le32 (calc_crc32); +} +#ifdef CONFIG_EFI_PARTITION /* * Public Functions (include/part.h)
@@ -259,7 +358,6 @@ int write_gpt_table(block_dev_desc_t *dev_desc,const int pte_blk_cnt =BLOCK_CNT ((gpt_h->num_partition_entries *sizeof (gpt_entry)), dev_desc);u32 calc_crc32; -u64 val;debug ("max lba: %x\n" , (u32 ) dev_desc->lba);/* Setup the Protective MBR */
@@ -284,15 +382,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc, != pte_blk_cnt) goto err; -/* recalculate the values for the Backup GPT Header */ - val =le64_to_cpu (gpt_h->my_lba); - gpt_h->my_lba = gpt_h->alternate_lba; - gpt_h->alternate_lba =cpu_to_le64 (val); - gpt_h->header_crc32 =0 ; - - calc_crc32 =efi_crc32 ((const unsigned char *)gpt_h, -le32_to_cpu (gpt_h->header_size)); - gpt_h->header_crc32 =cpu_to_le32 (calc_crc32); +prepare_backup_gpt_header (gpt_h); if (dev_desc->block_write(dev_desc->dev, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba)
@@ -511,10 +601,6 @@ static int is_pmbr_valid(legacy_mbr * mbr)static int is_gpt_valid (block_dev_desc_t *dev_desc,u64 lba,gpt_header *pgpt_head,gpt_entry **pgpt_pte) { -u32 crc32_backup =0 ; -u32 calc_crc32; -u64 lastlba; -if (!dev_desc || !pgpt_head) {printf ("%s: Invalid Argument(s)\n" , __func__);return 0 ;
@@ -527,55 +613,8 @@ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba,return 0 ; } -/* Check the GPT header signature */ -if (le64_to_cpu (pgpt_head->signature) !=GPT_HEADER_SIGNATURE ) { -printf ("GUID Partition Table Header signature is wrong:" -"0x%llX != 0x%llX\n" , -le64_to_cpu (pgpt_head->signature), -GPT_HEADER_SIGNATURE ); -return 0 ; - } - -/* Check the GUID Partition Table CRC */ -memcpy (&crc32_backup, &pgpt_head->header_crc32,sizeof (crc32_backup)); -memset (&pgpt_head->header_crc32,0 ,sizeof (pgpt_head->header_crc32)); - - calc_crc32 =efi_crc32 ((const unsigned char *)pgpt_head, -le32_to_cpu (pgpt_head->header_size)); - -memcpy (&pgpt_head->header_crc32, &crc32_backup,sizeof (crc32_backup)); - -if (calc_crc32 !=le32_to_cpu (crc32_backup)) { -printf ("GUID Partition Table Header CRC is wrong:" -"0x%x != 0x%x\n" , -le32_to_cpu (crc32_backup), calc_crc32); -return 0 ; - } - -/* Check that the my_lba entry points to the LBA that contains the GPT */ -if (le64_to_cpu (pgpt_head->my_lba) != lba) { -printf ("GPT: my_lba incorrect: %llX != %" PRIX64 "\n" , -le64_to_cpu (pgpt_head->my_lba), - lba); +if (validate_gpt_header (pgpt_head, (lbaint_t )lba, dev_desc->lba))return 0 ; - } - -/* Check the first_usable_lba and last_usable_lba are within the disk. */ - lastlba = (u64 )dev_desc->lba; -if (le64_to_cpu (pgpt_head->first_usable_lba) > lastlba) { -printf ("GPT: first_usable_lba incorrect: %llX > %" PRIX64 "\n" , -le64_to_cpu (pgpt_head->first_usable_lba), lastlba); -return 0 ; - } -if (le64_to_cpu (pgpt_head->last_usable_lba) > lastlba) { -printf ("GPT: last_usable_lba incorrect: %llX > %" PRIX64 "\n" , -le64_to_cpu (pgpt_head->last_usable_lba), lastlba); -return 0 ; - } - -debug ("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %" -PRIX64 "\n" ,le64_to_cpu (pgpt_head->first_usable_lba), -le64_to_cpu (pgpt_head->last_usable_lba), lastlba);/* Read and allocate Partition Table Entries */ *pgpt_pte =alloc_read_gpt_entries (dev_desc, pgpt_head);
@@ -584,17 +623,7 @@ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba,return 0 ; } -/* Check the GUID Partition Table Entry Array CRC */ - calc_crc32 =efi_crc32 ((const unsigned char *)*pgpt_pte, -le32_to_cpu (pgpt_head->num_partition_entries) * -le32_to_cpu (pgpt_head->sizeof_partition_entry)); - -if (calc_crc32 !=le32_to_cpu (pgpt_head->partition_entry_array_crc32)) { -printf ("GUID Partition Table Entry Array CRC is wrong:" -"0x%x != 0x%x\n" , -le32_to_cpu (pgpt_head->partition_entry_array_crc32), - calc_crc32); - +if (validate_gpt_entries (pgpt_head, *pgpt_pte)) {free (*pgpt_pte);return 0 ; }
Signature · 1 line
1.8.5
PATCH v4 2/2 fastboot: handle flash write to GPT partitions
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.
Additionally, prepare and write the Backup GUID Partition Table.
---
Changes in v4:
fix bug with partition_entry_lba in Backup GPT
use common static functions
Changes in v3:
- prefer leXX_to_cpu() over cpu_to_leXX()
- enhance calculation of pointer to GPT Entries
- prepare and write the Backup GPT
(requested by: Lukasz Majewski <[email protected]>)
Changes in v2:
add validation of the GPT before writing to flash (suggested by: Lukasz Majewski <[email protected]>)
README | 9 ++++++ common/fb_mmc.c | 26 ++++++++++++++-- disk/part_efi.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/part.h | 20 +++++++++++++ 4 files changed, 145 insertions(+), 3 deletions(-)
README +9 -0
@@ -1773,6 +1773,15 @@ 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. (Additionally, this downloaded image is post-processed + to generate and write the Backup 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
common/fb_mmc.c +23 -3
@@ -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,7 +67,6 @@ 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;
@@ -76,8 +80,24 @@ 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 MBR, Primary and Backup GPT(s)\n" , + __func__); +if (is_valid_gpt_buf (dev_desc, download_buffer)) { +printf ("%s: invalid GPT - refusing to write to flash\n" , + __func__); +fastboot_fail ("invalid GPT partition" ); +return ; + } +if (write_mbr_and_gpt_partitions (dev_desc, download_buffer)) { +printf ("%s: writing GPT partitions failed\n" , __func__); +fastboot_fail ("writing GPT partitions failed" ); +return ; + } +printf ("........ success\n" ); +fastboot_okay ("" ); +return ; + }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 ;
disk/part_efi.c +93 -0
105 lines not on this page · raw message
include/part.h +20 -0
@@ -244,6 +244,26 @@ 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_buf() - Ensure that the Primary GPT information is valid +* +* @param dev_desc - block device descriptor +* @param buf - buffer which contains the MBR and Primary GPT info +* +* @return - '0' on success, otherwise error +*/ +int is_valid_gpt_buf (block_dev_desc_t *dev_desc,void *buf); + +/** +* write_mbr_and_gpt_partitions() - write MBR, Primary GPT and Backup GPT +* +* @param dev_desc - block device descriptor +* @param buf - buffer which contains the MBR and Primary GPT info +* +* @return - '0' on success, otherwise error +*/ +int write_mbr_and_gpt_partitions (block_dev_desc_t *dev_desc,void *buf);#endif #endif /* _PART_H */
Signature · 1 line
1.8.5
PATCH v4 2/2 fastboot: handle flash write to GPT partitions
Hi Steve,
Quoted 272 lines
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.
Additionally, prepare and write the Backup GUID Partition Table.Signed-off-by Steve Rae <[email protected]>---
Changes in v4:
fix bug withpartition_entry_lbain Backup GPT
use common static functionsChanges in v3:
- preferleXX_to_cpu()overcpu_to_leXX()
- enhance calculation of pointer to GPT Entries
- prepare and write the Backup GPT
(requested by: Lukasz Majewski <[email protected]>)Changes in v2:
add validation of the GPT before writing to flash (suggested by: Lukasz Majewski <[email protected]>)README | 9 ++++++ common/fb_mmc.c | 26 ++++++++++++++-- disk/part_efi.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/part.h| 20 +++++++++++++ 4 files changed, 145 insertions(+), 3 deletions(-)README +0
-0@@ -1773,6 +1773,15 @@ The following options need to be configured: regarding the non-volatile storage device. Definethis to the eMMC device that fastboot should use to store the image.
README +2
-0+ CONFIG_FASTBOOT_GPT_NAME + The fastboot "flash" command supports writing thedownloaded
README +1
-0+ image to the Protective MBR and the Primary GUIDPartition
README +1
-0+ Table. (Additionally, this downloaded image ispost-processed
README +1
-0+ to generate and write the Backup GUID PartitionTable.)
README +1
-0+ This occurs when the specified "partition name" onthe
README +2
-0+ "fastboot flash" command line matches this value. + Default is GPT_ENTRY_NAME (currently "gpt") ifundefined. +
- Journaling Flash filesystem support:
CONFIG_JFFS2_NAND,CONFIG_JFFS2_NAND_OFF,CONFIG_JFFS2_NAND_SIZE,CONFIG_JFFS2_NAND_DEVcommon/fb_mmc.c +16
-3@@ -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,7 +67,6 @@ 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;@@ -76,8 +80,24 @@ 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 MBR, Primary and Backup GPT(s)\n", + __func__); +if (is_valid_gpt_buf (dev_desc, download_buffer)) { + printf("%s: invalid GPT - refusing to write to flash\n", + __func__); +fastboot_fail ("invalid GPT partition" ); +return ; + } +if (write_mbr_and_gpt_partitions (dev_desc, download_buffer)) { + printf("%s: writing GPT partitionsfailed\n",
__func__);common/fb_mmc.c +1
-0+ fastboot_fail("writing GPT partitionsfailed");
common/fb_mmc.c +6
-0+return ; + } +printf ("........ success\n" ); +fastboot_okay ("" ); +return ; + } else if (get_partition_info_efi_by_name(dev_desc, cmd,&info)) {
error("cannot find partition: '%s'\n", cmd);common/fb_mmc.c +0
-0fastboot_fail ("cannot find partition" );return ;disk/part_efi.c +42
-0@@ -161,6 +161,8 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h) val = le64_to_cpu(gpt_h->my_lba); gpt_h->my_lba = gpt_h->alternate_lba; gpt_h->alternate_lba =cpu_to_le64 (val); + gpt_h->partition_entry_lba = +cpu_to_le64 (le64_to_cpu (gpt_h->last_usable_lba) +1 ); gpt_h->header_crc32 =0 ; calc_crc32 = efi_crc32((const unsigned char *)gpt_h,@@ -545,6 +547,97 @@ err:free (gpt_h);return ret; } + +int is_valid_gpt_buf (block_dev_desc_t *dev_desc,void *buf) +{ +gpt_header *gpt_h; +gpt_entry *gpt_e; + +/* determine start of GPT Header in the buffer */ + gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * + dev_desc->blksz); +if (validate_gpt_header (gpt_h,GPT_PRIMARY_PARTITION_TABLE_LBA , + dev_desc->lba)) +return -1 ; + +/* determine start of GPT Entries in the buffer */ + gpt_e = buf + (le64_to_cpu (gpt_h->partition_entry_lba) * + dev_desc->blksz); +if (validate_gpt_entries (gpt_h, gpt_e)) +return -1 ; + +return 0 ; +} + +int write_mbr_and_gpt_partitions (block_dev_desc_t *dev_desc,void *buf) +{ +gpt_header *gpt_h; +gpt_entry *gpt_e; +int gpt_e_blk_cnt; +lbaint_t lba; +int cnt; + +if (is_valid_gpt_buf (dev_desc, buf)) +return -1 ; + +/* determine start of GPT Header in the buffer */ + gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * + dev_desc->blksz); + +/* determine start of GPT Entries in the buffer */ + gpt_e = buf + (le64_to_cpu (gpt_h->partition_entry_lba) * + dev_desc->blksz); + gpt_e_blk_cnt =BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) * +
le32_to_cpu(gpt_h->sizeof_partition_entry)),disk/part_efi.c +6
-0+ dev_desc); + +/* write MBR */ + lba =0 ;/* MBR is always at 0 */ + cnt =1 ;/* MBR (1 block) */ + if (dev_desc->block_write(dev_desc->dev, lba, cnt, buf) !=cnt) {
disk/part_efi.c +1
-0+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF")\n",
disk/part_efi.c +8
-0+ __func__, "MBR", cnt, lba); +return 1 ; + } + +/* write Primary GPT */ + lba =GPT_PRIMARY_PARTITION_TABLE_LBA ; + cnt =1 ;/* GPT Header (1 block) */ + if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_h) !=cnt) {
disk/part_efi.c +1
-0+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF")\n",
disk/part_efi.c +7
-0+ __func__, "Primary GPT Header", cnt, lba); +return 1 ; + } + + lba =le64_to_cpu (gpt_h->partition_entry_lba); + cnt = gpt_e_blk_cnt; + if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_e) !=cnt) {
disk/part_efi.c +1
-0+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF")\n",
disk/part_efi.c +10
-0+ __func__, "Primary GPT Entries", cnt, lba); +return 1 ; + } + +prepare_backup_gpt_header (gpt_h); + +/* write Backup GPT */ + lba =le64_to_cpu (gpt_h->partition_entry_lba); + cnt = gpt_e_blk_cnt; + if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_e) !=cnt) {
disk/part_efi.c +1
-0+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF")\n",
disk/part_efi.c +7
-0+ __func__, "Backup GPT Entries", cnt, lba); +return 1 ; + } + + lba =le64_to_cpu (gpt_h->my_lba); + cnt =1 ;/* GPT Header (1 block) */ + if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_h) !=cnt) {
disk/part_efi.c +1
-0+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF")\n",
disk/part_efi.c +6
-0+ __func__, "Backup GPT Header", cnt, lba); + return 1; + } + +return 0 ; +}#endif /* include/part.h +0
-0@@ -244,6 +244,26 @@ 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,include/part.h +3
-0disk_partition_t *partitions, const int parts_count); + +/** +* is_valid_gpt_buf() - Ensure that the Primary GPT information is valid
+ *
+ * @paramdev_desc- block device descriptor
+ * @param buf - buffer which contains the MBR and Primary GPT info
+ *
+ * @return - '0' on success, otherwise error
+ */include/part.h +4
-0+int is_valid_gpt_buf (block_dev_desc_t *dev_desc,void *buf); + +/** +* write_mbr_and_gpt_partitions() - write MBR, Primary GPT and Backup GPT
+ *
+ * @paramdev_desc- block device descriptor
+ * @param buf - buffer which contains the MBR and Primary GPT info
+ *
+ * @return - '0' on success, otherwise error
+ */
+intwrite_mbr_and_gpt_partitions(block_dev_desc_t *dev_desc, void *buf); #endif
Quoted 1 line
#endif /*
_PART_H*/
Test HW: Exynos4412 - trats2
To Marek:
This patch cleanly applies to master (SHA1:b9206e61f3d87535ac4f4b0b858e674fd1edfeaf) not u-boot-usb.
Therefore I cannot apply it to u-boot-usb based -dfu tree. We can either wait up the moment when -dfu get in sync with mainline or apply this patch to mainline directly.
Signature · 5 lines
Best regards, Lukasz Majewski Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
PATCH v4 2/2 fastboot: handle flash write to GPT partitions
In reply to Steve RaeQuoted 4 lines · Steve Rae
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.
Additionally, prepare and write the Backup GUID Partition Table.
I've been looking at how to do the same thing here. This is an area that suffers from each vendor doing whatever they want. Using vendor download/flash tools here is painful. They are all different because that is where the value add is. ;) What tool do you use on the host side to create the image? I have seen some vendor code to do it, or you could use parted plus a disk file and extract the partition table from it. I find either method a bit fragile and non-standard IMHO.
The 2 options I've come up with are 1) enable USB MS and use whatever host side tool you like or 2) use the existing "gpt write" command in u-boot and tie that into fastboot "oem format" command. The advantage and disadvantage of the latter is that it hides the partitioning details in u-boot from the user, but requires changing the u-boot env to change partition layout. The partitioning requirements are pretty SOC specific it seems.
I'm not saying we can't support both, but having some standardization here would be good.
Rob
Quoted 250 lines
Signed-off-by Steve Rae <[email protected]>---
Changes in v4:
fix bug withpartition_entry_lbain Backup GPT
use common static functionsChanges in v3:
- preferleXX_to_cpu()overcpu_to_leXX()
- enhance calculation of pointer to GPT Entries
- prepare and write the Backup GPT
(requested by: Lukasz Majewski <[email protected]>)Changes in v2:
add validation of the GPT before writing to flash (suggested by: Lukasz Majewski <[email protected]>)README | 9 ++++++ common/fb_mmc.c | 26 ++++++++++++++-- disk/part_efi.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/part.h | 20 +++++++++++++ 4 files changed, 145 insertions(+), 3 deletions(-)README +9
-0@@ -1773,6 +1773,15 @@ 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. (Additionally, this downloaded image is post-processed + to generate and write the Backup 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_DEVcommon/fb_mmc.c +23
-3@@ -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,7 +67,6 @@ 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;@@ -76,8 +80,24 @@ 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 MBR, Primary and Backup GPT(s)\n" , + __func__); +if (is_valid_gpt_buf (dev_desc, download_buffer)) { +printf ("%s: invalid GPT - refusing to write to flash\n" , + __func__); +fastboot_fail ("invalid GPT partition" ); +return ; + } +if (write_mbr_and_gpt_partitions (dev_desc, download_buffer)) { +printf ("%s: writing GPT partitions failed\n" , __func__); +fastboot_fail ("writing GPT partitions failed" ); +return ; + } +printf ("........ success\n" ); +fastboot_okay ("" ); +return ; + }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 ;disk/part_efi.c +93
-0@@ -161,6 +161,8 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h) val =le64_to_cpu (gpt_h->my_lba); gpt_h->my_lba = gpt_h->alternate_lba; gpt_h->alternate_lba =cpu_to_le64 (val); + gpt_h->partition_entry_lba = +cpu_to_le64 (le64_to_cpu (gpt_h->last_usable_lba) +1 ); gpt_h->header_crc32 =0 ; calc_crc32 = efi_crc32((const unsigned char *)gpt_h,@@ -545,6 +547,97 @@ err:free (gpt_h);return ret; } + +int is_valid_gpt_buf (block_dev_desc_t *dev_desc,void *buf) +{ +gpt_header *gpt_h; +gpt_entry *gpt_e; + +/* determine start of GPT Header in the buffer */ + gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * + dev_desc->blksz); +if (validate_gpt_header (gpt_h,GPT_PRIMARY_PARTITION_TABLE_LBA , + dev_desc->lba)) +return -1 ; + +/* determine start of GPT Entries in the buffer */ + gpt_e = buf + (le64_to_cpu (gpt_h->partition_entry_lba) * + dev_desc->blksz); +if (validate_gpt_entries (gpt_h, gpt_e)) +return -1 ; + +return 0 ; +} + +int write_mbr_and_gpt_partitions (block_dev_desc_t *dev_desc,void *buf) +{ +gpt_header *gpt_h; +gpt_entry *gpt_e; +int gpt_e_blk_cnt; +lbaint_t lba; +int cnt; + +if (is_valid_gpt_buf (dev_desc, buf)) +return -1 ; + +/* determine start of GPT Header in the buffer */ + gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * + dev_desc->blksz); + +/* determine start of GPT Entries in the buffer */ + gpt_e = buf + (le64_to_cpu (gpt_h->partition_entry_lba) * + dev_desc->blksz); + gpt_e_blk_cnt =BLOCK_CNT ((le32_to_cpu (gpt_h->num_partition_entries) * +le32_to_cpu (gpt_h->sizeof_partition_entry)), + dev_desc); + +/* write MBR */ + lba =0 ;/* MBR is always at 0 */ + cnt =1 ;/* MBR (1 block) */ +if (dev_desc->block_write (dev_desc->dev, lba, cnt, buf) != cnt) { +printf ("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n" , + __func__,"MBR" , cnt, lba); +return 1 ; + } + +/* write Primary GPT */ + lba =GPT_PRIMARY_PARTITION_TABLE_LBA ; + cnt =1 ;/* GPT Header (1 block) */ +if (dev_desc->block_write (dev_desc->dev, lba, cnt, gpt_h) != cnt) { +printf ("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n" , + __func__,"Primary GPT Header" , cnt, lba); +return 1 ; + } + + lba =le64_to_cpu (gpt_h->partition_entry_lba); + cnt = gpt_e_blk_cnt; +if (dev_desc->block_write (dev_desc->dev, lba, cnt, gpt_e) != cnt) { +printf ("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n" , + __func__,"Primary GPT Entries" , cnt, lba); +return 1 ; + } + +prepare_backup_gpt_header (gpt_h); + +/* write Backup GPT */ + lba =le64_to_cpu (gpt_h->partition_entry_lba); + cnt = gpt_e_blk_cnt; +if (dev_desc->block_write (dev_desc->dev, lba, cnt, gpt_e) != cnt) { +printf ("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n" , + __func__,"Backup GPT Entries" , cnt, lba); +return 1 ; + } + + lba =le64_to_cpu (gpt_h->my_lba); + cnt =1 ;/* GPT Header (1 block) */ +if (dev_desc->block_write (dev_desc->dev, lba, cnt, gpt_h) != cnt) { +printf ("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n" , + __func__,"Backup GPT Header" , cnt, lba); +return 1 ; + } + +return 0 ; +}#endif /* include/part.h +20
-1@@ -244,6 +244,26 @@ 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_buf() - Ensure that the Primary GPT information is valid +* +* @param dev_desc - block device descriptor +* @param buf - buffer which contains the MBR and Primary GPT info +* +* @return - '0' on success, otherwise error +*/ +int is_valid_gpt_buf (block_dev_desc_t *dev_desc,void *buf); + +/** +* write_mbr_and_gpt_partitions() - write MBR, Primary GPT and Backup GPT +* +* @param dev_desc - block device descriptor +* @param buf - buffer which contains the MBR and Primary GPT info +* +* @return - '0' on success, otherwise error +*/ +int write_mbr_and_gpt_partitions (block_dev_desc_t *dev_desc,void *buf);#endif #endif /* _PART_H */ --1.8.5
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
PATCH v4 2/2 fastboot: handle flash write to GPT partitions
Quoted 22 lines · Rob Herring
Quoted 4 lines · Steve Rae
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.
Additionally, prepare and write the Backup GUID Partition Table.I've been looking at how to do the same thing here. This is an area that suffers from each vendor doing whatever they want. Using vendor download/flash tools here is painful. They are all different because that is where the value add is. ;) What tool do you use on the host side to create the image? I have seen some vendor code to do it, or you could use parted plus a disk file and extract the partition table from it. I find either method a bit fragile and non-standard IMHO.
The 2 options I've come up with are 1) enable USB MS and use whatever host side tool you like or 2) use the existing "gpt write" command in u-boot and tie that into fastboot "oem format" command. The advantage and disadvantage of the latter is that it hides the partitioning details in u-boot from the user, but requires changing the u-boot env to change partition layout. The partitioning requirements are pretty SOC specific it seems.
Quoted 2 lines
I'm not saying we can't support both, but having some standardization here would be good.
Option two seems "good" from a not firewalling off the details point of view which means that there'll be a subset that wants to go with one anyhow.
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150123/937ebf4d/attachment.pgp>
PATCH v4 2/2 fastboot: handle flash write to GPT partitions
In reply to Rob HerringQuoted 6 lines · Rob Herring
Quoted 4 lines · Steve Rae
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.
Additionally, prepare and write the Backup GUID Partition Table.
Quoted 8 lines
I've been looking at how to do the same thing here. This is an area that suffers from each vendor doing whatever they want. Using vendor download/flash tools here is painful. They are all different because that is where the value add is. ;) What tool do you use on the host side to create the image? I have seen some vendor code to do it, or you could use parted plus a disk file and extract the partition table from it. I find either method a bit fragile and non-standard IMHO.
We use an internal tool -- however, I also note that ALL of the source code for our tool is "GPL-2.0+" (expect for one file which is Public Domain) Is U-Boot (Denx) interested in supporting a "host tool"?
Quoted 8 lines
The 2 options I've come up with are 1) enable USB MS and use whatever host side tool you like or 2) use the existing "gpt write" command in u-boot and tie that into fastboot "oem format" command. The advantage and disadvantage of the latter is that it hides the partitioning details in u-boot from the user, but requires changing the u-boot env to change partition layout. The partitioning requirements are pretty SOC specific it seems.
We also have code which creates the GPT tables from a "fastboot oem format" command, and (if I understand correctly) we have code that implements a "gpt" command line, which creates the GPT tables from env variables...
If there is interest here, I could investigate further.
Quoted 5 lines
I'm not saying we can't support both, but having some standardization here would be good.
Rob
I wasn't trying to promote an exclusive solution with this patch (which has been accepted - Thanks!). I was just trying to have an incremental change to the existing "fastboot flash" command (to handle the GPT Tables).
Thanks, Steve
[... snip ...]
PATCH v4 2/2 fastboot: handle flash write to GPT partitions
Quoted 32 lines · Steve Rae
Quoted 9 lines · Rob Herring
Quoted 5 lines · Steve Rae
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.
Additionally, prepare and write the Backup GUID Partition Table.Quoted 8 lines
I've been looking at how to do the same thing here. This is an area that suffers from each vendor doing whatever they want. Using vendor download/flash tools here is painful. They are all different because that is where the value add is. ;) What tool do you use on the host side to create the image? I have seen some vendor code to do it, or you could use parted plus a disk file and extract the partition table from it. I find either method a bit fragile and non-standard IMHO.
We use an internal tool -- however, I also note that ALL of the source code for our tool is "GPL-2.0+" (expect for one file which is Public Domain) Is U-Boot (Denx) interested in supporting a "host tool"?
Quoted 8 lines
The 2 options I've come up with are 1) enable USB MS and use whatever host side tool you like or 2) use the existing "gpt write" command in u-boot and tie that into fastboot "oem format" command. The advantage and disadvantage of the latter is that it hides the partitioning details in u-boot from the user, but requires changing the u-boot env to change partition layout. The partitioning requirements are pretty SOC specific it seems.
Quoted 4 lines
We also have code which creates the GPT tables from a "fastboot oem format" command, and (if I understand correctly) we have code that implements a "gpt" command line, which creates the GPT tables from env variables... If there is interest here, I could investigate further.
I have patches I'm working on to do this. I hope to get them sent out soon.
Rob
PATCH v4 2/2 fastboot: handle flash write to GPT partitions
In reply to Rob HerringHi Rob,
Quoted 22 lines · Steve Rae
Quoted 4 lines
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.
Additionally, prepare and write the Backup GUID Partition Table.I've been looking at how to do the same thing here. This is an area that suffers from each vendor doing whatever they want. Using vendor download/flash tools here is painful. They are all different because that is where the value add is. ;) What tool do you use on the host side to create the image? I have seen some vendor code to do it, or you could use parted plus a disk file and extract the partition table from it. I find either method a bit fragile and non-standard IMHO.
The 2 options I've come up with are 1) enable USB MS and use whatever host side tool you like or 2) use the existing "gpt write" command in u-boot and tie that into fastboot "oem format" command. The advantage and disadvantage of the latter is that it hides the partitioning details in u-boot from the user, but requires changing the u-boot env to change partition layout. The partitioning requirements are pretty SOC specific it seems.
Quoted 2 lines
I'm not saying we can't support both, but having some standardization here would be good.
On Exynos4/5 it is possible to use both. One can use mass storage (UMS) and also gpt write.
Moreover, there is the dfu (which is slow but standardized) support in u-boot, which seems SoC vendor agnostic. One can use dfu-util tools on host side too.
I can share one way to update GPT by using dfu with 'gpt write' u-boot command.
1. It is possible to extract default variables when u-boot is build:
{
# Generate params.bin
cp find . -name "env_common.o" copy_env_common.o
objcopy -O binary --only-section=.rodata.default_environment find . -name "copy_env_common.o" tr '\0' '\n' < copy_env_common.o > default_envs.txt mkenvimage -s 16384 -o params.bin default_envs.txt
rm copy_env_common.o default_envs.txt
}
2. Store params.bin in a known location (the location is soc dependent).
3. Reset board and execute 'gpt write mmc 0 $partitions' to default $partitions from params.bin
This works on Exynos.
Another option would be to add special alt setting for dfu - GPT and MBR which would accept binary partition layout and store them to proper location.
Quoted 280 lines
Rob
Quoted 277 lines
Signed-off-by Steve Rae <[email protected]>---
Changes in v4:
fix bug withpartition_entry_lbain Backup GPT
use common static functionsChanges in v3:
- preferleXX_to_cpu()overcpu_to_leXX()
- enhance calculation of pointer to GPT Entries
- prepare and write the Backup GPT
(requested by: Lukasz Majewski <[email protected]>)Changes in v2:
add validation of the GPT before writing to flash (suggested by: Lukasz Majewski <[email protected]>)README | 9 ++++++ common/fb_mmc.c | 26 ++++++++++++++-- disk/part_efi.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/part.h| 20 +++++++++++++ 4 files changed, 145 insertions(+), 3 deletions(-)README +0
-0@@ -1773,6 +1773,15 @@ The following options need to be configured: regarding the non-volatile storage device. Definethis to the eMMC device that fastboot should use to store the image.
README +2
-0+ CONFIG_FASTBOOT_GPT_NAME + The fastboot "flash" command supports writing thedownloaded
+ image to the Protective MBR and the Primary GUID
Partition
+ Table. (Additionally, this downloaded image is
post-processed
+ to generate and write the Backup GUID Partition
Table.)
+ This occurs when the specified "partition name" on
theREADME +2
-0+ "fastboot flash" command line matches this value. + Default is GPT_ENTRY_NAME (currently "gpt") ifundefined. +
- Journaling Flash filesystem support:
CONFIG_JFFS2_NAND,CONFIG_JFFS2_NAND_OFF,CONFIG_JFFS2_NAND_SIZE,CONFIG_JFFS2_NAND_DEVcommon/fb_mmc.c +5
-0@@ -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,7 +67,6 @@ static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info, void fb_mmc_flash_write(constchar *cmd, void
*download_buffer, unsigned intdownload_bytes, char *response) {common/fb_mmc.c +11
-3-int ret;block_dev_desc_t *dev_desc;disk_partition_t info;@@ -76,8 +80,24 @@ 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 MBR, Primary and Backup GPT(s)\n", + __func__); +if (is_valid_gpt_buf (dev_desc, download_buffer)) { + printf("%s: invalid GPT - refusing to write to flash\n", + __func__); +fastboot_fail ("invalid GPT partition" ); +return ; + } +if (write_mbr_and_gpt_partitions (dev_desc, download_buffer)) { + printf("%s: writing GPT partitionsfailed\n",
__func__);
+ fastboot_fail("writing GPT partitions
failed");common/fb_mmc.c +6
-0+return ; + } +printf ("........ success\n" ); +fastboot_okay ("" ); +return ; + } 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;disk/part_efi.c +0
-0@@ -161,6 +161,8 @@ static void
prepare_backup_gpt_header(gpt_header *gpt_h)val =le64_to_cpu(gpt_h->my_lba); gpt_h->my_lba = gpt_h->alternate_lba; gpt_h->alternate_lba = cpu_to_le64(val);disk/part_efi.c +2
-0+ gpt_h->partition_entry_lba = +
cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);gpt_h->header_crc32= 0;
calc_crc32= efi_crc32((const unsigned char *)gpt_h,disk/part_efi.c +40
-0@@ -545,6 +547,97 @@ err:free (gpt_h);return ret; } + +int is_valid_gpt_buf (block_dev_desc_t *dev_desc,void *buf) +{ +gpt_header *gpt_h; +gpt_entry *gpt_e; + +/* determine start of GPT Header in the buffer */ + gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * + dev_desc->blksz); +if (validate_gpt_header (gpt_h,GPT_PRIMARY_PARTITION_TABLE_LBA , + dev_desc->lba)) +return -1 ; + +/* determine start of GPT Entries in the buffer */ + gpt_e = buf + (le64_to_cpu (gpt_h->partition_entry_lba) * + dev_desc->blksz); +if (validate_gpt_entries (gpt_h, gpt_e)) +return -1 ; + +return 0 ; +} + +int write_mbr_and_gpt_partitions (block_dev_desc_t *dev_desc,void *buf) +{ +gpt_header *gpt_h; +gpt_entry *gpt_e; +int gpt_e_blk_cnt; +lbaint_t lba; +int cnt; + +if (is_valid_gpt_buf (dev_desc, buf)) +return -1 ; + +/* determine start of GPT Header in the buffer */ + gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * + dev_desc->blksz); + +/* determine start of GPT Entries in the buffer */ + gpt_e = buf + (le64_to_cpu (gpt_h->partition_entry_lba) * + dev_desc->blksz); + gpt_e_blk_cnt =BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) * +
le32_to_cpu(gpt_h->sizeof_partition_entry)),disk/part_efi.c +6
-0+ dev_desc); + +/* write MBR */ + lba =0 ;/* MBR is always at 0 */ + cnt =1 ;/* MBR (1 block) */ + if (dev_desc->block_write(dev_desc->dev, lba, cnt, buf) !=cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x"
LBAF ")\n",disk/part_efi.c +8
-0+ __func__, "MBR", cnt, lba); +return 1 ; + } + +/* write Primary GPT */ + lba =GPT_PRIMARY_PARTITION_TABLE_LBA ; + cnt =1 ;/* GPT Header (1 block) */ + if (dev_desc->block_write(dev_desc->dev, lba, cnt,
gpt_h) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x"
LBAF ")\n",disk/part_efi.c +7
-0+ __func__, "Primary GPT Header", cnt, lba); +return 1 ; + } + + lba =le64_to_cpu (gpt_h->partition_entry_lba); + cnt = gpt_e_blk_cnt; + if (dev_desc->block_write(dev_desc->dev, lba, cnt,
gpt_e) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x"
LBAF ")\n",disk/part_efi.c +10
-0+ __func__, "Primary GPT Entries", cnt, lba); +return 1 ; + } + +prepare_backup_gpt_header (gpt_h); + +/* write Backup GPT */ + lba =le64_to_cpu (gpt_h->partition_entry_lba); + cnt = gpt_e_blk_cnt; + if (dev_desc->block_write(dev_desc->dev, lba, cnt,
gpt_e) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x"
LBAF ")\n",disk/part_efi.c +7
-0+ __func__, "Backup GPT Entries", cnt, lba); +return 1 ; + } + + lba =le64_to_cpu (gpt_h->my_lba); + cnt =1 ;/* GPT Header (1 block) */ + if (dev_desc->block_write(dev_desc->dev, lba, cnt,
gpt_h) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x"
LBAF ")\n",disk/part_efi.c +6
-0+ __func__, "Backup GPT Header", cnt, lba); + return 1; + } + +return 0 ; +}#endif /* include/part.h +0
-0@@ -244,6 +244,26 @@ 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_buf()- Ensure that the Primary GPT information is valid
+ *
+ * @paramdev_desc- block device descriptor
+ * @param buf - buffer which contains the MBR and Primary GPT info
+ *
+ * @return - '0' on success, otherwise error
+ */include/part.h +4
-0+int is_valid_gpt_buf (block_dev_desc_t *dev_desc,void *buf); + +/** +* write_mbr_and_gpt_partitions() - write MBR, Primary GPT and Backup GPT
+ *
+ * @paramdev_desc- block device descriptor
+ * @param buf - buffer which contains the MBR and Primary GPT info
+ *
+ * @return - '0' on success, otherwise error
+ */
+intwrite_mbr_and_gpt_partitions(block_dev_desc_t *dev_desc, void *buf); #endif#endif /*
_PART_H*/
--
1.8.5_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
Signature · 5 lines
Best regards, Lukasz Majewski Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
PATCH v4 1/2 disk: part_efi: move code to static functions
In reply to Steve RaeHi Steve,
Quoted 254 lines
Signed-off-by Steve Rae <[email protected]>---
Changes in v4:
- move common code to static functionsChanges in v3: None
Changes in v2: Nonedisk/part_efi.c | 175+++++++++++++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 73 deletions(-)
disk/part_efi.c +23
-0@@ -69,6 +69,105 @@ static inline int is_bootable(gpt_entry *p) sizeof(efi_guid_t)); } +static int validate_gpt_header (gpt_header *gpt_h,lbaint_t lba, +lbaint_t lastlba) +{ +uint32_t crc32_backup =0 ; +uint32_t calc_crc32; + +/* Check the GPT header signature */ +if (le64_to_cpu (gpt_h->signature) !=GPT_HEADER_SIGNATURE ) { +printf ("%s signature is wrong: 0x%llX != 0x%llX\n" , +"GUID Partition Table Header" , +le64_to_cpu (gpt_h->signature), +GPT_HEADER_SIGNATURE ); +return -1 ; + } + +/* Check the GUID Partition Table CRC */ +memcpy (&crc32_backup, &gpt_h->header_crc32,sizeof (crc32_backup)); +memset (&gpt_h->header_crc32,0 ,sizeof (gpt_h->header_crc32)); + + calc_crc32 =efi_crc32 ((const unsigned char *)gpt_h, +le32_to_cpu (gpt_h->header_size)); + + memcpy(&gpt_h->header_crc32, &crc32_backup,
sizeof(crc32_backup)); +disk/part_efi.c +9
-0+if (calc_crc32 !=le32_to_cpu (crc32_backup)) { +printf ("%s CRC is wrong: 0x%x != 0x%x\n" , +"GUID Partition Table Header" , +le32_to_cpu (crc32_backup), calc_crc32); +return -1 ; + } + +/* +* Check that the my_lba entry points to the LBA that contains the GPT
disk/part_efi.c +10
-0+*/ +if (le64_to_cpu (gpt_h->my_lba) != lba) { +printf ("GPT: my_lba incorrect: %llX != " LBAF "\n" , +le64_to_cpu (gpt_h->my_lba), + lba); +return -1 ; + } + +/* +* Check that the first_usable_lba and that the
last_usable_lbaaredisk/part_efi.c +4
-0+* within the disk. +*/ +if (le64_to_cpu (gpt_h->first_usable_lba) > lastlba) { + printf("GPT: first_usable_lba incorrect: %llX > "LBAF "\n",
disk/part_efi.c +1
-0+ le64_to_cpu(gpt_h->first_usable_lba),lastlba);
disk/part_efi.c +4
-0+return -1 ; + } +if (le64_to_cpu (gpt_h->last_usable_lba) > lastlba) { + printf("GPT: last_usable_lba incorrect: %llX > "LBAF "\n",
disk/part_efi.c +5
-0+ le64_to_cpu(gpt_h->last_usable_lba), lastlba); +return -1 ; + } + + debug("GPT: first_usable_lba: %llX last_usable_lba: %llXlast lba: "
disk/part_efi.c +16
-0+LBAF "\n" ,le64_to_cpu (gpt_h->first_usable_lba), + le64_to_cpu(gpt_h->last_usable_lba), lastlba); + +return 0 ; +} + +static int validate_gpt_entries (gpt_header *gpt_h,gpt_entry *gpt_e) +{ +uint32_t calc_crc32; + +/* Check the GUID Partition Table Entry Array CRC */ + 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 (calc_crc32 !=
le32_to_cpu(gpt_h->partition_entry_array_crc32)) {disk/part_efi.c +2
-0+ printf("%s: 0x%x != 0x%x\n", + "GUID Partition Table Entry Array CRC iswrong",
+le32_to_cpu(gpt_h->partition_entry_array_crc32),disk/part_efi.c +23
-0+ calc_crc32); +return -1 ; + } + +return 0 ; +} + +static void prepare_backup_gpt_header (gpt_header *gpt_h) +{ +uint32_t calc_crc32; +uint64_t val; + +/* recalculate the values for the Backup GPT Header */ + val =le64_to_cpu (gpt_h->my_lba); + gpt_h->my_lba = gpt_h->alternate_lba; + gpt_h->alternate_lba =cpu_to_le64 (val); + gpt_h->header_crc32 =0 ; + + calc_crc32 =efi_crc32 ((const unsigned char *)gpt_h, +le32_to_cpu (gpt_h->header_size)); + gpt_h->header_crc32 =cpu_to_le32 (calc_crc32); +} +#ifdef CONFIG_EFI_PARTITION /* * Public Functions (include/part.h) @@ -259,7 +358,6 @@ int write_gpt_table(block_dev_desc_t *dev_desc, const int pte_blk_cnt =BLOCK_CNT((gpt_h->num_partition_entries
*sizeof(gpt_entry)),dev_desc); u32calc_crc32;disk/part_efi.c +1
-17-u64 val;debug ("max lba: %x\n" , (u32 ) dev_desc->lba);/* Setup the Protective MBR */ @@ -284,15 +382,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc, != pte_blk_cnt) goto err; -/* recalculate the values for the Backup GPT Header */ - val =le64_to_cpu (gpt_h->my_lba); - gpt_h->my_lba = gpt_h->alternate_lba; - gpt_h->alternate_lba =cpu_to_le64 (val); - gpt_h->header_crc32 =0 ; - - calc_crc32 =efi_crc32 ((const unsigned char *)gpt_h, -le32_to_cpu (gpt_h->header_size)); - gpt_h->header_crc32 =cpu_to_le32 (calc_crc32); +prepare_backup_gpt_header (gpt_h); if (dev_desc->block_write(dev_desc->dev, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba)@@ -511,10 +601,6 @@ static int is_pmbr_valid(legacy_mbr * mbr)static int is_gpt_valid (block_dev_desc_t *dev_desc,u64 lba,gpt_header *pgpt_head,gpt_entry **pgpt_pte) { -u32 crc32_backup =0 ; -u32 calc_crc32; -u64 lastlba; -if (!dev_desc || !pgpt_head) {printf ("%s: Invalid Argument(s)\n" , __func__);return 0 ;@@ -527,55 +613,8 @@ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, return 0; } -/* Check the GPT header signature */ -if (le64_to_cpu (pgpt_head->signature) != GPT_HEADER_SIGNATURE) { - printf("GUID Partition Table Header signature iswrong:"
disk/part_efi.c +0
-8-"0x%llX != 0x%llX\n" , -le64_to_cpu (pgpt_head->signature), - GPT_HEADER_SIGNATURE); -return 0 ; - } - -/* Check the GUID Partition Table CRC */ - memcpy(&crc32_backup, &pgpt_head->header_crc32,
sizeof(crc32_backup));disk/part_efi.c +0
-1- memset(&pgpt_head->header_crc32, 0,
sizeof(pgpt_head->header_crc32)); -disk/part_efi.c +0
-4- calc_crc32 =efi_crc32 ((const unsigned char *)pgpt_head, -le32_to_cpu (pgpt_head->header_size)); - - memcpy(&pgpt_head->header_crc32, &crc32_backup,
sizeof(crc32_backup)); -disk/part_efi.c +0
-8-if (calc_crc32 !=le32_to_cpu (crc32_backup)) { -printf ("GUID Partition Table Header CRC is wrong:" -"0x%x != 0x%x\n" , -le32_to_cpu (crc32_backup), calc_crc32); -return 0 ; - } - -/* Check that the my_lba entry points to the LBA that contains the GPT */
disk/part_efi.c +0
-2-if (le64_to_cpu (pgpt_head->my_lba) != lba) { - printf("GPT: my_lba incorrect: %llX != %" PRIX64"\n",
disk/part_efi.c +1
-2-le64_to_cpu (pgpt_head->my_lba), - lba); + if (validate_gpt_header(pgpt_head, (lbaint_t)lba,
dev_desc->lba)) return 0;disk/part_efi.c +0
-3- } - -/* Check the first_usable_lba and last_usable_lba are within the disk. */
disk/part_efi.c +0
-3- lastlba = (u64 )dev_desc->lba; -if (le64_to_cpu (pgpt_head->first_usable_lba) > lastlba) { - printf("GPT: first_usable_lba incorrect: %llX > %"PRIX64 "\n",
disk/part_efi.c +0
-1- le64_to_cpu(pgpt_head->first_usable_lba),lastlba);
disk/part_efi.c +0
-4-return 0 ; - } -if (le64_to_cpu (pgpt_head->last_usable_lba) > lastlba) { - printf("GPT: last_usable_lba incorrect: %llX > %"PRIX64 "\n",
disk/part_efi.c +0
-1- le64_to_cpu(pgpt_head->last_usable_lba),lastlba);
disk/part_efi.c +0
-4-return 0 ; - } - - debug("GPT: first_usable_lba: %llX last_usable_lba %llX lastlba %"
disk/part_efi.c +0
-9-PRIX64 "\n" ,le64_to_cpu (pgpt_head->first_usable_lba), - le64_to_cpu(pgpt_head->last_usable_lba), lastlba);/* Read and allocate Partition Table Entries */ *pgpt_pte =alloc_read_gpt_entries (dev_desc, pgpt_head);@@ -584,17 +623,7 @@ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, return 0; } -/* Check the GUID Partition Table Entry Array CRC */ - calc_crc32 =efi_crc32 ((const unsigned char *)*pgpt_pte, -le32_to_cpu (pgpt_head->num_partition_entries) * -le32_to_cpu (pgpt_head->sizeof_partition_entry)); - -if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) { - printf("GUID Partition Table Entry Array CRC iswrong:"
disk/part_efi.c +0
-2- "0x%x != 0x%x\n", -
le32_to_cpu(pgpt_head->partition_entry_array_crc32),
disk/part_efi.c static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, · line 629
Quoted 6 lines
disk/part_efi.c +1
-2- calc_crc32); - +if (validate_gpt_entries (pgpt_head, *pgpt_pte)) {free (*pgpt_pte);return 0 ; }
Test HW: Exynos4412 - trats2
To Marek:
This patch cleanly applies to master (SHA1:b9206e61f3d87535ac4f4b0b858e674fd1edfeaf) not u-boot-usb.
Therefore I cannot apply it to u-boot-usb based -dfu tree. We can either wait up the moment when -dfu get in sync with mainline or apply this patch to mainline directly.
Signature · 5 lines
Best regards, Lukasz Majewski Samsung R&D Institute Poland (SRPOL) | Linux Platform Group