summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;