"Das U-Boot" Source Tree
at master 1216 lines 32 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2008 RuggedCom, Inc. 4 * Richard Retanubun <RichardRetanubun@RuggedCom.com> 5 */ 6 7/* 8 * NOTE: 9 * when CONFIG_SYS_64BIT_LBA is not defined, lbaint_t is 32 bits; this 10 * limits the maximum size of addressable storage to < 2 tebibytes 11 */ 12 13#define LOG_CATEGORY LOGC_FS 14 15#include <blk.h> 16#include <log.h> 17#include <part.h> 18#include <u-boot/uuid.h> 19#include <asm/cache.h> 20#include <asm/global_data.h> 21#include <asm/unaligned.h> 22#include <command.h> 23#include <fdtdec.h> 24#include <ide.h> 25#include <malloc.h> 26#include <memalign.h> 27#include <part_efi.h> 28#include <dm/ofnode.h> 29#include <linux/compiler.h> 30#include <linux/ctype.h> 31#include <linux/printk.h> 32#include <u-boot/crc.h> 33 34/* GUID for basic data partitons */ 35#if CONFIG_IS_ENABLED(EFI_PARTITION) 36static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID; 37#endif 38 39/** 40 * efi_crc32() - EFI version of crc32 function 41 * @buf: buffer to calculate crc32 of 42 * @len - length of buf 43 * 44 * Description: Returns EFI-style CRC32 value for @buf 45 */ 46static inline u32 efi_crc32(const void *buf, u32 len) 47{ 48 return crc32(0, buf, len); 49} 50 51/* 52 * Private function prototypes 53 */ 54 55static int pmbr_part_valid(struct partition *part); 56static int is_pmbr_valid(legacy_mbr * mbr); 57static int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head, 58 gpt_entry **pgpt_pte); 59static gpt_entry *alloc_read_gpt_entries(struct blk_desc *desc, 60 gpt_header *pgpt_head); 61static int is_pte_valid(gpt_entry * pte); 62static int find_valid_gpt(struct blk_desc *desc, gpt_header *gpt_head, 63 gpt_entry **pgpt_pte); 64 65static char *print_efiname(gpt_entry *pte) 66{ 67 static char name[PARTNAME_SZ + 1]; 68 int i; 69 for (i = 0; i < PARTNAME_SZ; i++) { 70 u8 c; 71 c = pte->partition_name[i] & 0xff; 72 c = (c && !isprint(c)) ? '.' : c; 73 name[i] = c; 74 } 75 name[PARTNAME_SZ] = 0; 76 return name; 77} 78 79static const efi_guid_t system_guid = PARTITION_SYSTEM_GUID; 80 81static int get_bootable(gpt_entry *p) 82{ 83 int ret = 0; 84 85 if (!memcmp(&p->partition_type_guid, &system_guid, sizeof(efi_guid_t))) 86 ret |= PART_EFI_SYSTEM_PARTITION; 87 if (p->attributes.fields.legacy_bios_bootable) 88 ret |= PART_BOOTABLE; 89 return ret; 90} 91 92static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba, 93 lbaint_t lastlba) 94{ 95 uint32_t crc32_backup = 0; 96 uint32_t calc_crc32; 97 98 /* Check the GPT header signature */ 99 if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE_UBOOT) { 100 log_debug("%s signature is wrong: %#llX != %#llX\n", 101 "GUID Partition Table Header", 102 le64_to_cpu(gpt_h->signature), 103 GPT_HEADER_SIGNATURE_UBOOT); 104 return -1; 105 } 106 107 /* Check the GUID Partition Table CRC */ 108 memcpy(&crc32_backup, &gpt_h->header_crc32, sizeof(crc32_backup)); 109 memset(&gpt_h->header_crc32, 0, sizeof(gpt_h->header_crc32)); 110 111 calc_crc32 = efi_crc32((const unsigned char *)gpt_h, 112 le32_to_cpu(gpt_h->header_size)); 113 114 memcpy(&gpt_h->header_crc32, &crc32_backup, sizeof(crc32_backup)); 115 116 if (calc_crc32 != le32_to_cpu(crc32_backup)) { 117 log_debug("%s: CRC is wrong: %#x != %#x\n", 118 "GUID Partition Table Header", 119 le32_to_cpu(crc32_backup), calc_crc32); 120 return -1; 121 } 122 123 /* 124 * Check that the my_lba entry points to the LBA that contains the GPT 125 */ 126 if (le64_to_cpu(gpt_h->my_lba) != lba) { 127 log_debug("GPT: my_lba incorrect: %llX != " LBAF "\n", 128 le64_to_cpu(gpt_h->my_lba), lba); 129 return -1; 130 } 131 132 /* 133 * Check that the first_usable_lba and that the last_usable_lba are 134 * within the disk. 135 */ 136 if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) { 137 log_debug("GPT: first_usable_lba incorrect: %llX > " LBAF "\n", 138 le64_to_cpu(gpt_h->first_usable_lba), lastlba); 139 return -1; 140 } 141 if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) { 142 log_debug("GPT: last_usable_lba incorrect: %llX > " LBAF "\n", 143 le64_to_cpu(gpt_h->last_usable_lba), lastlba); 144 return -1; 145 } 146 147 debug("GPT: first_usable_lba: %llX last_usable_lba: %llX last lba: " 148 LBAF "\n", le64_to_cpu(gpt_h->first_usable_lba), 149 le64_to_cpu(gpt_h->last_usable_lba), lastlba); 150 151 return 0; 152} 153 154static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e) 155{ 156 uint32_t calc_crc32; 157 158 /* Check the GUID Partition Table Entry Array CRC */ 159 calc_crc32 = efi_crc32((const unsigned char *)gpt_e, 160 le32_to_cpu(gpt_h->num_partition_entries) * 161 le32_to_cpu(gpt_h->sizeof_partition_entry)); 162 163 if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) { 164 log_debug("%s: %#x != %#x\n", 165 "GUID Partition Table Entry Array CRC is wrong", 166 le32_to_cpu(gpt_h->partition_entry_array_crc32), 167 calc_crc32); 168 return -1; 169 } 170 171 return 0; 172} 173 174static void prepare_backup_gpt_header(gpt_header *gpt_h) 175{ 176 uint32_t calc_crc32; 177 uint64_t val; 178 179 /* recalculate the values for the Backup GPT Header */ 180 val = le64_to_cpu(gpt_h->my_lba); 181 gpt_h->my_lba = gpt_h->alternate_lba; 182 gpt_h->alternate_lba = cpu_to_le64(val); 183 gpt_h->partition_entry_lba = 184 cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1); 185 gpt_h->header_crc32 = 0; 186 187 calc_crc32 = efi_crc32((const unsigned char *)gpt_h, 188 le32_to_cpu(gpt_h->header_size)); 189 gpt_h->header_crc32 = cpu_to_le32(calc_crc32); 190} 191 192#if CONFIG_IS_ENABLED(EFI_PARTITION) 193/* 194 * Public Functions (include/part.h) 195 */ 196 197/* 198 * UUID is displayed as 32 hexadecimal digits, in 5 groups, 199 * separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters 200 */ 201int get_disk_guid(struct blk_desc *desc, char *guid) 202{ 203 ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz); 204 gpt_entry *gpt_pte = NULL; 205 unsigned char *guid_bin; 206 207 /* This function validates AND fills in the GPT header and PTE */ 208 if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1) 209 return -EINVAL; 210 211 guid_bin = gpt_head->disk_guid.b; 212 uuid_bin_to_str(guid_bin, guid, UUID_STR_FORMAT_GUID); 213 214 /* Remember to free pte */ 215 free(gpt_pte); 216 return 0; 217} 218 219static void __maybe_unused part_print_efi(struct blk_desc *desc) 220{ 221 ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz); 222 gpt_entry *gpt_pte = NULL; 223 int i = 0; 224 unsigned char *uuid; 225 226 /* This function validates AND fills in the GPT header and PTE */ 227 if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1) 228 return; 229 230 debug("%s: gpt-entry at %p\n", __func__, gpt_pte); 231 232 printf("Part\tStart LBA\tEnd LBA\t\tName\n"); 233 printf("\tAttributes\n"); 234 printf("\tType GUID\n"); 235 printf("\tPartition GUID\n"); 236 237 for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) { 238 /* Skip invalid PTE */ 239 if (!is_pte_valid(&gpt_pte[i])) 240 continue; 241 242 printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1), 243 le64_to_cpu(gpt_pte[i].starting_lba), 244 le64_to_cpu(gpt_pte[i].ending_lba), 245 print_efiname(&gpt_pte[i])); 246 printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw); 247 uuid = (unsigned char *)gpt_pte[i].partition_type_guid.b; 248 if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) 249 printf("\ttype:\t%pUl\n\t\t(%pUs)\n", uuid, uuid); 250 else 251 printf("\ttype:\t%pUl\n", uuid); 252 uuid = (unsigned char *)gpt_pte[i].unique_partition_guid.b; 253 printf("\tguid:\t%pUl\n", uuid); 254 } 255 256 /* Remember to free pte */ 257 free(gpt_pte); 258 return; 259} 260 261static int __maybe_unused part_get_info_efi(struct blk_desc *desc, int part, 262 struct disk_partition *info) 263{ 264 ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz); 265 gpt_entry *gpt_pte = NULL; 266 267 /* "part" argument must be at least 1 */ 268 if (part < 1) { 269 log_debug("Invalid Argument(s)\n"); 270 return -EINVAL; 271 } 272 273 /* This function validates AND fills in the GPT header and PTE */ 274 if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1) 275 return -EINVAL; 276 277 if (part > le32_to_cpu(gpt_head->num_partition_entries) || 278 !is_pte_valid(&gpt_pte[part - 1])) { 279 log_debug("Invalid partition number %d\n", part); 280 free(gpt_pte); 281 return -EPERM; 282 } 283 284 /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */ 285 info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba); 286 /* The ending LBA is inclusive, to calculate size, add 1 to it */ 287 info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1 288 - info->start; 289 info->blksz = desc->blksz; 290 291 snprintf((char *)info->name, sizeof(info->name), "%s", 292 print_efiname(&gpt_pte[part - 1])); 293 strcpy((char *)info->type, "U-Boot"); 294 info->bootable = get_bootable(&gpt_pte[part - 1]); 295 info->type_flags = gpt_pte[part - 1].attributes.fields.type_guid_specific; 296 if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) { 297 uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, 298 (char *)disk_partition_uuid(info), 299 UUID_STR_FORMAT_GUID); 300 } 301 if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) { 302 uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b, 303 (char *)disk_partition_type_guid(info), 304 UUID_STR_FORMAT_GUID); 305 } 306 307 log_debug("start 0x" LBAF ", size 0x" LBAF ", name %s\n", info->start, 308 info->size, info->name); 309 310 /* Remember to free pte */ 311 free(gpt_pte); 312 return 0; 313} 314 315static int part_test_efi(struct blk_desc *desc) 316{ 317 ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, desc->blksz); 318 319 /* Read legacy MBR from block 0 and validate it */ 320 if ((blk_dread(desc, 0, 1, (ulong *)legacymbr) != 1) 321 || (is_pmbr_valid(legacymbr) != 1)) { 322 /* 323 * TegraPT is compatible with EFI part, but it 324 * cannot pass the Protective MBR check. Skip it 325 * if CONFIG_TEGRA_PARTITION is enabled and the 326 * device in question is eMMC. 327 */ 328 if (IS_ENABLED(CONFIG_TEGRA_PARTITION)) 329 if (!is_pmbr_valid(legacymbr) && 330 desc->uclass_id == UCLASS_MMC && 331 !desc->devnum) 332 return 0; 333 return -1; 334 } 335 return 0; 336} 337 338/** 339 * set_protective_mbr(): Set the EFI protective MBR 340 * @param desc - block device descriptor 341 * 342 * Return: - zero on success, otherwise error 343 */ 344static int set_protective_mbr(struct blk_desc *desc) 345{ 346 /* Setup the Protective MBR */ 347 ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, p_mbr, 1, desc->blksz); 348 if (p_mbr == NULL) { 349 log_debug("calloc failed!\n"); 350 return -ENOMEM; 351 } 352 353 /* Read MBR to backup boot code if it exists */ 354 if (blk_dread(desc, 0, 1, p_mbr) != 1) { 355 log_debug("** Can't read from device %d **\n", 356 desc->devnum); 357 return -EIO; 358 } 359 360 /* Clear all data in MBR except of backed up boot code */ 361 memset((char *)p_mbr + MSDOS_MBR_BOOT_CODE_SIZE, 0, sizeof(*p_mbr) - 362 MSDOS_MBR_BOOT_CODE_SIZE); 363 364 /* Append signature */ 365 p_mbr->signature = MSDOS_MBR_SIGNATURE; 366 p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 367 p_mbr->partition_record[0].start_sect = 1; 368 p_mbr->partition_record[0].nr_sects = (u32)desc->lba - 1; 369 370 /* Write MBR sector to the MMC device */ 371 if (blk_dwrite(desc, 0, 1, p_mbr) != 1) { 372 log_debug("** Can't write to device %d **\n", desc->devnum); 373 return -EIO; 374 } 375 376 return 0; 377} 378 379int write_gpt_table(struct blk_desc *desc, gpt_header *gpt_h, gpt_entry *gpt_e) 380{ 381 const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries 382 * sizeof(gpt_entry)), desc); 383 u32 calc_crc32; 384 385 debug("max lba: %x\n", (u32)desc->lba); 386 /* Setup the Protective MBR */ 387 if (set_protective_mbr(desc) < 0) 388 goto err; 389 390 /* Generate CRC for the Primary GPT Header */ 391 calc_crc32 = efi_crc32((const unsigned char *)gpt_e, 392 le32_to_cpu(gpt_h->num_partition_entries) * 393 le32_to_cpu(gpt_h->sizeof_partition_entry)); 394 gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32); 395 396 calc_crc32 = efi_crc32((const unsigned char *)gpt_h, 397 le32_to_cpu(gpt_h->header_size)); 398 gpt_h->header_crc32 = cpu_to_le32(calc_crc32); 399 400 /* Write the First GPT to the block right after the Legacy MBR */ 401 if (blk_dwrite(desc, 1, 1, gpt_h) != 1) 402 goto err; 403 404 if (blk_dwrite(desc, le64_to_cpu(gpt_h->partition_entry_lba), 405 pte_blk_cnt, gpt_e) != pte_blk_cnt) 406 goto err; 407 408 prepare_backup_gpt_header(gpt_h); 409 410 if (blk_dwrite(desc, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba) 411 + 1, pte_blk_cnt, gpt_e) != pte_blk_cnt) 412 goto err; 413 414 if (blk_dwrite(desc, (lbaint_t)le64_to_cpu(gpt_h->my_lba), 1, 415 gpt_h) != 1) 416 goto err; 417 418 debug("GPT successfully written to block device!\n"); 419 return 0; 420 421 err: 422 log_debug("** Can't write to device %d **\n", desc->devnum); 423 return -EIO; 424} 425 426int gpt_fill_pte(struct blk_desc *desc, 427 gpt_header *gpt_h, gpt_entry *gpt_e, 428 struct disk_partition *partitions, int parts) 429{ 430 lbaint_t offset = (lbaint_t)le64_to_cpu(gpt_h->first_usable_lba); 431 lbaint_t last_usable_lba = (lbaint_t) 432 le64_to_cpu(gpt_h->last_usable_lba); 433 int i, k; 434 size_t efiname_len, dosname_len; 435 unsigned char *bin_uuid; 436#ifdef CONFIG_PARTITION_TYPE_GUID 437 char *str_type_guid; 438 unsigned char *bin_type_guid; 439#endif 440 size_t hdr_start = gpt_h->my_lba; 441 size_t hdr_end = hdr_start + 1; 442 443 size_t pte_start = gpt_h->partition_entry_lba; 444 size_t pte_end = pte_start + 445 gpt_h->num_partition_entries * gpt_h->sizeof_partition_entry / 446 desc->blksz; 447 448 for (i = 0; i < parts; i++) { 449 /* partition starting lba */ 450 lbaint_t start = partitions[i].start; 451 lbaint_t size = partitions[i].size; 452 453 if (start) { 454 offset = start + size; 455 } else { 456 start = offset; 457 offset += size; 458 } 459 460 /* 461 * If our partition overlaps with either the GPT 462 * header, or the partition entry, reject it. 463 */ 464 if (((start < hdr_end && hdr_start < (start + size)) || 465 (start < pte_end && pte_start < (start + size)))) { 466 log_debug("Partition overlap\n"); 467 return -ENOSPC; 468 } 469 470 gpt_e[i].starting_lba = cpu_to_le64(start); 471 472 if (offset > (last_usable_lba + 1)) { 473 log_debug("Partitions layout exceeds disk size\n"); 474 return -E2BIG; 475 } 476 /* partition ending lba */ 477 if ((i == parts - 1) && (size == 0)) 478 /* extend the last partition to maximuim */ 479 gpt_e[i].ending_lba = gpt_h->last_usable_lba; 480 else 481 gpt_e[i].ending_lba = cpu_to_le64(offset - 1); 482 483#ifdef CONFIG_PARTITION_TYPE_GUID 484 str_type_guid = partitions[i].type_guid; 485 bin_type_guid = gpt_e[i].partition_type_guid.b; 486 if (strlen(str_type_guid)) { 487 if (uuid_str_to_bin(str_type_guid, bin_type_guid, 488 UUID_STR_FORMAT_GUID)) { 489 log_debug("Partition no. %d: invalid type guid: %s\n", 490 i, str_type_guid); 491 return -EINVAL; 492 } 493 } else { 494 /* default partition type GUID */ 495 memcpy(bin_type_guid, 496 &partition_basic_data_guid, 16); 497 } 498#else 499 /* partition type GUID */ 500 memcpy(gpt_e[i].partition_type_guid.b, 501 &partition_basic_data_guid, 16); 502#endif 503 504 if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) { 505 const char *str_uuid; 506 507 str_uuid = disk_partition_uuid(&partitions[i]); 508 bin_uuid = gpt_e[i].unique_partition_guid.b; 509 510 if (uuid_str_to_bin(str_uuid, bin_uuid, 511 UUID_STR_FORMAT_GUID)) { 512 log_debug("Partition no. %d: invalid guid: %s\n", 513 i, str_uuid); 514 return -EINVAL; 515 } 516 } 517 518 /* partition attributes */ 519 memset(&gpt_e[i].attributes, 0, 520 sizeof(gpt_entry_attributes)); 521 522 if (partitions[i].bootable & PART_BOOTABLE) 523 gpt_e[i].attributes.fields.legacy_bios_bootable = 1; 524 525 /* partition name */ 526 efiname_len = sizeof(gpt_e[i].partition_name) 527 / sizeof(efi_char16_t); 528 dosname_len = sizeof(partitions[i].name); 529 530 memset(gpt_e[i].partition_name, 0, 531 sizeof(gpt_e[i].partition_name)); 532 533 for (k = 0; k < min(dosname_len, efiname_len); k++) 534 gpt_e[i].partition_name[k] = 535 (efi_char16_t)(partitions[i].name[k]); 536 537 debug("%s: name: %s offset[%d]: 0x" LBAF 538 " size[%d]: 0x" LBAF "\n", 539 __func__, partitions[i].name, i, 540 offset, i, size); 541 } 542 543 return 0; 544} 545 546static uint32_t partition_entries_offset(struct blk_desc *desc) 547{ 548 uint32_t offset_blks = 2; 549 uint32_t __maybe_unused offset_bytes; 550 int __maybe_unused config_offset; 551 552#if defined(CONFIG_EFI_PARTITION_ENTRIES_OFF) 553 /* 554 * Some architectures require their SPL loader at a fixed 555 * address within the first 16KB of the disk. To avoid an 556 * overlap with the partition entries of the EFI partition 557 * table, the first safe offset (in bytes, from the start of 558 * the disk) for the entries can be set in 559 * CONFIG_EFI_PARTITION_ENTRIES_OFF. 560 */ 561 offset_bytes = 562 PAD_TO_BLOCKSIZE(CONFIG_EFI_PARTITION_ENTRIES_OFF, desc); 563 offset_blks = offset_bytes / desc->blksz; 564#endif 565 566#if defined(CONFIG_OF_CONTROL) 567 /* 568 * Allow the offset of the first partition entires (in bytes 569 * from the start of the device) to be specified as a property 570 * of the device tree '/config' node. 571 */ 572 config_offset = ofnode_conf_read_int( 573 "u-boot,efi-partition-entries-offset", -EINVAL); 574 if (config_offset != -EINVAL) { 575 offset_bytes = PAD_TO_BLOCKSIZE(config_offset, desc); 576 offset_blks = offset_bytes / desc->blksz; 577 } 578#endif 579 580 debug("efi: partition entries offset (in blocks): %d\n", offset_blks); 581 582 /* 583 * The earliest LBA this can be at is LBA#2 (i.e. right behind 584 * the (protective) MBR and the GPT header. 585 */ 586 if (offset_blks < 2) 587 offset_blks = 2; 588 589 return offset_blks; 590} 591 592int gpt_fill_header(struct blk_desc *desc, gpt_header *gpt_h, char *str_guid, 593 int parts_count) 594{ 595 gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE_UBOOT); 596 gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 597 gpt_h->header_size = cpu_to_le32(sizeof(gpt_header)); 598 gpt_h->my_lba = cpu_to_le64(1); 599 gpt_h->alternate_lba = cpu_to_le64(desc->lba - 1); 600 gpt_h->last_usable_lba = cpu_to_le64(desc->lba - 34); 601 gpt_h->partition_entry_lba = 602 cpu_to_le64(partition_entries_offset(desc)); 603 gpt_h->first_usable_lba = 604 cpu_to_le64(le64_to_cpu(gpt_h->partition_entry_lba) + 32); 605 gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 606 gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry)); 607 gpt_h->header_crc32 = 0; 608 gpt_h->partition_entry_array_crc32 = 0; 609 610 if (uuid_str_to_bin(str_guid, gpt_h->disk_guid.b, UUID_STR_FORMAT_GUID)) 611 return -1; 612 613 return 0; 614} 615 616int gpt_restore(struct blk_desc *desc, char *str_disk_guid, 617 struct disk_partition *partitions, int parts_count) 618{ 619 gpt_header *gpt_h; 620 gpt_entry *gpt_e; 621 int ret, size; 622 623 size = PAD_TO_BLOCKSIZE(sizeof(gpt_header), desc); 624 gpt_h = malloc_cache_aligned(size); 625 if (gpt_h == NULL) { 626 log_debug("calloc failed!\n"); 627 return -ENOMEM; 628 } 629 memset(gpt_h, 0, size); 630 631 size = PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry), 632 desc); 633 gpt_e = malloc_cache_aligned(size); 634 if (gpt_e == NULL) { 635 log_debug("calloc failed!\n"); 636 free(gpt_h); 637 return -ENOMEM; 638 } 639 memset(gpt_e, 0, size); 640 641 /* Generate Primary GPT header (LBA1) */ 642 ret = gpt_fill_header(desc, gpt_h, str_disk_guid, parts_count); 643 if (ret) 644 goto err; 645 646 /* Generate partition entries */ 647 ret = gpt_fill_pte(desc, gpt_h, gpt_e, partitions, parts_count); 648 if (ret) 649 goto err; 650 651 /* Write GPT partition table */ 652 ret = write_gpt_table(desc, gpt_h, gpt_e); 653 654err: 655 free(gpt_e); 656 free(gpt_h); 657 return ret; 658} 659 660/** 661 * gpt_convert_efi_name_to_char() - convert u16 string to char string 662 * 663 * TODO: this conversion only supports ANSI characters 664 * 665 * @s: target buffer 666 * @es: u16 string to be converted 667 * @n: size of target buffer 668 */ 669static void gpt_convert_efi_name_to_char(char *s, void *es, int n) 670{ 671 char *ess = es; 672 int i, j; 673 674 memset(s, '\0', n); 675 676 for (i = 0, j = 0; j < n; i += 2, j++) { 677 s[j] = ess[i]; 678 if (!ess[i]) 679 return; 680 } 681} 682 683int gpt_verify_headers(struct blk_desc *desc, gpt_header *gpt_head, 684 gpt_entry **gpt_pte) 685{ 686 /* 687 * This function validates AND 688 * fills in the GPT header and PTE 689 */ 690 if (is_gpt_valid(desc, 691 GPT_PRIMARY_PARTITION_TABLE_LBA, 692 gpt_head, gpt_pte) != 1) { 693 log_debug("Invalid GPT\n"); 694 return -1; 695 } 696 697 /* Free pte before allocating again */ 698 free(*gpt_pte); 699 700 /* 701 * Check that the alternate_lba entry points to the last LBA 702 */ 703 if (le64_to_cpu(gpt_head->alternate_lba) != (desc->lba - 1)) { 704 log_debug("Misplaced Backup GPT\n"); 705 return -1; 706 } 707 708 if (is_gpt_valid(desc, (desc->lba - 1), 709 gpt_head, gpt_pte) != 1) { 710 log_debug("Invalid Backup GPT\n"); 711 return -1; 712 } 713 714 return 0; 715} 716 717static void restore_primary_gpt_header(gpt_header *gpt_h, struct blk_desc *desc) 718{ 719 u32 calc_crc32; 720 u64 val; 721 722 /* recalculate the values for the Primary GPT Header */ 723 val = le64_to_cpu(gpt_h->my_lba); 724 gpt_h->my_lba = gpt_h->alternate_lba; 725 gpt_h->alternate_lba = cpu_to_le64(val); 726 gpt_h->partition_entry_lba = cpu_to_le64(partition_entries_offset(desc)); 727 728 gpt_h->header_crc32 = 0; 729 730 calc_crc32 = efi_crc32((const unsigned char *)gpt_h, 731 le32_to_cpu(gpt_h->header_size)); 732 gpt_h->header_crc32 = cpu_to_le32(calc_crc32); 733} 734 735static int write_one_gpt_table(struct blk_desc *desc, gpt_header *gpt_h, 736 gpt_entry *gpt_e) 737{ 738 const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries 739 * sizeof(gpt_entry)), desc); 740 lbaint_t start; 741 int ret = 0; 742 743 start = le64_to_cpu(gpt_h->my_lba); 744 if (blk_dwrite(desc, start, 1, gpt_h) != 1) { 745 ret = -1; 746 goto out; 747 } 748 749 start = le64_to_cpu(gpt_h->partition_entry_lba); 750 if (blk_dwrite(desc, start, pte_blk_cnt, gpt_e) != pte_blk_cnt) { 751 ret = -1; 752 goto out; 753 } 754 755 out: 756 return ret; 757} 758 759int gpt_repair_headers(struct blk_desc *desc) 760{ 761 ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_h1, 1, desc->blksz); 762 ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_h2, 1, desc->blksz); 763 gpt_entry *gpt_e1 = NULL, *gpt_e2 = NULL; 764 int is_gpt1_valid, is_gpt2_valid; 765 int ret = -1; 766 767 is_gpt1_valid = is_gpt_valid(desc, GPT_PRIMARY_PARTITION_TABLE_LBA, 768 gpt_h1, &gpt_e1); 769 is_gpt2_valid = is_gpt_valid(desc, desc->lba - 1, 770 gpt_h2, &gpt_e2); 771 772 if (is_gpt1_valid && is_gpt2_valid) { 773 ret = 0; 774 goto out; 775 } 776 777 if (is_gpt1_valid && !is_gpt2_valid) { 778 prepare_backup_gpt_header(gpt_h1); 779 ret = write_one_gpt_table(desc, gpt_h1, gpt_e1); 780 goto out; 781 } 782 783 if (!is_gpt1_valid && is_gpt2_valid) { 784 restore_primary_gpt_header(gpt_h2, desc); 785 ret = write_one_gpt_table(desc, gpt_h2, gpt_e2); 786 goto out; 787 } 788 789 if (!is_gpt1_valid && !is_gpt2_valid) { 790 ret = -1; 791 goto out; 792 } 793 794 out: 795 if (is_gpt1_valid) 796 free(gpt_e1); 797 if (is_gpt2_valid) 798 free(gpt_e2); 799 800 return ret; 801} 802 803int gpt_verify_partitions(struct blk_desc *desc, 804 struct disk_partition *partitions, int parts, 805 gpt_header *gpt_head, gpt_entry **gpt_pte) 806{ 807 char efi_str[PARTNAME_SZ + 1]; 808 u64 gpt_part_size; 809 gpt_entry *gpt_e; 810 int ret, i; 811 812 ret = gpt_verify_headers(desc, gpt_head, gpt_pte); 813 if (ret) 814 return ret; 815 816 gpt_e = *gpt_pte; 817 818 for (i = 0; i < parts; i++) { 819 if (i == gpt_head->num_partition_entries) { 820 pr_err("More partitions than allowed!\n"); 821 return -1; 822 } 823 824 /* Check if GPT and ENV partition names match */ 825 gpt_convert_efi_name_to_char(efi_str, gpt_e[i].partition_name, 826 PARTNAME_SZ + 1); 827 828 debug("%s: part: %2d name - GPT: %16s, ENV: %16s ", 829 __func__, i, efi_str, partitions[i].name); 830 831 if (strncmp(efi_str, (char *)partitions[i].name, 832 sizeof(partitions->name))) { 833 pr_err("Partition name: %s does not match %s!\n", 834 efi_str, (char *)partitions[i].name); 835 return -1; 836 } 837 838 /* Check if GPT and ENV sizes match */ 839 gpt_part_size = le64_to_cpu(gpt_e[i].ending_lba) - 840 le64_to_cpu(gpt_e[i].starting_lba) + 1; 841 debug("size(LBA) - GPT: %8llu, ENV: %8llu ", 842 (unsigned long long)gpt_part_size, 843 (unsigned long long)partitions[i].size); 844 845 if (le64_to_cpu(gpt_part_size) != partitions[i].size) { 846 /* We do not check the extend partition size */ 847 if ((i == parts - 1) && (partitions[i].size == 0)) 848 continue; 849 850 pr_err("Partition %s size: %llu does not match %llu!\n", 851 efi_str, (unsigned long long)gpt_part_size, 852 (unsigned long long)partitions[i].size); 853 return -1; 854 } 855 856 /* 857 * Start address is optional - check only if provided 858 * in '$partition' variable 859 */ 860 if (!partitions[i].start) { 861 debug("\n"); 862 continue; 863 } 864 865 /* Check if GPT and ENV start LBAs match */ 866 debug("start LBA - GPT: %8llu, ENV: %8llu\n", 867 le64_to_cpu(gpt_e[i].starting_lba), 868 (unsigned long long)partitions[i].start); 869 870 if (le64_to_cpu(gpt_e[i].starting_lba) != partitions[i].start) { 871 pr_err("Partition %s start: %llu does not match %llu!\n", 872 efi_str, le64_to_cpu(gpt_e[i].starting_lba), 873 (unsigned long long)partitions[i].start); 874 return -1; 875 } 876 } 877 878 return 0; 879} 880 881int is_valid_gpt_buf(struct blk_desc *desc, void *buf) 882{ 883 gpt_header *gpt_h; 884 gpt_entry *gpt_e; 885 886 /* determine start of GPT Header in the buffer */ 887 gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * desc->blksz); 888 if (validate_gpt_header(gpt_h, GPT_PRIMARY_PARTITION_TABLE_LBA, 889 desc->lba)) 890 return -1; 891 892 /* determine start of GPT Entries in the buffer */ 893 gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) * 894 desc->blksz); 895 if (validate_gpt_entries(gpt_h, gpt_e)) 896 return -1; 897 898 return 0; 899} 900 901int write_mbr_and_gpt_partitions(struct blk_desc *desc, void *buf) 902{ 903 gpt_header *gpt_h; 904 gpt_entry *gpt_e; 905 int gpt_e_blk_cnt; 906 lbaint_t lba; 907 int cnt; 908 909 if (is_valid_gpt_buf(desc, buf)) 910 return -1; 911 912 /* determine start of GPT Header in the buffer */ 913 gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * desc->blksz); 914 915 /* determine start of GPT Entries in the buffer */ 916 gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) * desc->blksz); 917 gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) * 918 le32_to_cpu(gpt_h->sizeof_partition_entry)), 919 desc); 920 921 /* write MBR */ 922 lba = 0; /* MBR is always at 0 */ 923 cnt = 1; /* MBR (1 block) */ 924 if (blk_dwrite(desc, lba, cnt, buf) != cnt) { 925 log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n", 926 "MBR", cnt, lba); 927 return 1; 928 } 929 930 /* write Primary GPT */ 931 lba = GPT_PRIMARY_PARTITION_TABLE_LBA; 932 cnt = 1; /* GPT Header (1 block) */ 933 if (blk_dwrite(desc, lba, cnt, gpt_h) != cnt) { 934 log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n", 935 "Primary GPT Header", cnt, lba); 936 return 1; 937 } 938 939 lba = le64_to_cpu(gpt_h->partition_entry_lba); 940 cnt = gpt_e_blk_cnt; 941 if (blk_dwrite(desc, lba, cnt, gpt_e) != cnt) { 942 log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n", 943 "Primary GPT Entries", cnt, lba); 944 return 1; 945 } 946 947 prepare_backup_gpt_header(gpt_h); 948 949 /* write Backup GPT */ 950 lba = le64_to_cpu(gpt_h->partition_entry_lba); 951 cnt = gpt_e_blk_cnt; 952 if (blk_dwrite(desc, lba, cnt, gpt_e) != cnt) { 953 log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n", 954 "Backup GPT Entries", cnt, lba); 955 return 1; 956 } 957 958 lba = le64_to_cpu(gpt_h->my_lba); 959 cnt = 1; /* GPT Header (1 block) */ 960 if (blk_dwrite(desc, lba, cnt, gpt_h) != cnt) { 961 log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n", 962 "Backup GPT Header", cnt, lba); 963 return 1; 964 } 965 966 /* Update the partition table entries*/ 967 part_init(desc); 968 969 return 0; 970} 971#endif 972 973/* 974 * Private functions 975 */ 976/* 977 * pmbr_part_valid(): Check for EFI partition signature 978 * 979 * Returns: 1 if EFI GPT partition type is found. 980 */ 981static int pmbr_part_valid(struct partition *part) 982{ 983 if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT && 984 get_unaligned_le32(&part->start_sect) == 1UL) { 985 return 1; 986 } 987 988 return 0; 989} 990 991/* 992 * is_pmbr_valid(): test Protective MBR for validity 993 * 994 * @mbr: Pointer to Master Boot-Record data 995 * 996 * Returns: 1 if PMBR is valid, 0 otherwise. 997 * Validity depends on two things: 998 * 1) MSDOS signature is in the last two bytes of the MBR 999 * 2) One partition of type 0xEE is found, checked by pmbr_part_valid() 1000 */ 1001static int is_pmbr_valid(legacy_mbr *mbr) 1002{ 1003 uint sig = le16_to_cpu(mbr->signature); 1004 int i = 0; 1005 1006 if (sig != MSDOS_MBR_SIGNATURE) { 1007 log_debug("Invalid signature %x\n", sig); 1008 return 0; 1009 } 1010 log_debug("Signature %x valid\n", sig); 1011 1012 for (i = 0; i < 4; i++) { 1013 if (pmbr_part_valid(&mbr->partition_record[i])) { 1014 return 1; 1015 } 1016 } 1017 return 0; 1018} 1019 1020/** 1021 * is_gpt_valid() - tests one GPT header and PTEs for validity 1022 * 1023 * lba is the logical block address of the GPT header to test 1024 * gpt is a GPT header ptr, filled on return. 1025 * ptes is a PTEs ptr, filled on return. 1026 * 1027 * Description: returns 1 if valid, 0 on error, 2 if ignored header 1028 * If valid, returns pointers to PTEs. 1029 */ 1030static int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head, 1031 gpt_entry **pgpt_pte) 1032{ 1033 /* Confirm valid arguments prior to allocation. */ 1034 if (!desc || !pgpt_head) { 1035 log_debug("Invalid Argument(s)\n"); 1036 return 0; 1037 } 1038 1039 ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, mbr, 1, desc->blksz); 1040 1041 /* Read MBR Header from device */ 1042 if (blk_dread(desc, 0, 1, (ulong *)mbr) != 1) { 1043 log_debug("Can't read MBR header\n"); 1044 return 0; 1045 } 1046 1047 /* Read GPT Header from device */ 1048 if (blk_dread(desc, (lbaint_t)lba, 1, pgpt_head) != 1) { 1049 log_debug("Can't read GPT header\n"); 1050 return 0; 1051 } 1052 1053 /* Invalid but nothing to yell about. */ 1054 if (le64_to_cpu(pgpt_head->signature) == GPT_HEADER_CHROMEOS_IGNORE) { 1055 log_debug("ChromeOS 'IGNOREME' GPT header found and ignored\n"); 1056 return 2; 1057 } 1058 1059 if (validate_gpt_header(pgpt_head, (lbaint_t)lba, desc->lba)) 1060 return 0; 1061 1062 if (desc->sig_type == SIG_TYPE_NONE) { 1063 efi_guid_t empty = {}; 1064 if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) { 1065 desc->sig_type = SIG_TYPE_GUID; 1066 memcpy(&desc->guid_sig, &pgpt_head->disk_guid, 1067 sizeof(empty)); 1068 } else if (mbr->unique_mbr_signature != 0) { 1069 desc->sig_type = SIG_TYPE_MBR; 1070 desc->mbr_sig = mbr->unique_mbr_signature; 1071 } 1072 } 1073 1074 /* Read and allocate Partition Table Entries */ 1075 *pgpt_pte = alloc_read_gpt_entries(desc, pgpt_head); 1076 if (!*pgpt_pte) 1077 return 0; 1078 1079 if (validate_gpt_entries(pgpt_head, *pgpt_pte)) { 1080 free(*pgpt_pte); 1081 return 0; 1082 } 1083 1084 /* We're done, all's well */ 1085 return 1; 1086} 1087 1088/** 1089 * find_valid_gpt() - finds a valid GPT header and PTEs 1090 * 1091 * gpt is a GPT header ptr, filled on return. 1092 * ptes is a PTEs ptr, filled on return. 1093 * 1094 * Description: returns 1 if found a valid gpt, 0 on error. 1095 * If valid, returns pointers to PTEs. 1096 */ 1097static int find_valid_gpt(struct blk_desc *desc, gpt_header *gpt_head, 1098 gpt_entry **pgpt_pte) 1099{ 1100 int r; 1101 1102 r = is_gpt_valid(desc, GPT_PRIMARY_PARTITION_TABLE_LBA, gpt_head, 1103 pgpt_pte); 1104 1105 if (r != 1) { 1106 if (r != 2) 1107 log_debug("Invalid GPT\n"); 1108 1109 if (is_gpt_valid(desc, desc->lba - 1, gpt_head, pgpt_pte) 1110 != 1) { 1111 log_debug("Invalid Backup GPT\n"); 1112 return 0; 1113 } 1114 if (r != 2) 1115 log_debug(" Using Backup GPT\n"); 1116 } 1117 return 1; 1118} 1119 1120/** 1121 * alloc_read_gpt_entries(): reads partition entries from disk 1122 * @desc 1123 * @gpt - GPT header 1124 * 1125 * Description: Returns ptes on success, NULL on error. 1126 * Allocates space for PTEs based on information found in @gpt. 1127 * Notes: remember to free pte when you're done! 1128 */ 1129static gpt_entry *alloc_read_gpt_entries(struct blk_desc *desc, 1130 gpt_header *pgpt_head) 1131{ 1132 size_t count = 0, blk_cnt; 1133 lbaint_t blk; 1134 gpt_entry *pte = NULL; 1135 1136 if (!desc || !pgpt_head) { 1137 log_debug("Invalid Argument(s)\n"); 1138 return NULL; 1139 } 1140 1141 count = le32_to_cpu(pgpt_head->num_partition_entries) * 1142 le32_to_cpu(pgpt_head->sizeof_partition_entry); 1143 1144 log_debug("count = %u * %u = %lu\n", 1145 (u32)le32_to_cpu(pgpt_head->num_partition_entries), 1146 (u32)le32_to_cpu(pgpt_head->sizeof_partition_entry), 1147 (ulong)count); 1148 1149 /* Allocate memory for PTE, remember to FREE */ 1150 if (count != 0) { 1151 pte = memalign(ARCH_DMA_MINALIGN, 1152 PAD_TO_BLOCKSIZE(count, desc)); 1153 } 1154 1155 if (count == 0 || pte == NULL) { 1156 log_debug("ERROR: Can't allocate %#lX bytes for GPT Entries\n", 1157 (ulong)count); 1158 return NULL; 1159 } 1160 1161 /* Read GPT Entries from device */ 1162 blk = le64_to_cpu(pgpt_head->partition_entry_lba); 1163 blk_cnt = BLOCK_CNT(count, desc); 1164 if (blk_dread(desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) { 1165 log_debug("Can't read GPT Entries\n"); 1166 free(pte); 1167 return NULL; 1168 } 1169 return pte; 1170} 1171 1172/** 1173 * is_pte_valid(): validates a single Partition Table Entry 1174 * @gpt_entry - Pointer to a single Partition Table Entry 1175 * 1176 * Description: returns 1 if valid, 0 on error. 1177 */ 1178static int is_pte_valid(gpt_entry * pte) 1179{ 1180 efi_guid_t unused_guid; 1181 1182 if (!pte) { 1183 log_debug("Invalid Argument(s)\n"); 1184 return 0; 1185 } 1186 1187 /* Only one validation for now: 1188 * The GUID Partition Type != Unused Entry (ALL-ZERO) 1189 */ 1190 memset(unused_guid.b, 0, sizeof(unused_guid.b)); 1191 1192 if (memcmp(pte->partition_type_guid.b, unused_guid.b, 1193 sizeof(unused_guid.b)) == 0) { 1194 1195 log_debug("Found an unused PTE GUID at 0x%08X\n", 1196 (unsigned int)(uintptr_t)pte); 1197 1198 return 0; 1199 } else { 1200 return 1; 1201 } 1202} 1203 1204/* 1205 * Add an 'a_' prefix so it comes before 'dos' in the linker list. We need to 1206 * check EFI first, since a DOS partition is often used as a 'protective MBR' 1207 * with EFI. 1208 */ 1209U_BOOT_PART_TYPE(a_efi) = { 1210 .name = "EFI", 1211 .part_type = PART_TYPE_EFI, 1212 .max_entries = GPT_ENTRY_NUMBERS, 1213 .get_info = part_get_info_ptr(part_get_info_efi), 1214 .print = part_print_ptr(part_print_efi), 1215 .test = part_test_efi, 1216};