| .. | .. | 
|---|
| 18 | 18 | #include <dt_table.h> | 
|---|
| 19 | 19 | #include <image-android-dt.h> | 
|---|
| 20 | 20 | #include <malloc.h> | 
|---|
|  | 21 | +#include <mp_boot.h> | 
|---|
| 21 | 22 | #include <fdt_support.h> | 
|---|
| 22 | 23 | #include <fs.h> | 
|---|
| 23 | 24 | #include <boot_rkimg.h> | 
|---|
| .. | .. | 
|---|
| 462 | 463 | slot->successful_boot = 0; | 
|---|
| 463 | 464 | } | 
|---|
| 464 | 465 |  | 
|---|
|  | 466 | +static char *join_str(const char *a, const char *b) | 
|---|
|  | 467 | +{ | 
|---|
|  | 468 | +	size_t len = strlen(a) + strlen(b) + 1 /* null term */; | 
|---|
|  | 469 | +	char *ret = (char *)malloc(len); | 
|---|
|  | 470 | + | 
|---|
|  | 471 | +	if (!ret) { | 
|---|
|  | 472 | +		debug("failed to alloc %zu\n", len); | 
|---|
|  | 473 | +		return NULL; | 
|---|
|  | 474 | +	} | 
|---|
|  | 475 | +	strcpy(ret, a); | 
|---|
|  | 476 | +	strcat(ret, b); | 
|---|
|  | 477 | + | 
|---|
|  | 478 | +	return ret; | 
|---|
|  | 479 | +} | 
|---|
|  | 480 | + | 
|---|
|  | 481 | +static size_t get_partition_size(AvbOps *ops, char *name, | 
|---|
|  | 482 | +				 const char *slot_suffix) | 
|---|
|  | 483 | +{ | 
|---|
|  | 484 | +	char *partition_name = join_str(name, slot_suffix); | 
|---|
|  | 485 | +	uint64_t size = 0; | 
|---|
|  | 486 | +	AvbIOResult res; | 
|---|
|  | 487 | + | 
|---|
|  | 488 | +	if (partition_name == NULL) | 
|---|
|  | 489 | +		goto bail; | 
|---|
|  | 490 | + | 
|---|
|  | 491 | +	res = ops->get_size_of_partition(ops, partition_name, &size); | 
|---|
|  | 492 | +	if (res != AVB_IO_RESULT_OK && res != AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION) | 
|---|
|  | 493 | +		size = 0; | 
|---|
|  | 494 | +bail: | 
|---|
|  | 495 | +	if (partition_name) | 
|---|
|  | 496 | +		free(partition_name); | 
|---|
|  | 497 | + | 
|---|
|  | 498 | +	return size; | 
|---|
|  | 499 | +} | 
|---|
|  | 500 | + | 
|---|
|  | 501 | +static struct AvbOpsData preload_user_data; | 
|---|
|  | 502 | + | 
|---|
|  | 503 | +static int avb_image_distribute_prepare(AvbSlotVerifyData *slot_data, | 
|---|
|  | 504 | +					AvbOps *ops, char *slot_suffix) | 
|---|
|  | 505 | +{ | 
|---|
|  | 506 | +	struct AvbOpsData *data = (struct AvbOpsData *)(ops->user_data); | 
|---|
|  | 507 | +	size_t vendor_boot_size; | 
|---|
|  | 508 | +	size_t init_boot_size; | 
|---|
|  | 509 | +	size_t resource_size; | 
|---|
|  | 510 | +	size_t boot_size; | 
|---|
|  | 511 | +	void *image_buf; | 
|---|
|  | 512 | + | 
|---|
|  | 513 | +	boot_size = max(get_partition_size(ops, ANDROID_PARTITION_BOOT, slot_suffix), | 
|---|
|  | 514 | +		get_partition_size(ops, ANDROID_PARTITION_RECOVERY, slot_suffix)); | 
|---|
|  | 515 | +	init_boot_size = get_partition_size(ops, | 
|---|
|  | 516 | +				ANDROID_PARTITION_INIT_BOOT, slot_suffix); | 
|---|
|  | 517 | +	vendor_boot_size = get_partition_size(ops, | 
|---|
|  | 518 | +				ANDROID_PARTITION_VENDOR_BOOT, slot_suffix); | 
|---|
|  | 519 | +	resource_size = get_partition_size(ops, | 
|---|
|  | 520 | +				ANDROID_PARTITION_RESOURCE, slot_suffix); | 
|---|
|  | 521 | +	image_buf = sysmem_alloc(MEM_AVB_ANDROID, | 
|---|
|  | 522 | +				 boot_size + init_boot_size + | 
|---|
|  | 523 | +				 vendor_boot_size + resource_size); | 
|---|
|  | 524 | +	if (!image_buf) { | 
|---|
|  | 525 | +		printf("avb: sysmem alloc failed\n"); | 
|---|
|  | 526 | +		return -ENOMEM; | 
|---|
|  | 527 | +	} | 
|---|
|  | 528 | + | 
|---|
|  | 529 | +	/* layout: | boot/recovery | vendor_boot | init_boot | resource | */ | 
|---|
|  | 530 | +	data->slot_suffix = slot_suffix; | 
|---|
|  | 531 | +	data->boot.addr = image_buf; | 
|---|
|  | 532 | +	data->boot.size = 0; | 
|---|
|  | 533 | +	data->vendor_boot.addr = data->boot.addr + boot_size; | 
|---|
|  | 534 | +	data->vendor_boot.size = 0; | 
|---|
|  | 535 | +	data->init_boot.addr = data->vendor_boot.addr + vendor_boot_size; | 
|---|
|  | 536 | +	data->init_boot.size = 0; | 
|---|
|  | 537 | +	data->resource.addr = data->init_boot.addr + init_boot_size; | 
|---|
|  | 538 | +	data->resource.size = 0; | 
|---|
|  | 539 | + | 
|---|
|  | 540 | +	return 0; | 
|---|
|  | 541 | +} | 
|---|
|  | 542 | + | 
|---|
|  | 543 | +static int avb_image_distribute_finish(AvbSlotVerifyData *slot_data, | 
|---|
|  | 544 | +				       AvbSlotVerifyFlags flags, | 
|---|
|  | 545 | +				       ulong *load_address) | 
|---|
|  | 546 | +{ | 
|---|
|  | 547 | +	struct andr_img_hdr *hdr; | 
|---|
|  | 548 | +	ulong load_addr = *load_address; | 
|---|
|  | 549 | +	void *vendor_boot_hdr = NULL; | 
|---|
|  | 550 | +	void *init_boot_hdr = NULL; | 
|---|
|  | 551 | +	void *boot_hdr = NULL; | 
|---|
|  | 552 | +	char *part_name; | 
|---|
|  | 553 | +	int i, ret; | 
|---|
|  | 554 | + | 
|---|
|  | 555 | +	for (i = 0; i < slot_data->num_loaded_partitions; i++) { | 
|---|
|  | 556 | +		part_name = slot_data->loaded_partitions[i].partition_name; | 
|---|
|  | 557 | +		if (!strncmp(ANDROID_PARTITION_BOOT, part_name, 4) || | 
|---|
|  | 558 | +		    !strncmp(ANDROID_PARTITION_RECOVERY, part_name, 8)) { | 
|---|
|  | 559 | +			boot_hdr = slot_data->loaded_partitions[i].data; | 
|---|
|  | 560 | +		} else if (!strncmp(ANDROID_PARTITION_INIT_BOOT, part_name, 9)) { | 
|---|
|  | 561 | +			init_boot_hdr = slot_data->loaded_partitions[i].data; | 
|---|
|  | 562 | +		} else if (!strncmp(ANDROID_PARTITION_VENDOR_BOOT, part_name, 11)) { | 
|---|
|  | 563 | +			vendor_boot_hdr = slot_data->loaded_partitions[i].data; | 
|---|
|  | 564 | +		} | 
|---|
|  | 565 | +	} | 
|---|
|  | 566 | + | 
|---|
|  | 567 | +	/* | 
|---|
|  | 568 | +	 *		populate boot_img_hdr_v34 | 
|---|
|  | 569 | +	 * | 
|---|
|  | 570 | +	 * If allow verification error: the images are loaded by | 
|---|
|  | 571 | +	 * ops->get_preloaded_partition() which auto populates | 
|---|
|  | 572 | +	 * boot_img_hdr_v34. | 
|---|
|  | 573 | +	 * | 
|---|
|  | 574 | +	 * If not allow verification error: the images are full loaded | 
|---|
|  | 575 | +	 * by ops->read_from_partition() which doesn't populate | 
|---|
|  | 576 | +	 * boot_img_hdr_v34, we need to fix it here for bootm and | 
|---|
|  | 577 | +	 */ | 
|---|
|  | 578 | + | 
|---|
|  | 579 | +	hdr = boot_hdr; | 
|---|
|  | 580 | +	if (hdr->header_version >= 3 && | 
|---|
|  | 581 | +	    !(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR)) { | 
|---|
|  | 582 | +		hdr = malloc(sizeof(struct andr_img_hdr)); | 
|---|
|  | 583 | +		if (!hdr) | 
|---|
|  | 584 | +			return -ENOMEM; | 
|---|
|  | 585 | + | 
|---|
|  | 586 | +		ret = populate_boot_info(boot_hdr, vendor_boot_hdr, | 
|---|
|  | 587 | +					 init_boot_hdr, hdr, true); | 
|---|
|  | 588 | +		if (ret < 0) { | 
|---|
|  | 589 | +			printf("avb: populate boot info failed, ret=%d\n", ret); | 
|---|
|  | 590 | +			return ret; | 
|---|
|  | 591 | +		} | 
|---|
|  | 592 | +		memcpy(boot_hdr, hdr, sizeof(*hdr)); | 
|---|
|  | 593 | +	} | 
|---|
|  | 594 | + | 
|---|
|  | 595 | +	/* distribute ! */ | 
|---|
|  | 596 | +	load_addr -= hdr->page_size; | 
|---|
|  | 597 | +	if (android_image_memcpy_separate(boot_hdr, &load_addr)) { | 
|---|
|  | 598 | +		printf("Failed to separate copy android image\n"); | 
|---|
|  | 599 | +		return AVB_SLOT_VERIFY_RESULT_ERROR_IO; | 
|---|
|  | 600 | +	} | 
|---|
|  | 601 | + | 
|---|
|  | 602 | +	*load_address = load_addr; | 
|---|
|  | 603 | + | 
|---|
|  | 604 | +	return 0; | 
|---|
|  | 605 | +} | 
|---|
|  | 606 | + | 
|---|
|  | 607 | +int android_image_verify_resource(const char *boot_part, ulong *resc_buf) | 
|---|
|  | 608 | +{ | 
|---|
|  | 609 | +	const char *requested_partitions[] = { | 
|---|
|  | 610 | +		NULL, | 
|---|
|  | 611 | +		NULL, | 
|---|
|  | 612 | +	}; | 
|---|
|  | 613 | +	struct AvbOpsData *data; | 
|---|
|  | 614 | +	uint8_t unlocked = true; | 
|---|
|  | 615 | +	AvbOps *ops; | 
|---|
|  | 616 | +	AvbSlotVerifyFlags flags; | 
|---|
|  | 617 | +	AvbSlotVerifyData *slot_data = {NULL}; | 
|---|
|  | 618 | +	AvbSlotVerifyResult verify_result; | 
|---|
|  | 619 | +	char slot_suffix[3] = {0}; | 
|---|
|  | 620 | +	char *part_name; | 
|---|
|  | 621 | +	void *image_buf = NULL; | 
|---|
|  | 622 | +	int retry_no_vbmeta_partition = 1; | 
|---|
|  | 623 | +	int i, ret; | 
|---|
|  | 624 | + | 
|---|
|  | 625 | +	ops = avb_ops_user_new(); | 
|---|
|  | 626 | +	if (ops == NULL) { | 
|---|
|  | 627 | +		printf("avb_ops_user_new() failed!\n"); | 
|---|
|  | 628 | +		return -AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 
|---|
|  | 629 | +	} | 
|---|
|  | 630 | + | 
|---|
|  | 631 | +	if (ops->read_is_device_unlocked(ops, (bool *)&unlocked) != AVB_IO_RESULT_OK) | 
|---|
|  | 632 | +		printf("Error determining whether device is unlocked.\n"); | 
|---|
|  | 633 | + | 
|---|
|  | 634 | +	printf("Device is: %s\n", (unlocked & LOCK_MASK)? "UNLOCKED" : "LOCKED"); | 
|---|
|  | 635 | + | 
|---|
|  | 636 | +	if (unlocked & LOCK_MASK) { | 
|---|
|  | 637 | +		*resc_buf = 0; | 
|---|
|  | 638 | +		return 0; | 
|---|
|  | 639 | +	} | 
|---|
|  | 640 | + | 
|---|
|  | 641 | +	flags = AVB_SLOT_VERIFY_FLAGS_NONE; | 
|---|
|  | 642 | +	if (strcmp(boot_part, ANDROID_PARTITION_RECOVERY) == 0) | 
|---|
|  | 643 | +		flags |= AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION; | 
|---|
|  | 644 | + | 
|---|
|  | 645 | +#ifdef CONFIG_ANDROID_AB | 
|---|
|  | 646 | +	part_name = strdup(boot_part); | 
|---|
|  | 647 | +	*(part_name + strlen(boot_part) - 2) = '\0'; | 
|---|
|  | 648 | +	requested_partitions[0] = part_name; | 
|---|
|  | 649 | + | 
|---|
|  | 650 | +	ret = rk_avb_get_current_slot(slot_suffix); | 
|---|
|  | 651 | +	if (ret) { | 
|---|
|  | 652 | +		printf("Failed to get slot suffix, ret=%d\n", ret); | 
|---|
|  | 653 | +		return ret; | 
|---|
|  | 654 | +	} | 
|---|
|  | 655 | +#else | 
|---|
|  | 656 | +	requested_partitions[0] = boot_part; | 
|---|
|  | 657 | +#endif | 
|---|
|  | 658 | +	data = (struct AvbOpsData *)(ops->user_data); | 
|---|
|  | 659 | +	ret = avb_image_distribute_prepare(slot_data, ops, slot_suffix); | 
|---|
|  | 660 | +	if (ret) { | 
|---|
|  | 661 | +		printf("avb image distribute prepare failed %d\n", ret); | 
|---|
|  | 662 | +		return ret; | 
|---|
|  | 663 | +	} | 
|---|
|  | 664 | + | 
|---|
|  | 665 | +retry_verify: | 
|---|
|  | 666 | +	verify_result = | 
|---|
|  | 667 | +	avb_slot_verify(ops, | 
|---|
|  | 668 | +			requested_partitions, | 
|---|
|  | 669 | +			slot_suffix, | 
|---|
|  | 670 | +			flags, | 
|---|
|  | 671 | +			AVB_HASHTREE_ERROR_MODE_RESTART, | 
|---|
|  | 672 | +			&slot_data); | 
|---|
|  | 673 | +	if (verify_result != AVB_SLOT_VERIFY_RESULT_OK && | 
|---|
|  | 674 | +	    verify_result != AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED) { | 
|---|
|  | 675 | +		if (retry_no_vbmeta_partition && strcmp(boot_part, ANDROID_PARTITION_RECOVERY) == 0) { | 
|---|
|  | 676 | +			printf("Verify recovery with vbmeta.\n"); | 
|---|
|  | 677 | +			flags &= ~AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION; | 
|---|
|  | 678 | +			retry_no_vbmeta_partition = 0; | 
|---|
|  | 679 | +			goto retry_verify; | 
|---|
|  | 680 | +		} | 
|---|
|  | 681 | +	} | 
|---|
|  | 682 | + | 
|---|
|  | 683 | +	if (verify_result != AVB_SLOT_VERIFY_RESULT_OK || !slot_data) { | 
|---|
|  | 684 | +		sysmem_free((ulong)data->boot.addr); | 
|---|
|  | 685 | +		return verify_result; | 
|---|
|  | 686 | +	} | 
|---|
|  | 687 | + | 
|---|
|  | 688 | +	for (i = 0; i < slot_data->num_loaded_partitions; i++) { | 
|---|
|  | 689 | +		part_name = slot_data->loaded_partitions[i].partition_name; | 
|---|
|  | 690 | +		if (!strncmp(ANDROID_PARTITION_RESOURCE, part_name, 8)) { | 
|---|
|  | 691 | +			image_buf = slot_data->loaded_partitions[i].data; | 
|---|
|  | 692 | +			break; | 
|---|
|  | 693 | +		} else if (!strncmp(ANDROID_PARTITION_BOOT, part_name, 4) || | 
|---|
|  | 694 | +			   !strncmp(ANDROID_PARTITION_RECOVERY, part_name, 8)) { | 
|---|
|  | 695 | +			struct andr_img_hdr *hdr; | 
|---|
|  | 696 | + | 
|---|
|  | 697 | +			hdr = (void *)slot_data->loaded_partitions[i].data; | 
|---|
|  | 698 | +			if (android_image_check_header(hdr)) | 
|---|
|  | 699 | +				continue; | 
|---|
|  | 700 | + | 
|---|
|  | 701 | +			if (hdr->header_version <= 2) { | 
|---|
|  | 702 | +				image_buf = (void *)hdr + hdr->page_size + | 
|---|
|  | 703 | +					ALIGN(hdr->kernel_size, hdr->page_size) + | 
|---|
|  | 704 | +					ALIGN(hdr->ramdisk_size, hdr->page_size); | 
|---|
|  | 705 | +				break; | 
|---|
|  | 706 | +			} | 
|---|
|  | 707 | +		} | 
|---|
|  | 708 | +	} | 
|---|
|  | 709 | + | 
|---|
|  | 710 | +	if (image_buf) { | 
|---|
|  | 711 | +		memcpy((char *)&preload_user_data, (char *)data, sizeof(*data)); | 
|---|
|  | 712 | +		*resc_buf = (ulong)image_buf; | 
|---|
|  | 713 | +	} | 
|---|
|  | 714 | + | 
|---|
|  | 715 | +	return 0; | 
|---|
|  | 716 | +} | 
|---|
|  | 717 | + | 
|---|
|  | 718 | +/* | 
|---|
|  | 719 | + *		AVB Policy. | 
|---|
|  | 720 | + * | 
|---|
|  | 721 | + * == avb with unlock: | 
|---|
|  | 722 | + * Don't process hash verify. | 
|---|
|  | 723 | + * Go pre-loaded path: Loading vendor_boot and init_boot | 
|---|
|  | 724 | + * directly to where they should be, while loading the | 
|---|
|  | 725 | + * boot/recovery. The boot message tells like: | 
|---|
|  | 726 | + * ··· | 
|---|
|  | 727 | + * preloaded: distribute image from 'boot_a' | 
|---|
|  | 728 | + * preloaded: distribute image from 'init_boot_a' | 
|---|
|  | 729 | + * preloaded: distribute image from 'vendor_boot_a' | 
|---|
|  | 730 | + * ··· | 
|---|
|  | 731 | + * | 
|---|
|  | 732 | + * == avb with lock: | 
|---|
|  | 733 | + * Process hash verify. | 
|---|
|  | 734 | + * Go pre-loaded path: Loading full vendor_boot, init_boot and | 
|---|
|  | 735 | + * boot/recovery one by one to verify, and distributing them to | 
|---|
|  | 736 | + * where they should be by memcpy at last. | 
|---|
|  | 737 | + * | 
|---|
|  | 738 | + * The three images share a large memory buffer that allocated | 
|---|
|  | 739 | + * by sysmem_alloc(), it locate at high memory address that | 
|---|
|  | 740 | + * just lower than SP bottom. The boot message tells like: | 
|---|
|  | 741 | + * ··· | 
|---|
|  | 742 | + * preloaded: full image from 'boot_a' at 0xe47f90c0 - 0xe7a4b0c0 | 
|---|
|  | 743 | + * preloaded: full image from 'init_boot_a' at 0xeaff90c0 - 0xeb2950c0 | 
|---|
|  | 744 | + * preloaded: full image from 'vendor_boot_a' at 0xe87f90c0 - 0xe9f6e0c0 | 
|---|
|  | 745 | + * ··· | 
|---|
|  | 746 | + */ | 
|---|
| 465 | 747 | static AvbSlotVerifyResult android_slot_verify(char *boot_partname, | 
|---|
| 466 | 748 | unsigned long *android_load_address, | 
|---|
| 467 | 749 | char *slot_suffix) | 
|---|
| 468 | 750 | { | 
|---|
| 469 |  | -	const char *requested_partitions[1] = {NULL}; | 
|---|
|  | 751 | +	const char *requested_partitions[] = { | 
|---|
|  | 752 | +		boot_partname, | 
|---|
|  | 753 | +		NULL, | 
|---|
|  | 754 | +		NULL, | 
|---|
|  | 755 | +		NULL, | 
|---|
|  | 756 | +	}; | 
|---|
|  | 757 | +	struct AvbOpsData *data; | 
|---|
|  | 758 | +	struct blk_desc *dev_desc; | 
|---|
|  | 759 | +	struct andr_img_hdr *hdr; | 
|---|
|  | 760 | +	disk_partition_t part_info; | 
|---|
| 470 | 761 | uint8_t unlocked = true; | 
|---|
| 471 | 762 | AvbOps *ops; | 
|---|
| 472 | 763 | AvbSlotVerifyFlags flags; | 
|---|
| 473 |  | -	AvbSlotVerifyData *slot_data[1] = {NULL}; | 
|---|
|  | 764 | +	AvbSlotVerifyData *slot_data = {NULL}; | 
|---|
| 474 | 765 | AvbSlotVerifyResult verify_result; | 
|---|
| 475 | 766 | AvbABData ab_data, ab_data_orig; | 
|---|
| 476 | 767 | size_t slot_index_to_boot = 0; | 
|---|
| .. | .. | 
|---|
| 478 | 769 | char can_boot = 1; | 
|---|
| 479 | 770 | char retry_no_vbmeta_partition = 1; | 
|---|
| 480 | 771 | unsigned long load_address = *android_load_address; | 
|---|
| 481 |  | -	struct andr_img_hdr *hdr; | 
|---|
|  | 772 | +	int ret; | 
|---|
| 482 | 773 |  | 
|---|
| 483 |  | -	requested_partitions[0] = boot_partname; | 
|---|
|  | 774 | +	dev_desc = rockchip_get_bootdev(); | 
|---|
|  | 775 | +	if (!dev_desc) | 
|---|
|  | 776 | +		return AVB_IO_RESULT_ERROR_IO; | 
|---|
|  | 777 | + | 
|---|
|  | 778 | +	if (part_get_info_by_name(dev_desc, boot_partname, &part_info) < 0) { | 
|---|
|  | 779 | +		printf("Could not find \"%s\" partition\n", boot_partname); | 
|---|
|  | 780 | +		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; | 
|---|
|  | 781 | +	} | 
|---|
|  | 782 | + | 
|---|
|  | 783 | +	hdr = populate_andr_img_hdr(dev_desc, &part_info); | 
|---|
|  | 784 | +	if (!hdr) { | 
|---|
|  | 785 | +		printf("No valid android hdr\n"); | 
|---|
|  | 786 | +		return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; | 
|---|
|  | 787 | +	} | 
|---|
|  | 788 | + | 
|---|
|  | 789 | +	if (hdr->header_version >= 4) { | 
|---|
|  | 790 | +		requested_partitions[1] = ANDROID_PARTITION_VENDOR_BOOT; | 
|---|
|  | 791 | +		if (((hdr->os_version >> 25) & 0x7f) >= 13) | 
|---|
|  | 792 | +			requested_partitions[2] = ANDROID_PARTITION_INIT_BOOT; | 
|---|
|  | 793 | +	} | 
|---|
|  | 794 | + | 
|---|
| 484 | 795 | ops = avb_ops_user_new(); | 
|---|
| 485 | 796 | if (ops == NULL) { | 
|---|
| 486 | 797 | printf("avb_ops_user_new() failed!\n"); | 
|---|
| .. | .. | 
|---|
| 497 | 808 | if (unlocked & LOCK_MASK) | 
|---|
| 498 | 809 | flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR; | 
|---|
| 499 | 810 |  | 
|---|
| 500 |  | -	if(load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) { | 
|---|
|  | 811 | +	if (load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) { | 
|---|
| 501 | 812 | printf("Can not load metadata\n"); | 
|---|
| 502 | 813 | return AVB_SLOT_VERIFY_RESULT_ERROR_IO; | 
|---|
| 503 | 814 | } | 
|---|
| .. | .. | 
|---|
| 509 | 820 | else | 
|---|
| 510 | 821 | slot_index_to_boot = 0; | 
|---|
| 511 | 822 |  | 
|---|
| 512 |  | -	if (strcmp(boot_partname, "recovery") == 0) | 
|---|
|  | 823 | +	if (strcmp(boot_partname, ANDROID_PARTITION_RECOVERY) == 0) | 
|---|
| 513 | 824 | flags |= AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION; | 
|---|
|  | 825 | + | 
|---|
|  | 826 | +#ifdef CONFIG_MP_BOOT | 
|---|
|  | 827 | +	preload_user_data.boot.addr = (void *)mpb_post(1); | 
|---|
|  | 828 | +	preload_user_data.boot.size = (size_t)mpb_post(2); | 
|---|
|  | 829 | +#endif | 
|---|
|  | 830 | + | 
|---|
|  | 831 | +	/* use preload one if available */ | 
|---|
|  | 832 | +	if (preload_user_data.boot.addr) { | 
|---|
|  | 833 | +		data = (struct AvbOpsData *)(ops->user_data); | 
|---|
|  | 834 | + | 
|---|
|  | 835 | +		data->slot_suffix = slot_suffix; | 
|---|
|  | 836 | +		data->boot = preload_user_data.boot; | 
|---|
|  | 837 | +		data->vendor_boot = preload_user_data.vendor_boot; | 
|---|
|  | 838 | +		data->init_boot = preload_user_data.init_boot; | 
|---|
|  | 839 | +		data->resource = preload_user_data.resource; | 
|---|
|  | 840 | +	} else { | 
|---|
|  | 841 | +		ret = avb_image_distribute_prepare(slot_data, ops, slot_suffix); | 
|---|
|  | 842 | +		if (ret < 0) { | 
|---|
|  | 843 | +			printf("avb image distribute prepare failed %d\n", ret); | 
|---|
|  | 844 | +			return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 
|---|
|  | 845 | +		} | 
|---|
|  | 846 | +	} | 
|---|
| 514 | 847 |  | 
|---|
| 515 | 848 | retry_verify: | 
|---|
| 516 | 849 | verify_result = | 
|---|
| .. | .. | 
|---|
| 519 | 852 | slot_suffix, | 
|---|
| 520 | 853 | flags, | 
|---|
| 521 | 854 | AVB_HASHTREE_ERROR_MODE_RESTART, | 
|---|
| 522 |  | -			&slot_data[0]); | 
|---|
|  | 855 | +			&slot_data); | 
|---|
| 523 | 856 | if (verify_result != AVB_SLOT_VERIFY_RESULT_OK && | 
|---|
| 524 | 857 | verify_result != AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED) { | 
|---|
| 525 |  | -		if (retry_no_vbmeta_partition && strcmp(boot_partname, "recovery") == 0) { | 
|---|
|  | 858 | +		if (retry_no_vbmeta_partition && strcmp(boot_partname, ANDROID_PARTITION_RECOVERY) == 0) { | 
|---|
| 526 | 859 | printf("Verify recovery with vbmeta.\n"); | 
|---|
| 527 | 860 | flags &= ~AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION; | 
|---|
| 528 | 861 | retry_no_vbmeta_partition = 0; | 
|---|
| .. | .. | 
|---|
| 558 | 891 | break; | 
|---|
| 559 | 892 | } | 
|---|
| 560 | 893 |  | 
|---|
| 561 |  | -	if (!slot_data[0]) { | 
|---|
|  | 894 | +	if (!slot_data) { | 
|---|
| 562 | 895 | can_boot = 0; | 
|---|
| 563 | 896 | goto out; | 
|---|
| 564 | 897 | } | 
|---|
| .. | .. | 
|---|
| 569 | 902 | int len = 0; | 
|---|
| 570 | 903 | char *bootargs, *newbootargs; | 
|---|
| 571 | 904 | #ifdef CONFIG_ANDROID_AVB_ROLLBACK_INDEX | 
|---|
| 572 |  | -		if (rk_avb_update_stored_rollback_indexes_for_slot(ops, slot_data[0])) | 
|---|
|  | 905 | +		if (rk_avb_update_stored_rollback_indexes_for_slot(ops, slot_data)) | 
|---|
| 573 | 906 | printf("Fail to update the rollback indexes.\n"); | 
|---|
| 574 | 907 | #endif | 
|---|
| 575 |  | -		if (*slot_data[0]->cmdline) { | 
|---|
| 576 |  | -			debug("Kernel command line: %s\n", slot_data[0]->cmdline); | 
|---|
| 577 |  | -			len += strlen(slot_data[0]->cmdline); | 
|---|
|  | 908 | +		if (slot_data->cmdline) { | 
|---|
|  | 909 | +			debug("Kernel command line: %s\n", slot_data->cmdline); | 
|---|
|  | 910 | +			len += strlen(slot_data->cmdline); | 
|---|
| 578 | 911 | } | 
|---|
| 579 | 912 |  | 
|---|
| 580 | 913 | bootargs = env_get("bootargs"); | 
|---|
| .. | .. | 
|---|
| 593 | 926 | strcpy(newbootargs, bootargs); | 
|---|
| 594 | 927 | strcat(newbootargs, " "); | 
|---|
| 595 | 928 | } | 
|---|
| 596 |  | -		if (*slot_data[0]->cmdline) | 
|---|
| 597 |  | -			strcat(newbootargs, slot_data[0]->cmdline); | 
|---|
|  | 929 | +		if (slot_data->cmdline) | 
|---|
|  | 930 | +			strcat(newbootargs, slot_data->cmdline); | 
|---|
| 598 | 931 | env_set("bootargs", newbootargs); | 
|---|
| 599 | 932 |  | 
|---|
| 600 |  | -		hdr = (void *)slot_data[0]->loaded_partitions->data; | 
|---|
| 601 |  | - | 
|---|
| 602 |  | -		/* | 
|---|
| 603 |  | -		 *		populate boot_img_hdr_v34 | 
|---|
| 604 |  | -		 * | 
|---|
| 605 |  | -		 * If allow verification error: the image is loaded by | 
|---|
| 606 |  | -		 * ops->get_preloaded_partition() which auto populates | 
|---|
| 607 |  | -		 * boot_img_hdr_v34. | 
|---|
| 608 |  | -		 * | 
|---|
| 609 |  | -		 * If not allow verification error: the image is full loaded | 
|---|
| 610 |  | -		 * by ops->read_from_partition() which doesn't populate | 
|---|
| 611 |  | -		 * boot_img_hdr_v34, we need to fix it here. | 
|---|
| 612 |  | -		 */ | 
|---|
| 613 |  | -		if (hdr->header_version >= 3 && | 
|---|
| 614 |  | -		    !(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR)) { | 
|---|
| 615 |  | -			struct andr_img_hdr *v3hdr; | 
|---|
| 616 |  | -			struct blk_desc *dev_desc; | 
|---|
| 617 |  | -			disk_partition_t part; | 
|---|
| 618 |  | - | 
|---|
| 619 |  | -			dev_desc = rockchip_get_bootdev(); | 
|---|
| 620 |  | -			if (!dev_desc) | 
|---|
| 621 |  | -				return -1; | 
|---|
| 622 |  | - | 
|---|
| 623 |  | -			if (part_get_info_by_name(dev_desc, | 
|---|
| 624 |  | -						  boot_partname, &part) < 0) | 
|---|
| 625 |  | -				return -1; | 
|---|
| 626 |  | - | 
|---|
| 627 |  | -			v3hdr = populate_andr_img_hdr(dev_desc, &part); | 
|---|
| 628 |  | -			if (v3hdr) { | 
|---|
| 629 |  | -				memcpy(hdr, v3hdr, sizeof(*v3hdr)); | 
|---|
| 630 |  | -				free(v3hdr); | 
|---|
| 631 |  | -			} | 
|---|
| 632 |  | -		} | 
|---|
| 633 |  | - | 
|---|
| 634 |  | -		/* Reserve page_size */ | 
|---|
| 635 |  | -		load_address -= hdr->page_size; | 
|---|
| 636 |  | -		if (android_image_memcpy_separate(hdr, &load_address)) { | 
|---|
| 637 |  | -			printf("Failed to separate copy android image\n"); | 
|---|
| 638 |  | -			return AVB_SLOT_VERIFY_RESULT_ERROR_IO; | 
|---|
|  | 933 | +		/* if need, distribute full image to where they should be */ | 
|---|
|  | 934 | +		ret = avb_image_distribute_finish(slot_data, flags, &load_address); | 
|---|
|  | 935 | +		if (ret) { | 
|---|
|  | 936 | +			printf("avb image distribute finish failed %d\n", ret); | 
|---|
|  | 937 | +			return ret; | 
|---|
| 639 | 938 | } | 
|---|
| 640 | 939 | *android_load_address = load_address; | 
|---|
| 641 | 940 | } else { | 
|---|
| .. | .. | 
|---|
| 649 | 948 | verify_result = AVB_SLOT_VERIFY_RESULT_ERROR_IO; | 
|---|
| 650 | 949 | } | 
|---|
| 651 | 950 |  | 
|---|
| 652 |  | -	if (slot_data[0] != NULL) | 
|---|
| 653 |  | -		avb_slot_verify_data_free(slot_data[0]); | 
|---|
|  | 951 | +	if (slot_data != NULL) | 
|---|
|  | 952 | +		avb_slot_verify_data_free(slot_data); | 
|---|
| 654 | 953 |  | 
|---|
| 655 | 954 | if ((unlocked & LOCK_MASK) && can_boot) | 
|---|
| 656 | 955 | return 0; | 
|---|
| .. | .. | 
|---|
| 1047 | 1346 | printf("Android image load failed\n"); | 
|---|
| 1048 | 1347 | return -1; | 
|---|
| 1049 | 1348 | } | 
|---|
| 1050 |  | -#endif | 
|---|
| 1051 |  | - | 
|---|
| 1052 |  | -#ifdef CONFIG_ANDROID_AB | 
|---|
| 1053 |  | -	ab_update_root_uuid(); | 
|---|
| 1054 | 1349 | #endif | 
|---|
| 1055 | 1350 |  | 
|---|
| 1056 | 1351 | /* Set Android root variables. */ | 
|---|