hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
u-boot/common/android_bootloader.c
....@@ -18,6 +18,7 @@
1818 #include <dt_table.h>
1919 #include <image-android-dt.h>
2020 #include <malloc.h>
21
+#include <mp_boot.h>
2122 #include <fdt_support.h>
2223 #include <fs.h>
2324 #include <boot_rkimg.h>
....@@ -462,15 +463,305 @@
462463 slot->successful_boot = 0;
463464 }
464465
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
+ */
465747 static AvbSlotVerifyResult android_slot_verify(char *boot_partname,
466748 unsigned long *android_load_address,
467749 char *slot_suffix)
468750 {
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;
470761 uint8_t unlocked = true;
471762 AvbOps *ops;
472763 AvbSlotVerifyFlags flags;
473
- AvbSlotVerifyData *slot_data[1] = {NULL};
764
+ AvbSlotVerifyData *slot_data = {NULL};
474765 AvbSlotVerifyResult verify_result;
475766 AvbABData ab_data, ab_data_orig;
476767 size_t slot_index_to_boot = 0;
....@@ -478,9 +769,29 @@
478769 char can_boot = 1;
479770 char retry_no_vbmeta_partition = 1;
480771 unsigned long load_address = *android_load_address;
481
- struct andr_img_hdr *hdr;
772
+ int ret;
482773
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
+
484795 ops = avb_ops_user_new();
485796 if (ops == NULL) {
486797 printf("avb_ops_user_new() failed!\n");
....@@ -497,7 +808,7 @@
497808 if (unlocked & LOCK_MASK)
498809 flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR;
499810
500
- if(load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) {
811
+ if (load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) {
501812 printf("Can not load metadata\n");
502813 return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
503814 }
....@@ -509,8 +820,30 @@
509820 else
510821 slot_index_to_boot = 0;
511822
512
- if (strcmp(boot_partname, "recovery") == 0)
823
+ if (strcmp(boot_partname, ANDROID_PARTITION_RECOVERY) == 0)
513824 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
+ }
514847
515848 retry_verify:
516849 verify_result =
....@@ -519,10 +852,10 @@
519852 slot_suffix,
520853 flags,
521854 AVB_HASHTREE_ERROR_MODE_RESTART,
522
- &slot_data[0]);
855
+ &slot_data);
523856 if (verify_result != AVB_SLOT_VERIFY_RESULT_OK &&
524857 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) {
526859 printf("Verify recovery with vbmeta.\n");
527860 flags &= ~AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION;
528861 retry_no_vbmeta_partition = 0;
....@@ -558,7 +891,7 @@
558891 break;
559892 }
560893
561
- if (!slot_data[0]) {
894
+ if (!slot_data) {
562895 can_boot = 0;
563896 goto out;
564897 }
....@@ -569,12 +902,12 @@
569902 int len = 0;
570903 char *bootargs, *newbootargs;
571904 #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))
573906 printf("Fail to update the rollback indexes.\n");
574907 #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);
578911 }
579912
580913 bootargs = env_get("bootargs");
....@@ -593,49 +926,15 @@
593926 strcpy(newbootargs, bootargs);
594927 strcat(newbootargs, " ");
595928 }
596
- if (*slot_data[0]->cmdline)
597
- strcat(newbootargs, slot_data[0]->cmdline);
929
+ if (slot_data->cmdline)
930
+ strcat(newbootargs, slot_data->cmdline);
598931 env_set("bootargs", newbootargs);
599932
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;
639938 }
640939 *android_load_address = load_address;
641940 } else {
....@@ -649,8 +948,8 @@
649948 verify_result = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
650949 }
651950
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);
654953
655954 if ((unlocked & LOCK_MASK) && can_boot)
656955 return 0;
....@@ -1047,10 +1346,6 @@
10471346 printf("Android image load failed\n");
10481347 return -1;
10491348 }
1050
-#endif
1051
-
1052
-#ifdef CONFIG_ANDROID_AB
1053
- ab_update_root_uuid();
10541349 #endif
10551350
10561351 /* Set Android root variables. */