*/
static unsigned int download_size;
static unsigned int download_bytes;
-#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
-static bool is_recovery_mode;
+#if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC)
+static bool is_recovery_mode = false;
#endif
/* common variables of fastboot getvar command */
case BOOTMODE_FASTBOOT_BCB_CMD:
/* Make the boot into fastboot mode*/
puts("Fastboot: Got bootloader commands!\n");
-#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
- is_recovery_mode = false;
-#endif
run_command("fastboot 0", 0);
break;
#ifdef CONFIG_ANDROID_RECOVERY
case BOOTMODE_RECOVERY_KEY_PRESSED:
/* Make the boot into recovery mode */
puts("Fastboot: Got Recovery key pressing or recovery commands!\n");
-#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
+#if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC)
is_recovery_mode = true;
#else
board_recovery_setup();
#endif
default:
/* skip special mode boot*/
-#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
- is_recovery_mode = false;
-#endif
puts("Fastboot: Normal\n");
break;
}
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[]) {
}
bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false);
avb_metric = get_timer(0);
- /* if in lock state, do avb verify */
+ /* For imx6 on Android, we don't have a/b slot and we want to verify
+ * boot/recovery with AVB. For imx8 and Android Things we don't have
+ * recovery and support a/b slot for boot */
+#ifdef CONFIG_ANDROID_AB_SUPPORT
+ /* we can use avb to verify Trusty if we want */
+ const char *requested_partitions[] = {"boot", 0};
avb_result = avb_ab_flow_fast(&fsl_avb_ab_ops, requested_partitions, allow_fail,
AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data);
+#else /* CONFIG_ANDROID_AB_SUPPORT */
+ if (!is_recovery_mode) {
+ const char *requested_partitions[] = {"boot", 0};
+ avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions, allow_fail,
+ AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data);
+ } else {
+ const char *requested_partitions[] = {"recovery", 0};
+ avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions, allow_fail,
+ AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data);
+ }
+#endif /* CONFIG_ANDROID_AB_SUPPORT */
/* get the duration of avb */
metrics.avb = get_timer(avb_metric);
else
fastboot_setup_system_boot_args(avb_out_data->ab_suffix, true);
}
-#endif
+#endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */
image_size = avb_loadpart->data_size;
#if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M)
/* If we are using uncompressed kernel image, copy it directly to
size_t num_read;
hdr = &boothdr;
- char bootimg[8];
+ char bootimg[10];
+ /* we don't have a/b slot for imx6 on normal Android*/
+#ifndef CONFIG_ANDROID_AB_SUPPORT
+ char *slot = "";
+ if (!is_recovery_mode) {
+ sprintf(bootimg, "boot");
+ } else {
+ sprintf(bootimg, "recovery");
+ }
+ printf("boot '%s' still\n", bootimg);
+#else
char *slot = select_slot(&fsl_avb_ab_ops);
if (slot == NULL) {
printf("boota: no bootable slot\n");
}
sprintf(bootimg, "boot%s", slot);
printf(" boot '%s' still\n", bootimg);
+#endif
/* 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,
}
hdr = (struct andr_img_hdr *)(ulong)(hdr->kernel_addr - hdr->page_size);
#endif /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */
-
char bootargs_sec[ANDR_BOOT_ARGS_SIZE];
sprintf(bootargs_sec,
"androidboot.verifiedbootstate=orange androidboot.slot_suffix=%s", slot);
#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
if(!is_recovery_mode)
fastboot_setup_system_boot_args(slot, true);
-#endif
+#endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */
#ifdef CONFIG_FASTBOOT_LOCK
}
#endif
return ret;
}
+/* For legacy i.mx6/7, we won't enable A/B due to the limitation of
+ * storage capacity, but we still want to verify boot/recovery with
+ * AVB. */
+AvbABFlowResult avb_single_flow(AvbABOps* ab_ops,
+ const char* const* requested_partitions,
+ AvbSlotVerifyFlags flags,
+ AvbHashtreeErrorMode hashtree_error_mode,
+ AvbSlotVerifyData** out_data) {
+ AvbOps* ops = ab_ops->ops;
+ AvbSlotVerifyData* slot_data = NULL;
+ AvbSlotVerifyData* data = NULL;
+ AvbABFlowResult ret;
+ bool saw_and_allowed_verification_error = false;
+
+ /* Validate boot/recovery. */
+ AvbSlotVerifyResult verify_result;
+
+ verify_result = avb_slot_verify(ops,
+ requested_partitions,
+ "",
+ flags,
+ hashtree_error_mode,
+ &slot_data);
+ switch (verify_result) {
+ case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
+ ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
+ goto out;
+
+ case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
+ ret = AVB_AB_FLOW_RESULT_ERROR_IO;
+ goto out;
+
+ case AVB_SLOT_VERIFY_RESULT_OK:
+ break;
+
+ case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
+ /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
+ * these mean game over.
+ */
+ ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
+ goto out;
+
+ /* explicit fallthrough. */
+ case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
+ if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
+ /* Do nothing since we allow this. */
+ avb_debugv("Allowing slot ",
+ slot_suffixes[n],
+ " which verified "
+ "with result ",
+ avb_slot_verify_result_to_string(verify_result),
+ " because "
+ "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
+ "is set.\n",
+ NULL);
+ saw_and_allowed_verification_error = true;
+ } else {
+ ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
+ goto out;
+ }
+ break;
+
+ case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
+ ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
+ goto out;
+ /* Do not add a 'default:' case here because of -Wswitch. */
+ }
+
+ avb_assert(slot_data != NULL);
+ data = slot_data;
+ slot_data = NULL;
+ if (saw_and_allowed_verification_error) {
+ avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
+ ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
+ } else {
+ ret = AVB_AB_FLOW_RESULT_OK;
+ }
+
+out:
+ if (slot_data != NULL) {
+ avb_slot_verify_data_free(slot_data);
+ }
+
+ if (out_data != NULL) {
+ *out_data = data;
+ } else {
+ if (data != NULL) {
+ avb_slot_verify_data_free(data);
+ }
+ }
+
+ return ret;
+}
+
AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
const char* const* requested_partitions,
AvbSlotVerifyFlags flags,