MA-9387 [Android] fastboot: fastboot gpt.img for sd card in android
authorzhang sanshan <sanshan.zhang@nxp.com>
Thu, 13 Jul 2017 12:07:58 +0000 (20:07 +0800)
committerJason Liu <jason.hui.liu@nxp.com>
Thu, 2 Nov 2017 18:37:03 +0000 (02:37 +0800)
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>
disk/part_efi.c
drivers/usb/gadget/f_fastboot.c

index 492b5ed..8bc6f39 100644 (file)
@@ -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
 
 /*
index c5b603e..24deb26 100644 (file)
@@ -70,6 +70,7 @@
 
 #define ANDROID_GPT_OFFSET         0
 #define ANDROID_GPT_SIZE           0x100000
+#define ANDROID_GPT_END                   0x4400
 #define FASTBOOT_INTERFACE_CLASS       0xff
 #define FASTBOOT_INTERFACE_SUB_CLASS   0x42
 #define FASTBOOT_INTERFACE_PROTOCOL    0x03
@@ -214,6 +215,9 @@ static struct usb_gadget_strings *fastboot_strings[] = {
 #define FASTBOOT_FBPARTS_ENV_MAX_LEN 1024
 /* To support the Android-style naming of flash */
 #define MAX_PTN                    32
+static struct fastboot_ptentry g_ptable[MAX_PTN];
+static unsigned int g_pcount;
+struct fastboot_device_info fastboot_devinfo;
 
 
 enum {
@@ -931,6 +935,13 @@ static lbaint_t mmc_sparse_reserve(struct sparse_storage *info,
        return blkcnt;
 }
 
+/*judge wether the gpt image and bootloader image are overlay*/
+bool bootloader_gpt_overlay(void)
+{
+       return (g_ptable[PTN_GPT_INDEX].partition_id  == g_ptable[PTN_BOOTLOADER_INDEX].partition_id  &&
+               ANDROID_BOOTLOADER_OFFSET < ANDROID_GPT_END);
+}
+
 static void process_flash_mmc(const char *cmdbuf)
 {
        if (download_bytes) {
@@ -948,6 +959,31 @@ static void process_flash_mmc(const char *cmdbuf)
                }
 #endif
 
+               if (strncmp(cmdbuf, "gpt", 3) == 0 && bootloader_gpt_overlay()) {
+                       int mmc_no = 0;
+                       struct mmc *mmc;
+                       struct blk_desc *dev_desc;
+                       mmc_no = fastboot_devinfo.dev_id;
+                       mmc = find_mmc_device(mmc_no);
+                       if (mmc == NULL) {
+                               printf("invalid mmc device\n");
+                               fastboot_tx_write_str("FAILinvalid mmc device");
+                       }
+                       dev_desc = blk_get_dev("mmc", mmc_no);
+                       if (is_valid_gpt_buf(dev_desc, interface.transfer_buffer)) {
+                               printf("invalid GPT image\n");
+                               fastboot_tx_write_str("FAILinvalid GPT partition image");
+                               return;
+                       }
+                       if (write_backup_gpt_partitions(dev_desc, interface.transfer_buffer)) {
+                               printf("writing GPT image fail\n");
+                               fastboot_tx_write_str("FAILwriting GPT image fail");
+                               return;
+                       }
+                       printf("flash gpt image successfully\n");
+                       fastboot_okay("");
+                       return;
+               }
                /* Next is the partition name */
                ptn = fastboot_flash_find_ptn(cmdbuf);
                if (ptn == NULL) {
@@ -1273,10 +1309,6 @@ static void parameters_setup(void)
                                CONFIG_FASTBOOT_BUF_SIZE;
 }
 
-static struct fastboot_ptentry g_ptable[MAX_PTN];
-static unsigned int g_pcount;
-struct fastboot_device_info fastboot_devinfo;
-
 static int _fastboot_setup_dev(void)
 {
        char *fastboot_env;