The restoration of GPT table (both primary and secondary) is now possible. Simple GUID generation is supported.
Signed-off-by: Lukasz Majewski <l.majew...@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.p...@samsung.com> --- Changes for v2: - Move GPT Header and Page Table Entries generation code to cmd_gpt.c - Provide clean API to use set_gpt_table function for GPT restoration on a block device --- disk/part_efi.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/part.h | 3 ++ 2 files changed, 102 insertions(+), 0 deletions(-) diff --git a/disk/part_efi.c b/disk/part_efi.c index d4c61d2..531c7ad 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -403,4 +403,103 @@ static int is_pte_valid(gpt_entry * pte) return 1; } } + +/** + * set_protective_mbr(): Set the EFI protective MBR + * @param dev_desc - block device descriptor + * + * @return - zero on success, otherwise error + */ +static int set_protective_mbr(block_dev_desc_t *dev_desc) +{ + legacy_mbr p_mbr; + + /* Setup the Protective MBR */ + memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr)); + /* Append signature */ + p_mbr.signature = MSDOS_MBR_SIGNATURE; + p_mbr.partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; + p_mbr.partition_record[0].start_sect = 1; + p_mbr.partition_record[0].nr_sects = (u32) dev_desc->lba; + + /* Write MBR sector to the MMC device */ + if (dev_desc->block_write(dev_desc->dev, 0, 1, &p_mbr) != 1) { + printf("** Can't write to device %d **\n", + dev_desc->dev); + return -1; + } + + return 0; +} + +/** + * set_gpt_table() - Restore the GUID Partition Table + * + * @param dev_desc - block device descriptor + * @param parts - number of partitions + * @param size - pointer to array with each partition size + * @param name - pointer to array with each partition name + * + * @return - zero on success, otherwise error + */ +int set_gpt_table(block_dev_desc_t *dev_desc, + gpt_header *gpt_h, gpt_entry *gpt_e) +{ + const int pte_blk_num = (GPT_ENTRY_NUMBERS * sizeof(gpt_entry)) / + dev_desc->blksz; + u32 calc_crc32; + u64 val; + + debug("max lba: %x\n", (u32) dev_desc->lba); + + /* Setup the Protective MBR */ + if (set_protective_mbr(dev_desc) < 0) + goto err; + + /* Generate CRC for the Primary GPT Header */ + 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)); + gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32); + + 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); + + /* Write the First GPT to the block right after the Legacy MBR */ + if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1) + goto err; + + if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e) + != pte_blk_num) + goto err; + + /* recalculate the values for the Second 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); + + /* Write the Second GPT that is located at the end of the disk */ + if (dev_desc->block_write(dev_desc->dev, + le32_to_cpu(gpt_h->last_usable_lba + 1), + pte_blk_num, gpt_e) != pte_blk_num) + goto err; + + if (dev_desc->block_write(dev_desc->dev, + le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1) + goto err; + + printf("GPT successfully written to block device!\n"); + return 0; + + err: + printf("** Can't write to device %d **\n", + dev_desc->dev); + return -1; +} #endif diff --git a/include/part.h b/include/part.h index e1478f4..fc34ed2 100644 --- a/include/part.h +++ b/include/part.h @@ -157,10 +157,13 @@ int test_part_amiga (block_dev_desc_t *dev_desc); #endif #ifdef CONFIG_EFI_PARTITION +#include <part_efi.h> /* disk/part_efi.c */ int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); void print_part_efi (block_dev_desc_t *dev_desc); int test_part_efi (block_dev_desc_t *dev_desc); +int set_gpt_table(block_dev_desc_t *dev_desc, + gpt_header *gpt_h, gpt_entry *gpt_e); #endif #endif /* _PART_H */ -- 1.7.2.3 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot