diff options
author | zhang sanshan <sanshan.zhang@nxp.com> | 2017-05-15 10:45:07 +0800 |
---|---|---|
committer | Chen Guoyin <guoyin.chen@nxp.com> | 2017-07-10 15:08:53 +0800 |
commit | 1c79796a523255af5d012fa3cbc5400131b3b8b9 (patch) | |
tree | 671d094845bc787fca67f158f73084db3ee80f49 /drivers/usb | |
parent | 893ec7807779aa34ce49866f03e49c592fff9543 (diff) | |
download | u-boot-imx-1c79796a523255af5d012fa3cbc5400131b3b8b9.zip u-boot-imx-1c79796a523255af5d012fa3cbc5400131b3b8b9.tar.gz u-boot-imx-1c79796a523255af5d012fa3cbc5400131b3b8b9.tar.bz2 |
MA-9409-1 enable avb on android things.
Fix issue for API changed from v2017.
porting below patch from v2016.
commit 44834fd12f60a090e3d10ab6f84a75460894d49d
Change-Id: Ifaf0b86dd29648f9150646f00f54502676df9013
Signed-off-by: zhang sanshan <sanshan.zhang@nxp.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/f_fastboot.c | 269 |
1 files changed, 259 insertions, 10 deletions
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 33cad88..912fa50 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -55,6 +55,9 @@ #include "bcb.h" #endif +#ifdef CONFIG_AVB_SUPPORT +#include <fsl_avb.h> +#endif #define FASTBOOT_VERSION "0.4" @@ -97,6 +100,7 @@ static inline struct f_fastboot *func_to_fastboot(struct usb_function *f) static struct f_fastboot *fastboot_func; static unsigned int download_size; static unsigned int download_bytes; +static int strcmp_l1(const char *s1, const char *s2); static struct usb_endpoint_descriptor fs_ep_in = { .bLength = USB_DT_ENDPOINT_SIZE, @@ -790,8 +794,7 @@ static void process_flash_sata(const char *cmdbuf) /* Next is the partition name */ ptn = fastboot_flash_find_ptn(cmdbuf); - if (ptn == 0) { - printf("Partition:'%s' does not exist\n", ptn->name); + if (ptn == NULL) { fastboot_fail("partition does not exist"); } else if ((download_bytes > ptn->length * MMC_SATA_BLOCK_SIZE) && @@ -927,11 +930,22 @@ static void process_flash_mmc(const char *cmdbuf) { if (download_bytes) { struct fastboot_ptentry *ptn; +#ifdef CONFIG_AVB_SUPPORT + if (!strcmp_l1(FASTBOOT_PARTITION_AVBKEY, cmdbuf)) { + printf("pubkey len %d\n", download_bytes); + if (avbkey_init(interface.transfer_buffer, download_bytes) != 0) { + fastboot_fail("fail to Write partition"); + } else { + printf("init 'avbkey' DONE!\n"); + fastboot_okay("OKAY"); + } + return; + } +#endif /* Next is the partition name */ ptn = fastboot_flash_find_ptn(cmdbuf); - if (ptn == 0) { - printf("Partition:'%s' does not exist\n", ptn->name); + if (ptn == NULL) { fastboot_fail("partition does not exist"); } else if ((download_bytes > ptn->length * MMC_SATA_BLOCK_SIZE) && @@ -1213,6 +1227,9 @@ static int _fastboot_parts_add_ptable_entry(int ptable_index, strcpy(ptable[ptable_index].name, name); #endif +#ifdef CONFIG_PARTITION_UUIDS + strcpy(ptable[ptable_index].uuid, (const char *)info.uuid); +#endif return 0; } @@ -1632,6 +1649,25 @@ void board_recovery_setup(void) #endif /*CONFIG_ANDROID_RECOVERY*/ #endif /*CONFIG_FSL_FASTBOOT*/ +#if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) +static AvbABOps fsl_avb_ab_ops = { + .read_ab_metadata = fsl_read_ab_metadata, + .write_ab_metadata = fsl_write_ab_metadata, + .ops = NULL +}; + +static AvbOps fsl_avb_ops = { + .ab_ops = &fsl_avb_ab_ops, + .read_from_partition = fsl_read_from_partition_multi, + .write_to_partition = fsl_write_to_partition, + .validate_vbmeta_public_key = fsl_validate_vbmeta_public_key_rpmb, + .read_rollback_index = fsl_read_rollback_index_rpmb, + .write_rollback_index = fsl_write_rollback_index_rpmb, + .read_is_device_unlocked = fsl_read_is_device_unlocked, + .get_unique_guid_for_partition = fsl_get_unique_guid_for_partition +}; +#endif + void fastboot_setup(void) { struct tag_serialnr serialnr; @@ -1652,6 +1688,9 @@ void fastboot_setup(void) _fastboot_load_partitions(); parameters_setup(); +#ifdef CONFIG_AVB_SUPPORT + fsl_avb_ab_ops.ops = &fsl_avb_ops; +#endif } /* Write the bcb with fastboot bootloader commands */ @@ -1765,6 +1804,172 @@ bootimg_print_image_hdr(struct andr_img_hdr *hdr) static struct andr_img_hdr boothdr __aligned(ARCH_DMA_MINALIGN); +#if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) +/* we can use avb to verify Trusty if we want */ +const char *requested_partitions[] = {"boot", 0}; + +int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + + ulong addr = 0; + struct andr_img_hdr *hdr = NULL; + struct andr_img_hdr *hdrload; + ulong image_size; + + AvbABFlowResult avb_result; + AvbSlotVerifyData *avb_out_data; + AvbPartitionData *avb_loadpart; + +#ifdef CONFIG_FASTBOOT_LOCK + /* check lock state */ + FbLockState lock_status = fastboot_get_lock_stat(); + if (lock_status == FASTBOOT_LOCK_ERROR) { + printf("In boota get fastboot lock status error. Set lock status\n"); + fastboot_set_lock_stat(FASTBOOT_LOCK); + lock_status = FASTBOOT_LOCK; + } + bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false); + /* if in lock state, do avb verify */ + avb_result = avb_ab_flow(&fsl_avb_ab_ops, requested_partitions, allow_fail, &avb_out_data); + if (avb_result == AVB_AB_FLOW_RESULT_OK) { + assert(avb_out_data != NULL); + /* load the first partition */ + avb_loadpart = avb_out_data->loaded_partitions; + assert(avb_loadpart != NULL); + /* we should use avb_part_data->data as boot image */ + /* boot image is already read by avb */ + hdr = (struct andr_img_hdr *)avb_loadpart->data; + if (android_image_check_header(hdr)) { + printf("boota: bad boot image magic\n"); + goto fail; + } + printf(" verify OK, boot '%s%s'\n", avb_loadpart->partition_name, avb_out_data->ab_suffix); + char bootargs_sec[2048]; + sprintf(bootargs_sec, "androidboot.slot_suffix=%s %s", avb_out_data->ab_suffix, avb_out_data->cmdline); + setenv("bootargs_sec", bootargs_sec); +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT + if(!is_recovery_mode) + fastboot_setup_system_boot_args(avb_out_data->ab_suffix); +#endif + image_size = avb_loadpart->data_size; + memcpy((void *)load_addr, (void *)hdr, image_size); + } else if (lock_status == FASTBOOT_LOCK) { /* && verify fail */ + /* if in lock state, verify enforce fail */ + printf(" verify FAIL, state: LOCK\n"); + goto fail; + } else { /* lock_status == FASTBOOT_UNLOCK && verify fail */ + /* if in unlock state, log the verify state */ + printf(" verify FAIL, state: UNLOCK\n"); +#endif + /* if lock/unlock not enabled or verify fail + * in unlock state, will try boot */ + size_t num_read; + hdr = &boothdr; + + char bootimg[8]; + char *slot = select_slot(&fsl_avb_ab_ops); + if (slot == NULL) { + printf("boota: no bootable slot\n"); + goto fail; + } + sprintf(bootimg, "boot%s", slot); + printf(" boot '%s' still\n", bootimg); + /* maybe we should use bootctl to select a/b + * but libavb doesn't export a/b select */ + if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, bootimg, + 0, sizeof(boothdr), hdr, &num_read) != AVB_IO_RESULT_OK && + num_read != sizeof(boothdr)) { + printf("boota: read bootimage head error\n"); + goto fail; + } + if (android_image_check_header(hdr)) { + printf("boota: bad boot image magic\n"); + goto fail; + } + image_size = android_image_get_end(hdr) - (ulong)hdr; + if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, bootimg, + 0, image_size, (void *)load_addr, &num_read) != AVB_IO_RESULT_OK && + num_read != image_size) { + printf("boota: read boot image error\n"); + goto fail; + } + char bootargs_sec[ANDR_BOOT_ARGS_SIZE]; + sprintf(bootargs_sec, "androidboot.slot_suffix=%s", slot); + setenv("bootargs_sec", bootargs_sec); +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT + if(!is_recovery_mode) + fastboot_setup_system_boot_args(slot); +#endif +#ifdef CONFIG_FASTBOOT_LOCK + } +#endif + + flush_cache((ulong)load_addr, image_size); + addr = load_addr; + hdrload = (struct andr_img_hdr *)load_addr; + + ulong img_ramdisk, img_ramdisk_len; + if(android_image_get_ramdisk(hdrload, &img_ramdisk, &img_ramdisk_len) != 0) { + printf("boota: mmc failed to read ramdisk\n"); + goto fail; + } + memcpy((void *)hdrload->ramdisk_addr, (void *)img_ramdisk, img_ramdisk_len); + /* flush cache after read */ + flush_cache((ulong)hdrload->ramdisk_addr, img_ramdisk_len); /* FIXME */ + +#ifdef CONFIG_OF_LIBFDT + /* load the dtb file */ + if (hdrload->second_size && hdrload->second_addr) { + ulong img_fdt, img_fdt_len; + if (android_image_get_fdt(hdrload, &img_fdt, &img_fdt_len) != 0) { + printf("boota: mmc failed to dtb\n"); + goto fail; + } + memcpy((void *)hdrload->second_addr, (void *)img_fdt, img_fdt_len); + /* flush cache after read */ + flush_cache((ulong)hdrload->second_addr, img_fdt_len); /* FIXME */ + } +#endif /*CONFIG_OF_LIBFDT*/ + printf("kernel @ %08x (%d)\n", hdrload->kernel_addr, hdrload->kernel_size); + printf("ramdisk @ %08x (%d)\n", hdrload->ramdisk_addr, hdrload->ramdisk_size); +#ifdef CONFIG_OF_LIBFDT + if (hdrload->second_size) + printf("fdt @ %08x (%d)\n", hdrload->second_addr, hdrload->second_size); +#endif /*CONFIG_OF_LIBFDT*/ + + char boot_addr_start[12]; + char ramdisk_addr[25]; + char fdt_addr[12]; + + char *bootm_args[] = { "bootm", boot_addr_start, ramdisk_addr, fdt_addr}; + + sprintf(boot_addr_start, "0x%lx", addr); + sprintf(ramdisk_addr, "0x%x:0x%x", hdrload->ramdisk_addr, hdrload->ramdisk_size); + sprintf(fdt_addr, "0x%x", hdrload->second_addr); + + if (avb_out_data != NULL) + avb_slot_verify_data_free(avb_out_data); + + do_bootm(NULL, 0, 4, bootm_args); + + /* This only happens if image is somehow faulty so we start over */ + do_reset(NULL, 0, 0, NULL); + + return 1; + +fail: + /* avb has no recovery */ + if (avb_out_data != NULL) + avb_slot_verify_data_free(avb_out_data); + + return run_command("fastboot 0", 0); +} + +U_BOOT_CMD( + boota, 2, 1, do_boota, + "boota - boot android bootimg \n", + "boot from current mmc with avb verify\n" +); +#else /* CONFIG_AVB_SUPPORT */ /* boota <addr> [ mmc0 | mmc1 [ <partition> ] ] */ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -2114,11 +2319,11 @@ U_BOOT_CMD( "\t 'partition' (optional) is the partition id of your device, " "if no partition give, will going to 'boot' partition\n" ); +#endif /* CONFIG_AVB_SUPPORT */ #endif /* CONFIG_CMD_BOOTA */ #endif static void rx_handler_command(struct usb_ep *ep, struct usb_request *req); -static int strcmp_l1(const char *s1, const char *s2); static char *fb_response_str; @@ -2400,10 +2605,13 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) } else if (is_slotvar(cmd)) { -#ifdef CONFIG_FSL_BOOTCTL - get_slotvar(cmd, response, chars_left); - fastboot_tx_write_str(response); - return; +#ifdef CONFIG_AVB_SUPPORT + if (get_slotvar_avb(&fsl_avb_ab_ops, cmd, + response + strlen(response), chars_left + 1) < 0) + goto fail; +#elif CONFIG_FSL_BOOTCTL + if (get_slotvar(cmd, response + strlen(response), chars_left + 1) < 0) + goto fail; #else strncat(response, FASTBOOT_VAR_NO, chars_left); #endif @@ -2457,6 +2665,11 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) } } fastboot_tx_write_str(response); + return; +fail: + strncpy(response, "FAIL", 4); + fastboot_tx_write_str(response); + return; } static unsigned int rx_bytes_expected(struct usb_ep *ep) @@ -2819,6 +3032,37 @@ static void cb_erase(struct usb_ep *ep, struct usb_request *req) } #endif +#ifdef CONFIG_AVB_SUPPORT +static void cb_set_active_avb(struct usb_ep *ep, struct usb_request *req) +{ + AvbIOResult ret; + int slot = 0; + char *cmd = req->buf; + + strsep(&cmd, ":"); + if (!cmd) { + error("missing slot suffix\n"); + fastboot_tx_write_str("FAILmissing slot suffix"); + return; + } + + slot = slotidx_from_suffix(cmd); + + if (slot < 0) { + fastboot_tx_write_str("FAILerr slot suffix"); + return; + } + + ret = avb_ab_mark_slot_active(&fsl_avb_ab_ops, slot); + if (ret != AVB_IO_RESULT_OK) + fastboot_tx_write_str("avb IO error"); + else + fastboot_tx_write_str("OKAY"); + + return; +} +#endif /*CONFIG_AVB_SUPPORT*/ + #ifdef CONFIG_FSL_FASTBOOT static void cb_reboot_bootloader(struct usb_ep *ep, struct usb_request *req) { @@ -2879,7 +3123,12 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = { .cb = cb_flashing, }, #endif -#ifdef CONFIG_FSL_BOOTCTL +#ifdef CONFIG_AVB_SUPPORT + { + .cmd = "set_active", + .cb = cb_set_active_avb, + }, +#elif CONFIG_FSL_BOOTCTL { .cmd = "set_active", .cb = cb_set_active, |