diff options
-rw-r--r-- | disk/part_efi.c | 72 | ||||
-rw-r--r-- | drivers/usb/gadget/f_fastboot.c | 40 |
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; |