summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhang sanshan <sanshan.zhang@nxp.com>2017-07-13 20:07:58 +0800
committerzhang sanshan <sanshan.zhang@nxp.com>2017-07-19 18:24:38 +0800
commitc7aefcba1d8eaa503c7e7dc108c097ae4a1a9a95 (patch)
treedec44910abf59037f7f5200687920fbe3db020b2
parent721193c18f248faa1c892cc64fc656b21b7320b8 (diff)
downloadu-boot-imx-c7aefcba1d8eaa503c7e7dc108c097ae4a1a9a95.zip
u-boot-imx-c7aefcba1d8eaa503c7e7dc108c097ae4a1a9a95.tar.gz
u-boot-imx-c7aefcba1d8eaa503c7e7dc108c097ae4a1a9a95.tar.bz2
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>
-rw-r--r--disk/part_efi.c72
-rw-r--r--drivers/usb/gadget/f_fastboot.c40
2 files changed, 107 insertions, 5 deletions
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 492b5ed..8bc6f39 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
/*
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index f7ff7bd..0939234 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -69,6 +69,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
@@ -213,6 +214,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 {
@@ -930,6 +934,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) {
@@ -947,6 +958,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) {
@@ -1272,10 +1308,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;