1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
| #include <common.h> #include <command.h> #include <android_image.h> #include <mmc.h> #include <stdlib.h> #include <memalign.h> #include <fdtdec.h>
#define PART_MAX_COUNT 128 #define LAB_SIZE 512 #define HEADER_OFFSET LAB_SIZE #define ENTRY_OFFSET (2 * LAB_SIZE) #define VAL1_OFFSET sizeof(u64) #define VAL2_OFFSET (2 * sizeof(u64))
static u64 get_gpt_blk_cnt_and_print(struct blk_desc *dev_desc, gpt_header *gpt_head, gpt_entry **gpt_pte) { char efi_str[PARTNAME_SZ + 1]; u64 gpt_part_size, gpt_blk_cnt = 0; gpt_entry *gpt_e; int i;
gpt_e = *gpt_pte; for (i = 0; i < gpt_head->num_partition_entries; i++) {
raite_gpt_convert_efi_name_to_char(efi_str, gpt_e[i].partition_name, PARTNAME_SZ + 1);
printf("%s: part: %2d name - GPT: %16s ", __func__, i, efi_str); gpt_part_size = le64_to_cpu(gpt_e[i].ending_lba) - le64_to_cpu(gpt_e[i].starting_lba) + 1; gpt_blk_cnt += gpt_part_size; if(gpt_part_size == 1) break; printf("size(LBA) - GPT: %8llu ", (unsigned long long)gpt_part_size);
printf("start LBA - GPT: %8llu \n", le64_to_cpu(gpt_e[i].starting_lba)); }
return gpt_blk_cnt + gpt_e[0].starting_lba - 1; }
static int get_gpt_meta_data(u64 *data_size, void **data) { gpt_header *pgpt_head; gpt_entry *entries; void *meta_data; u64 meta_data_size, gpt_entries_size; struct blk_desc *dev_desc = NULL; struct mmc *mmc = NULL; u64 blk_size = 0; u64 blk_cnt = 0; u64 tag = 0x55AA; lbaint_t lba; if (!data_size || !data) { printf("%s *** ERROR: Invalid Argument(s) ***\n", __func__); return -1; } mmc = do_returnmmc(); if (!mmc) return CMD_RET_FAILURE; dev_desc = mmc_get_blk_desc(mmc); if (!dev_desc) { printf("%s *** ERROR: mmc_get_blk_desc err ***\n", __func__); return -1; }
gpt_entries_size = sizeof(gpt_entry) * PART_MAX_COUNT; meta_data_size = LAB_SIZE + sizeof(gpt_header) + gpt_entries_size; meta_data = malloc(meta_data_size); if(!meta_data) { printf("%s *** ERROR: malloc memory (gpt meta data) ***\n", __func__); return -1; } memset(meta_data, 0, meta_data_size); pgpt_head = (gpt_header *)((char *)meta_data + HEADER_OFFSET); entries = (gpt_entry *)((char *)meta_data + ENTRY_OFFSET); ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz);
lba = 0; blk_cnt = 1; if (blk_dread(dev_desc, lba, blk_cnt, (ulong *)mbr) != 1) { printf("*** ERROR: Can't read MBR header ***\n"); goto ERROR_OUT; }
lba = GPT_PRIMARY_PARTITION_TABLE_LBA; blk_cnt = 1; if (blk_dread(dev_desc, lba, blk_cnt, pgpt_head) != 1) { printf("%s *** ERROR: Can't read GPT header ***\n", __func__); goto ERROR_OUT; }
lba = GPT_PRIMARY_PARTITION_TABLE_LBA; if (validate_gpt_header(pgpt_head, lba, dev_desc->lba)) { printf("%s *** ERROR: validate_gpt_header GPT header ***\n", __func__); goto ERROR_OUT; }
if (dev_desc->sig_type == SIG_TYPE_NONE) { efi_guid_t empty = {}; if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) { dev_desc->sig_type = SIG_TYPE_GUID; memcpy(&dev_desc->guid_sig, &pgpt_head->disk_guid, sizeof(empty)); } else if (mbr->unique_mbr_signature != 0) { dev_desc->sig_type = SIG_TYPE_MBR; dev_desc->mbr_sig = mbr->unique_mbr_signature; } }
lba = le64_to_cpu(pgpt_head->partition_entry_lba); blk_cnt = BLOCK_CNT((le32_to_cpu(pgpt_head->num_partition_entries) * le32_to_cpu(pgpt_head->sizeof_partition_entry)), dev_desc); if (blk_dread(dev_desc, lba, blk_cnt, entries) != blk_cnt) { printf("%s *** ERROR:read entries (lba=%llu) ***\n", __func__, pgpt_head->partition_entry_lba); goto ERROR_OUT; } blk_size = dev_desc->blksz; validate_gpt_entries(pgpt_head, entries); debug("%s read entries lba %llu (blk_cnt %llu blk_size=%llu)\n", __func__, (unsigned long long)(ulong)lba, blk_cnt, blk_size); blk_cnt = get_gpt_blk_cnt(dev_desc, pgpt_head, &entries);
blk_cnt = get_gpt_blk_cnt(dev_desc, pgpt_head, &entries); memcpy(meta_data, (void *)&tag, sizeof(u64)); memcpy(meta_data + VAL1_OFFSET, (void *)&blk_size, sizeof(u64)); memcpy(meta_data + VAL2_OFFSET, (void *)&blk_cnt, sizeof(u64));
*data_size = meta_data_size; *data = meta_data;
return 0;
ERROR_OUT: free(meta_data); meta_data = NULL; return -1; }
|