X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=disk%2Fpart_efi.c;h=71c3cb3f78d9fbffae660c019cfa54d3bb4ef7e1;hb=723806cc5bea9f8b37323dfd7568603f99af6a06;hp=77bdfcbce5eafa694f15e67f1bda009597d579c7;hpb=084bf4c244ce98ab1ee7b590d44471fa5cae25f6;p=u-boot diff --git a/disk/part_efi.c b/disk/part_efi.c index 77bdfcbce5..71c3cb3f78 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -13,11 +13,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -171,23 +173,50 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h) gpt_h->header_crc32 = cpu_to_le32(calc_crc32); } -#ifdef CONFIG_EFI_PARTITION +#if CONFIG_IS_ENABLED(EFI_PARTITION) /* * Public Functions (include/part.h) */ +/* + * UUID is displayed as 32 hexadecimal digits, in 5 groups, + * separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters + */ +int get_disk_guid(struct blk_desc * dev_desc, char *guid) +{ + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); + gpt_entry *gpt_pte = NULL; + unsigned char *guid_bin; + + /* This function validates AND fills in the GPT header and PTE */ + if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA, + gpt_head, &gpt_pte) != 1) { + printf("%s: *** ERROR: Invalid GPT ***\n", __func__); + if (is_gpt_valid(dev_desc, dev_desc->lba - 1, + gpt_head, &gpt_pte) != 1) { + printf("%s: *** ERROR: Invalid Backup GPT ***\n", + __func__); + return -EINVAL; + } else { + printf("%s: *** Using Backup GPT ***\n", + __func__); + } + } + + guid_bin = gpt_head->disk_guid.b; + uuid_bin_to_str(guid_bin, guid, UUID_STR_FORMAT_GUID); + + return 0; +} + void part_print_efi(struct blk_desc *dev_desc) { ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); gpt_entry *gpt_pte = NULL; int i = 0; - char uuid[37]; + char uuid[UUID_STR_LEN + 1]; unsigned char *uuid_bin; - if (!dev_desc) { - printf("%s: Invalid Argument(s)\n", __func__); - return; - } /* This function validates AND fills in the GPT header and PTE */ if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA, gpt_head, &gpt_pte) != 1) { @@ -244,7 +273,7 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part, gpt_entry *gpt_pte = NULL; /* "part" argument must be at least 1 */ - if (!dev_desc || !info || part < 1) { + if (part < 1) { printf("%s: Invalid Argument(s)\n", __func__); return -1; } @@ -283,7 +312,7 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part, print_efiname(&gpt_pte[part - 1])); strcpy((char *)info->type, "U-Boot"); info->bootable = is_bootable(&gpt_pte[part - 1]); -#ifdef CONFIG_PARTITION_UUIDS +#if CONFIG_IS_ENABLED(PARTITION_UUIDS) uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid, UUID_STR_FORMAT_GUID); #endif @@ -300,25 +329,6 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part, return 0; } -int part_get_info_efi_by_name(struct blk_desc *dev_desc, - const char *name, disk_partition_t *info) -{ - int ret; - int i; - for (i = 1; i < GPT_ENTRY_NUMBERS; i++) { - ret = part_get_info_efi(dev_desc, i, info); - if (ret != 0) { - /* no more entries in table */ - return -1; - } - if (strcmp(name, (const char *)info->name) == 0) { - /* matched */ - return 0; - } - } - return -2; -} - static int part_test_efi(struct blk_desc *dev_desc) { ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz); @@ -347,6 +357,13 @@ static int set_protective_mbr(struct blk_desc *dev_desc) printf("%s: calloc failed!\n", __func__); return -1; } + + /* Read MBR to backup boot code if it exists */ + if (blk_dread(dev_desc, 0, 1, p_mbr) != 1) { + error("** Can't read from device %d **\n", dev_desc->devnum); + return -1; + } + /* Append signature */ p_mbr->signature = MSDOS_MBR_SIGNATURE; p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; @@ -389,8 +406,8 @@ int write_gpt_table(struct blk_desc *dev_desc, if (blk_dwrite(dev_desc, 1, 1, gpt_h) != 1) goto err; - if (blk_dwrite(dev_desc, 2, pte_blk_cnt, gpt_e) - != pte_blk_cnt) + if (blk_dwrite(dev_desc, le64_to_cpu(gpt_h->partition_entry_lba), + pte_blk_cnt, gpt_e) != pte_blk_cnt) goto err; prepare_backup_gpt_header(gpt_h); @@ -420,7 +437,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, le64_to_cpu(gpt_h->last_usable_lba); int i, k; size_t efiname_len, dosname_len; -#ifdef CONFIG_PARTITION_UUIDS +#if CONFIG_IS_ENABLED(PARTITION_UUIDS) char *str_uuid; unsigned char *bin_uuid; #endif @@ -443,7 +460,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, gpt_e[i].starting_lba = cpu_to_le64(offset); offset += partitions[i].size; } - if (offset >= last_usable_lba) { + if (offset > (last_usable_lba + 1)) { printf("Partitions layout exceds disk size\n"); return -1; } @@ -475,11 +492,11 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, &PARTITION_BASIC_DATA_GUID, 16); #endif -#ifdef CONFIG_PARTITION_UUIDS +#if CONFIG_IS_ENABLED(PARTITION_UUIDS) str_uuid = partitions[i].uuid; bin_uuid = gpt_e[i].unique_partition_guid.b; - if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_STD)) { + if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_GUID)) { printf("Partition no. %d: invalid guid: %s\n", i, str_uuid); return -1; @@ -514,6 +531,49 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, return 0; } +static uint32_t partition_entries_offset(struct blk_desc *dev_desc) +{ + uint32_t offset_blks = 2; + int __maybe_unused config_offset; + +#if defined(CONFIG_EFI_PARTITION_ENTRIES_OFF) + /* + * Some architectures require their SPL loader at a fixed + * address within the first 16KB of the disk. To avoid an + * overlap with the partition entries of the EFI partition + * table, the first safe offset (in bytes, from the start of + * the disk) for the entries can be set in + * CONFIG_EFI_PARTITION_ENTRIES_OFF. + */ + offset_blks = + PAD_TO_BLOCKSIZE(CONFIG_EFI_PARTITION_ENTRIES_OFF, dev_desc); +#endif + +#if defined(CONFIG_OF_CONTROL) + /* + * Allow the offset of the first partition entires (in bytes + * from the start of the device) to be specified as a property + * of the device tree '/config' node. + */ + config_offset = fdtdec_get_config_int(gd->fdt_blob, + "u-boot,efi-partition-entries-offset", + -EINVAL); + if (config_offset != -EINVAL) + offset_blks = PAD_TO_BLOCKSIZE(config_offset, dev_desc); +#endif + + debug("efi: partition entries offset (in blocks): %d\n", offset_blks); + + /* + * The earliest LBA this can be at is LBA#2 (i.e. right behind + * the (protective) MBR and the GPT header. + */ + if (offset_blks < 2) + offset_blks = 2; + + return offset_blks; +} + int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h, char *str_guid, int parts_count) { @@ -522,9 +582,11 @@ int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h, gpt_h->header_size = cpu_to_le32(sizeof(gpt_header)); gpt_h->my_lba = cpu_to_le64(1); gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1); - gpt_h->first_usable_lba = cpu_to_le64(34); gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34); - gpt_h->partition_entry_lba = cpu_to_le64(2); + gpt_h->partition_entry_lba = + cpu_to_le64(partition_entries_offset(dev_desc)); + gpt_h->first_usable_lba = + cpu_to_le64(le64_to_cpu(gpt_h->partition_entry_lba) + 32); gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry)); gpt_h->header_crc32 = 0; @@ -659,6 +721,10 @@ int gpt_verify_partitions(struct blk_desc *dev_desc, (unsigned long long)partitions[i].size); if (le64_to_cpu(gpt_part_size) != partitions[i].size) { + /* We do not check the extend partition size */ + if ((i == parts - 1) && (partitions[i].size == 0)) + continue; + error("Partition %s size: %llu does not match %llu!\n", efi_str, (unsigned long long)gpt_part_size, (unsigned long long)partitions[i].size); @@ -890,9 +956,10 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc, count = le32_to_cpu(pgpt_head->num_partition_entries) * le32_to_cpu(pgpt_head->sizeof_partition_entry); - debug("%s: count = %u * %u = %zu\n", __func__, + debug("%s: count = %u * %u = %lu\n", __func__, (u32) le32_to_cpu(pgpt_head->num_partition_entries), - (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count); + (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), + (ulong)count); /* Allocate memory for PTE, remember to FREE */ if (count != 0) { @@ -901,9 +968,8 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc, } if (count == 0 || pte == NULL) { - printf("%s: ERROR: Can't allocate 0x%zX " - "bytes for GPT Entries\n", - __func__, count); + printf("%s: ERROR: Can't allocate %#lX bytes for GPT Entries\n", + __func__, (ulong)count); return NULL; } @@ -958,6 +1024,7 @@ static int is_pte_valid(gpt_entry * pte) U_BOOT_PART_TYPE(a_efi) = { .name = "EFI", .part_type = PART_TYPE_EFI, + .max_entries = GPT_ENTRY_NUMBERS, .get_info = part_get_info_ptr(part_get_info_efi), .print = part_print_ptr(part_print_efi), .test = part_test_efi,