summaryrefslogtreecommitdiff
path: root/disk
diff options
context:
space:
mode:
authorzhang sanshan <sanshan.zhang@nxp.com>2017-07-13 20:07:58 +0800
committerJason Liu <jason.hui.liu@nxp.com>2017-11-03 02:37:03 +0800
commita120adeaabdea3a7929439346a18371e1b99e98d (patch)
tree490587c7049ff9fe616ab45302aaf8763e7202a2 /disk
parentcd355a5fd919c160afeb3c861a68b37180467e44 (diff)
MA-9387 [Android] fastboot: fastboot gpt.img for sd card in android
we set gpt image in the last lba for sd boot. complete the gpt header, gpt entry and protective MBR according the last lba gpt rule. Change-Id: Icc356a66f82ad359c0243245ab9fdfaea3bccd4f Signed-off-by: zhang sanshan <sanshan.zhang@nxp.com>
Diffstat (limited to 'disk')
-rw-r--r--disk/part_efi.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 492b5ed707..8bc6f39f4d 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -133,6 +133,25 @@ static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
return 0;
}
+static void prepare_last_lba_gpt_header(struct blk_desc *dev_desc, 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 = cpu_to_le64(dev_desc->lba - 1);;
+ gpt_h->alternate_lba = cpu_to_le64(val);
+ gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
+ 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,
+ le32_to_cpu(gpt_h->header_size));
+ gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
+}
+
static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
{
uint32_t calc_crc32;
@@ -170,7 +189,6 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h)
le32_to_cpu(gpt_h->header_size));
gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
}
-
#if CONFIG_IS_ENABLED(EFI_PARTITION)
/*
* Public Functions (include/part.h)
@@ -768,6 +786,58 @@ int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf)
return 0;
}
+int write_backup_gpt_partitions(struct blk_desc *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 (blk_dwrite(dev_desc, lba, cnt, buf) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
+ __func__, "MBR", cnt, lba);
+ return 1;
+ }
+
+ prepare_last_lba_gpt_header(dev_desc, gpt_h);
+
+ /* write Backup GPT */
+ lba = le64_to_cpu(gpt_h->partition_entry_lba);
+ cnt = gpt_e_blk_cnt;
+ if (blk_dwrite(dev_desc, 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 (blk_dwrite(dev_desc, 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
/*