1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #include <android_bootloader.h> 8 #include <android_avb/avb_version.h> 9 #include <android_avb/avb_ab_flow.h> 10 #include <android_avb/avb_ops_user.h> 11 #include <android_cmds.h> 12 #include <malloc.h> 13 #include <common.h> 14 #include <bootm.h> 15 #include <command.h> 16 #include <android_bootloader_message.h> 17 #include <android_avb/rk_avb_ops_user.h> 18 #include <android_avb/avb_atx_ops.h> 19 20 static int do_boot_android(cmd_tbl_t *cmdtp, int flag, int argc, 21 char * const argv[]) 22 { 23 unsigned long load_address; 24 int ret = CMD_RET_SUCCESS; 25 char *addr_arg_endp, *addr_str; 26 struct blk_desc *dev_desc; 27 28 if (argc < 3) 29 return CMD_RET_USAGE; 30 if (argc > 5) 31 return CMD_RET_USAGE; 32 33 if (argc >= 5) { 34 load_address = simple_strtoul(argv[4], &addr_arg_endp, 16); 35 if (addr_arg_endp == argv[4] || *addr_arg_endp != '\0') 36 return CMD_RET_USAGE; 37 } else { 38 addr_str = env_get("kernel_addr_r"); 39 if (addr_str) 40 load_address = simple_strtoul(addr_str, NULL, 16); 41 else 42 load_address = CONFIG_SYS_LOAD_ADDR; 43 } 44 45 #if defined(CONFIG_ARM64) 46 /* ARM64 kernel load addr need to align to 0x80000, and android boot.img 47 * have a 2KB header, need to reserve space for it. 48 */ 49 load_address &= ~0x7ffff; 50 #endif 51 52 dev_desc = blk_get_dev(argv[1], simple_strtoul(argv[2], NULL, 16)); 53 if (!dev_desc) { 54 printf("Could not get %s %s\n", argv[1], argv[2]); 55 return CMD_RET_FAILURE; 56 } 57 58 ret = android_bootloader_boot_flow(dev_desc, load_address); 59 if (ret < 0) { 60 printf("Android boot failed, error %d.\n", ret); 61 return CMD_RET_FAILURE; 62 } 63 return CMD_RET_SUCCESS; 64 } 65 66 U_BOOT_CMD( 67 boot_android, 5, 0, do_boot_android, 68 "Execute the Android Bootloader flow.", 69 "<interface> <dev[:part|;part_name]> <slot> [<kernel_addr>]\n" 70 " - Load the Boot Control Block (BCB) from the partition 'part' on\n" 71 " device type 'interface' instance 'dev' to determine the boot\n" 72 " mode, and load and execute the appropriate kernel.\n" 73 " In normal and recovery mode, the kernel will be loaded from\n" 74 " the corresponding \"boot\" partition. In bootloader mode, the\n" 75 " command defined in the \"fastbootcmd\" variable will be\n" 76 " executed.\n" 77 " On Android devices with multiple slots, the pass 'slot' is\n" 78 " used to load the appropriate kernel. The standard slot names\n" 79 " are 'a' and 'b'.\n" 80 " - If 'part_name' is passed, preceded with a ; instead of :, the\n" 81 " partition name whose label is 'part_name' will be looked up in\n" 82 " the partition table. This is commonly the \"misc\" partition.\n" 83 ); 84 85 #ifdef CONFIG_RK_AVB_LIBAVB_USER 86 static int bootloader_message_read(struct android_bootloader_message *data) 87 { 88 AvbOps *ops; 89 char requested_partitions[] = "misc"; 90 size_t out_num_read; 91 char *buffer; 92 93 ops = avb_ops_user_new(); 94 buffer = (char *)data; 95 96 if (ops == NULL) { 97 printf("avb_ops_user_new() failed!\n"); 98 return CMD_RET_FAILURE; 99 } 100 101 if (ops->read_from_partition(ops, requested_partitions, 102 0, 2048, buffer, 103 &out_num_read) != 0) { 104 printf("do avb read error!\n"); 105 avb_ops_user_free(ops); 106 return CMD_RET_FAILURE; 107 } 108 109 avb_ops_user_free(ops); 110 111 return CMD_RET_SUCCESS; 112 } 113 114 static int bootloader_message_write(struct android_bootloader_message *data) 115 { 116 AvbOps *ops; 117 char requested_partitions[] = "misc"; 118 char *buffer; 119 120 ops = avb_ops_user_new(); 121 buffer = (char *)data; 122 123 if (ops == NULL) { 124 printf("avb_ops_user_new() failed!\n"); 125 return CMD_RET_FAILURE; 126 } 127 128 if (ops->write_to_partition(ops, requested_partitions, 129 0, 2048, buffer) != 0) { 130 printf("do avb write error!\n"); 131 avb_ops_user_free(ops); 132 return CMD_RET_FAILURE; 133 } 134 135 avb_ops_user_free(ops); 136 137 return CMD_RET_SUCCESS; 138 } 139 140 int do_avb_init_ab_metadata(cmd_tbl_t *cmdtp, int flag, 141 int argc, char * const argv[]) 142 { 143 AvbOps *ops; 144 AvbABData ab_data; 145 146 memset(&ab_data, 0, sizeof(AvbABData)); 147 debug("sizeof(AvbABData) = %d\n", (int)(size_t)sizeof(AvbABData)); 148 if (argc != 1) 149 return CMD_RET_USAGE; 150 151 ops = avb_ops_user_new(); 152 if (ops == NULL) { 153 printf("avb_ops_user_new() failed!\n"); 154 return CMD_RET_FAILURE; 155 } 156 157 avb_ab_data_init(&ab_data); 158 if (ops->ab_ops->write_ab_metadata(ops->ab_ops, &ab_data) != 0) { 159 printf("do_avb_init_ab_metadata error!\n"); 160 avb_ops_user_free(ops); 161 return CMD_RET_FAILURE; 162 } 163 164 printf("Initialize ab data to misc partition success.\n"); 165 avb_ops_user_free(ops); 166 167 return CMD_RET_SUCCESS; 168 } 169 170 int do_avb_version(cmd_tbl_t *cmdtp, int flag, int argc, 171 char * const argv[]) 172 { 173 const char *avb_version; 174 175 if (argc != 1) 176 return CMD_RET_USAGE; 177 178 avb_version = avb_version_string(); 179 printf("Android avb version is %s.\n", avb_version); 180 181 return CMD_RET_SUCCESS; 182 } 183 184 int do_avb_ab_mark_slot_active(cmd_tbl_t *cmdtp, int flag, 185 int argc, char * const argv[]) 186 { 187 AvbOps *ops; 188 unsigned int slot_number; 189 190 if (argc != 2) 191 return CMD_RET_USAGE; 192 193 ops = avb_ops_user_new(); 194 if (ops == NULL) { 195 printf("avb_ops_user_new() failed!\n"); 196 return CMD_RET_FAILURE; 197 } 198 199 slot_number = simple_strtoul(argv[1], NULL, 16); 200 if (avb_ab_mark_slot_active(ops->ab_ops, slot_number) != 0) { 201 printf("avb_ab_mark_slot_active error!\n"); 202 avb_ops_user_free(ops); 203 return CMD_RET_FAILURE; 204 } 205 206 printf("Mark slot %d active successfully.\n", slot_number); 207 avb_ops_user_free(ops); 208 209 return CMD_RET_SUCCESS; 210 } 211 212 int do_avb_ab_mark_slot_unbootable(cmd_tbl_t *cmdtp, int flag, 213 int argc, char * const argv[]) 214 { 215 AvbOps *ops; 216 unsigned int slot_number; 217 218 if (argc != 2) 219 return CMD_RET_USAGE; 220 221 ops = avb_ops_user_new(); 222 if (ops == NULL) { 223 printf("avb_ops_user_new() failed!\n"); 224 return CMD_RET_FAILURE; 225 } 226 227 slot_number = simple_strtoul(argv[1], NULL, 16); 228 if (avb_ab_mark_slot_unbootable(ops->ab_ops, slot_number) != 0) { 229 printf("do_avb_ab_mark_slot_unbootable error!\n"); 230 avb_ops_user_free(ops); 231 return CMD_RET_FAILURE; 232 } 233 234 printf("Mark slot %d unbootable successfully.\n", slot_number); 235 avb_ops_user_free(ops); 236 237 return CMD_RET_SUCCESS; 238 } 239 240 int do_avb_ab_mark_slot_successful(cmd_tbl_t *cmdtp, int flag, 241 int argc, char * const argv[]) 242 { 243 AvbOps *ops; 244 unsigned int slot_number; 245 246 if (argc != 2) 247 return CMD_RET_USAGE; 248 249 ops = avb_ops_user_new(); 250 if (ops == NULL) { 251 printf("avb_ops_user_new() failed!\n"); 252 return CMD_RET_FAILURE; 253 } 254 255 slot_number = simple_strtoul(argv[1], NULL, 16); 256 if (avb_ab_mark_slot_successful(ops->ab_ops, slot_number) != 0) { 257 printf("do_avb_ab_mark_slot_successful error!\n"); 258 avb_ops_user_free(ops); 259 return CMD_RET_FAILURE; 260 } 261 262 avb_ops_user_free(ops); 263 264 return CMD_RET_SUCCESS; 265 } 266 267 int do_avb_read_rollback_index(cmd_tbl_t *cmdtp, int flag, 268 int argc, char * const argv[]) 269 { 270 AvbOps *ops; 271 uint64_t out_rollback_index; 272 size_t rollback_index_location; 273 274 if (argc != 2) 275 return CMD_RET_USAGE; 276 277 ops = avb_ops_user_new(); 278 if (ops == NULL) { 279 printf("avb_ops_user_new() failed!\n"); 280 return CMD_RET_FAILURE; 281 } 282 283 rollback_index_location = simple_strtoul(argv[1], NULL, 16); 284 if (ops->read_rollback_index(ops, rollback_index_location, 285 &out_rollback_index) != 0) { 286 printf("do_avb_read_rollback_index error!\n"); 287 avb_ops_user_free(ops); 288 return CMD_RET_FAILURE; 289 } 290 291 printf("\nout_rollback_index = %llx\n", out_rollback_index); 292 avb_ops_user_free(ops); 293 294 return CMD_RET_SUCCESS; 295 } 296 297 int do_avb_write_rollback_index(cmd_tbl_t *cmdtp, int flag, 298 int argc, char * const argv[]) 299 { 300 AvbOps *ops; 301 uint64_t out_rollback_index; 302 size_t rollback_index_location; 303 304 if (argc != 3) 305 return CMD_RET_USAGE; 306 307 rollback_index_location = simple_strtoul(argv[1], NULL, 16); 308 out_rollback_index = simple_strtoull(argv[2], NULL, 16); 309 debug("out_rollback_index = %llx\n", out_rollback_index); 310 ops = avb_ops_user_new(); 311 if (ops == NULL) { 312 printf("avb_ops_user_new() failed!\n"); 313 return CMD_RET_FAILURE; 314 } 315 316 if (ops->write_rollback_index(ops, rollback_index_location, 317 out_rollback_index) != 0) { 318 printf("do_avb_write_rollback_index error!\n"); 319 avb_ops_user_free(ops); 320 return CMD_RET_FAILURE; 321 } 322 323 printf("\nWrite rollback index successfully.\n"); 324 avb_ops_user_free(ops); 325 326 return CMD_RET_SUCCESS; 327 } 328 329 int do_avb_read_is_device_unlocked(cmd_tbl_t *cmdtp, int flag, 330 int argc, char * const argv[]) 331 { 332 AvbOps *ops; 333 bool out_is_unlocked; 334 335 if (argc != 1) 336 return CMD_RET_USAGE; 337 338 ops = avb_ops_user_new(); 339 if (ops == NULL) { 340 printf("avb_ops_user_new() failed!\n"); 341 return CMD_RET_FAILURE; 342 } 343 344 if (ops->read_is_device_unlocked(ops, &out_is_unlocked) != 0) { 345 printf("do_avb_read_is_device_unlocked error!\n"); 346 avb_ops_user_free(ops); 347 return CMD_RET_FAILURE; 348 } 349 350 printf("\n The device is %s\n", 351 out_is_unlocked ? "UNLOCKED" : "LOCKED"); 352 avb_ops_user_free(ops); 353 354 return CMD_RET_SUCCESS; 355 } 356 int do_avb_write_is_device_unlocked(cmd_tbl_t *cmdtp, int flag, 357 int argc, char * const argv[]) 358 { 359 AvbOps *ops; 360 bool out_is_unlocked; 361 362 if (argc != 2) 363 return CMD_RET_USAGE; 364 365 out_is_unlocked = simple_strtoul(argv[1], NULL, 16); 366 if ((out_is_unlocked != 0) || (out_is_unlocked != 1)) 367 printf("enter out_is_unlocked value must is '0' or '1'\n"); 368 369 ops = avb_ops_user_new(); 370 if (ops == NULL) { 371 printf("avb_ops_user_new() failed!\n"); 372 return CMD_RET_FAILURE; 373 } 374 375 if (ops->write_is_device_unlocked(ops, &out_is_unlocked) != 0) { 376 printf("do_avb_write_is_device_unlocked error!\n"); 377 avb_ops_user_free(ops); 378 return CMD_RET_FAILURE; 379 } 380 381 debug("out_is_unlocked = %d\n", out_is_unlocked); 382 avb_ops_user_free(ops); 383 384 return CMD_RET_SUCCESS; 385 } 386 387 int do_avb_get_size_of_partition(cmd_tbl_t *cmdtp, int flag, 388 int argc, char * const argv[]) 389 { 390 AvbOps *ops; 391 char *requested_partitions; 392 uint64_t out_size_in_bytes; 393 394 if (argc != 2) 395 return CMD_RET_USAGE; 396 397 requested_partitions = argv[1]; 398 ops = avb_ops_user_new(); 399 if (ops == NULL) { 400 printf("avb_ops_user_new() failed!\n"); 401 return CMD_RET_FAILURE; 402 } 403 404 if (ops->get_size_of_partition(ops, requested_partitions, 405 &out_size_in_bytes) != 0) { 406 printf("Can not get %s partition size!\n", requested_partitions); 407 avb_ops_user_free(ops); 408 return CMD_RET_FAILURE; 409 } 410 411 printf("%s partition size = 0x%llx\n", requested_partitions, 412 out_size_in_bytes); 413 avb_ops_user_free(ops); 414 415 return CMD_RET_SUCCESS; 416 } 417 418 int do_avb_get_get_unique_guid_for_partition(cmd_tbl_t *cmdtp, int flag, 419 int argc, char * const argv[]) 420 { 421 AvbOps *ops; 422 char *requested_partitions; 423 size_t guid_buf_size = 37; 424 char guid_buf[37]; 425 426 if (argc != 2) 427 return CMD_RET_USAGE; 428 429 requested_partitions = argv[1]; 430 ops = avb_ops_user_new(); 431 if (ops == NULL) { 432 printf("avb_ops_user_new() failed!\n"); 433 return CMD_RET_FAILURE; 434 } 435 436 if (ops->get_unique_guid_for_partition(ops, requested_partitions, 437 guid_buf, guid_buf_size) != 0) { 438 printf("Can not get %s partition UUID!\n", 439 requested_partitions); 440 avb_ops_user_free(ops); 441 return CMD_RET_FAILURE; 442 } 443 444 printf("%s partition UUID is %s\n", requested_partitions, guid_buf); 445 avb_ops_user_free(ops); 446 447 return CMD_RET_SUCCESS; 448 } 449 450 int do_avb_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 451 { 452 AvbOps *ops; 453 char *requested_partitions; 454 int64_t offset_blk; 455 size_t blkcnt; 456 size_t out_num_read; 457 int i; 458 char *buffer; 459 460 if (argc != 4) 461 return CMD_RET_USAGE; 462 463 requested_partitions = argv[1]; 464 offset_blk = simple_strtoul(argv[2], NULL, 16); 465 blkcnt = simple_strtoul(argv[3], NULL, 16); 466 ops = avb_ops_user_new(); 467 buffer = (char *)malloc(blkcnt * 512); 468 if (buffer == NULL) 469 printf("malloc buffer failed!\n"); 470 471 if (ops == NULL) { 472 printf("avb_ops_user_new() failed!\n"); 473 return CMD_RET_FAILURE; 474 } 475 476 if (ops->read_from_partition(ops, requested_partitions, 477 offset_blk, blkcnt, buffer, 478 &out_num_read) != 0) { 479 printf("do avb read error!\n"); 480 free(buffer); 481 avb_ops_user_free(ops); 482 return CMD_RET_FAILURE; 483 } 484 485 for (i = 0; i < 512 * blkcnt; i++) { 486 printf("buffer %d = %x", i, buffer[i]); 487 if ((i + 1) % 4 == 0) 488 printf("\n"); 489 } 490 491 free(buffer); 492 avb_ops_user_free(ops); 493 494 return CMD_RET_SUCCESS; 495 } 496 497 int do_avb_read_ab_metadata(cmd_tbl_t *cmdtp, int flag, 498 int argc, char * const argv[]) 499 { 500 AvbOps *ops; 501 AvbABData ab_data; 502 503 if (argc != 1) 504 return CMD_RET_USAGE; 505 506 ops = avb_ops_user_new(); 507 if (ops == NULL) { 508 printf("avb_ops_user_new() failed!\n"); 509 return CMD_RET_FAILURE; 510 } 511 512 if (ops->ab_ops->read_ab_metadata(ops->ab_ops, &ab_data) != 0) { 513 printf("do_avb_write_ab_metadata error!\n"); 514 avb_ops_user_free(ops); 515 return CMD_RET_FAILURE; 516 } 517 518 printf("Slot A information:\n"); 519 printf("slot A: priority = %d, tries_remaining = %d,\ 520 successful_boot = %d\n", 521 ab_data.slots[0].priority, 522 ab_data.slots[0].tries_remaining, 523 ab_data.slots[0].successful_boot); 524 printf("Slot B information:\n"); 525 printf("slot B: priority = %d, tries_remaining = %d,\ 526 successful_boot = %d\n", 527 ab_data.slots[1].priority, 528 ab_data.slots[1].tries_remaining, 529 ab_data.slots[1].successful_boot); 530 avb_ops_user_free(ops); 531 532 return CMD_RET_SUCCESS; 533 } 534 535 int do_avb_write_ab_metadata(cmd_tbl_t *cmdtp, int flag, 536 int argc, char * const argv[]) 537 { 538 AvbOps *ops; 539 AvbABData ab_data; 540 541 if (argc != 1) 542 return CMD_RET_USAGE; 543 544 ops = avb_ops_user_new(); 545 if (ops == NULL) { 546 printf("avb_ops_user_new() failed!\n"); 547 return CMD_RET_FAILURE; 548 } 549 550 if (ops->ab_ops->write_ab_metadata(ops->ab_ops, &ab_data) != 0) { 551 printf("do_avb_write_ab_metadata error!\n"); 552 avb_ops_user_free(ops); 553 return CMD_RET_FAILURE; 554 } 555 556 avb_ops_user_free(ops); 557 558 return CMD_RET_SUCCESS; 559 } 560 561 int do_perm_attr_test(cmd_tbl_t *cmdtp, int flag, 562 int argc, char * const argv[]) 563 { 564 AvbOps *ops; 565 int i; 566 uint8_t hash[AVB_SHA256_DIGEST_SIZE]; 567 568 if (argc != 1) 569 return CMD_RET_USAGE; 570 571 ops = avb_ops_user_new(); 572 if (ops == NULL) { 573 printf("avb_ops_user_new() failed!\n"); 574 return CMD_RET_FAILURE; 575 } 576 577 if (ops->atx_ops->read_permanent_attributes_hash(ops->atx_ops, hash) != 0) { 578 printf("read_permanent_attributes_hash error!\n"); 579 avb_ops_user_free(ops); 580 return CMD_RET_FAILURE; 581 } 582 583 for (i = 0; i < AVB_SHA256_DIGEST_SIZE; i++) { 584 if (i % 4 == 0) 585 printf("\n"); 586 printf("0x%x ", hash[i]); 587 } 588 589 avb_ops_user_free(ops); 590 591 return CMD_RET_SUCCESS; 592 } 593 594 int do_avb_verify_partition(cmd_tbl_t *cmdtp, int flag, 595 int argc, char * const argv[]) 596 { 597 AvbOps *ops; 598 const char *requested_partitions[1]; 599 const char * slot_suffixes[2] = {"_a", "_b"}; 600 AvbSlotVerifyFlags flags; 601 AvbSlotVerifyData *slot_data[2] = {NULL, NULL}; 602 AvbSlotVerifyResult verify_result; 603 size_t n; 604 605 if (argc != 3) 606 return CMD_RET_USAGE; 607 608 requested_partitions[0] = argv[1]; 609 n = simple_strtoul(argv[2], NULL, 16); 610 ops = avb_ops_user_new(); 611 flags = AVB_SLOT_VERIFY_FLAGS_NONE; 612 verify_result = 613 avb_slot_verify(ops, 614 requested_partitions, 615 slot_suffixes[n], 616 flags, 617 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 618 &slot_data[n]); 619 if (verify_result != 0) 620 return CMD_RET_FAILURE; 621 622 avb_ops_user_free(ops); 623 624 return CMD_RET_SUCCESS; 625 } 626 627 int do_avb_flow(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 628 { 629 char slot_partition[2][20] = {{0}, {0}}; 630 unsigned long load_address; 631 AvbOps *ops; 632 const char *avb_version; 633 AvbSlotVerifyData *slot_data; 634 AvbSlotVerifyFlags flags; 635 const char *requested_partitions[] = {"boot", "system", NULL}; 636 char *command_line; 637 bool unlocked; 638 const char *mode_cmdline = NULL; 639 char root_data[70] = "root=PARTUUID="; 640 char *vboot_state = "androidboot.verifiedbootstate="; 641 char avb_root_data[2000] = {0}; 642 size_t guid_buf_size = 37; 643 char guid_buf[37]; 644 char verify_flag; 645 char boot_slot_select[5]; 646 struct android_bootloader_message data; 647 const char *fastboot_cmd = env_get("fastbootcmd"); 648 AvbABFlowResult ab_result; 649 650 if (argc != 2) 651 return CMD_RET_USAGE; 652 653 bootloader_message_read(&data); 654 if (!strcmp("bootonce-bootloader", data.command)) { 655 memset(data.command, 0, sizeof(data.command)); 656 bootloader_message_write(&data); 657 if (fastboot_cmd) { 658 printf("bootonce-bootloader!\n"); 659 return run_command(fastboot_cmd, CMD_FLAG_ENV); 660 } else { 661 printf("The fastbootcmd is NULL!\n"); 662 goto fail; 663 } 664 } else if (!strcmp("boot-recovery", data.command)) { 665 printf("Enter boot-recovery!\n"); 666 } else if(!strcmp("boot-normal", data.command)) { 667 printf("Enter boot-normal!\n"); 668 mode_cmdline = "skip_initramfs"; 669 } else { 670 /* 671 * Firstly, confirm if there is a command in misc partition in 672 * previous cases, and then we need to confirm whether user has 673 * requested to enter recovery mode by entering "reboot recovery" 674 * command through adb or serial console. 675 */ 676 char *env_rebootmode = env_get("reboot_mode"); 677 678 if (env_rebootmode && !strcmp("recovery", env_rebootmode)) 679 printf("Enter recovery mode by command 'reboot recovery'!\n"); 680 else 681 mode_cmdline = "skip_initramfs"; 682 } 683 684 avb_version = avb_version_string(); 685 printf("Android avb version is %s.\n", avb_version); 686 ops = avb_ops_user_new(); 687 if (ops == NULL) { 688 printf("avb_ops_user_new() failed!\n"); 689 goto fail; 690 } 691 692 if (ops->read_is_device_unlocked(ops, &unlocked) != 0) { 693 printf("Error determining whether device is unlocked.\n"); 694 unlocked = ANDROID_VBOOT_UNLOCK; 695 if (ops->write_is_device_unlocked(ops, &unlocked) != 0) { 696 printf("Can not write lock state!\n"); 697 unlocked = ANDROID_VBOOT_LOCK; 698 } 699 if (ops->read_is_device_unlocked(ops, &unlocked) != 0) { 700 printf("Can not read lock state!\n"); 701 unlocked = ANDROID_VBOOT_LOCK; 702 } 703 } 704 705 printf("read_is_device_unlocked() ops returned that device is %s\n", 706 unlocked ? "UNLOCKED" : "LOCKED"); 707 708 flags = AVB_SLOT_VERIFY_FLAGS_NONE; 709 if (unlocked) 710 flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR; 711 712 verify_flag = argv[1][0]; 713 if (verify_flag == 'v') { 714 debug("start with verify!\n"); 715 ab_result = 716 avb_ab_flow(ops->ab_ops, 717 requested_partitions, 718 flags, 719 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 720 &slot_data); 721 if ((ab_result != AVB_AB_FLOW_RESULT_OK) && 722 (ab_result != 723 AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR)) { 724 printf("avb_ab_flow() error!\n"); 725 avb_ops_user_free(ops); 726 goto fail; 727 } 728 729 if (ab_result ==\ 730 AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR) { 731 strcat(avb_root_data, vboot_state); 732 strcat(avb_root_data, "orange"); 733 } else if (ab_result == AVB_AB_FLOW_RESULT_OK) { 734 strcat(avb_root_data, vboot_state); 735 strcat(avb_root_data, "green"); 736 } 737 738 command_line = android_assemble_cmdline(slot_data->ab_suffix, 739 mode_cmdline); 740 strcat(avb_root_data, " "); 741 strcat(avb_root_data, command_line); 742 strcat(avb_root_data, " "); 743 strcat(avb_root_data, slot_data->cmdline); 744 env_set("bootargs", avb_root_data); 745 load_address = CONFIG_SYS_LOAD_ADDR; 746 if (rk_avb_close_optee_client()) 747 printf("Can not close optee client!\n"); 748 749 memcpy((uint8_t*)load_address, 750 slot_data->loaded_partitions->data, 751 slot_data->loaded_partitions->data_size); 752 android_bootloader_boot_kernel(load_address); 753 avb_ops_user_free(ops); 754 } else if (verify_flag == 'n') { 755 load_address = CONFIG_SYS_LOAD_ADDR; 756 rk_avb_ab_slot_select(ops->ab_ops, boot_slot_select); 757 strcat(slot_partition[1], requested_partitions[1]); 758 strcat(slot_partition[1], boot_slot_select); 759 printf("%s\n", slot_partition[1]); 760 ops->get_unique_guid_for_partition(ops, 761 slot_partition[1], 762 guid_buf, 763 guid_buf_size); 764 strcat(root_data, guid_buf); 765 command_line = android_assemble_cmdline(boot_slot_select, 766 mode_cmdline); 767 strcat(root_data, " "); 768 strcat(root_data, command_line); 769 env_set("bootargs", root_data); 770 if (android_avb_boot_flow(boot_slot_select, load_address)) { 771 printf("Cannot boot the system, goto the fastboot!\n"); 772 avb_ops_user_free(ops); 773 goto fail; 774 } 775 avb_ops_user_free(ops); 776 } else if (verify_flag == 'o') { 777 load_address = CONFIG_SYS_LOAD_ADDR; 778 strcat(slot_partition[1], requested_partitions[1]); 779 ops->get_unique_guid_for_partition(ops, 780 slot_partition[1], 781 guid_buf, 782 guid_buf_size); 783 strcat(root_data, guid_buf); 784 command_line = android_assemble_cmdline(boot_slot_select, 785 mode_cmdline); 786 strcat(root_data, " "); 787 strcat(root_data, command_line); 788 env_set("bootargs", root_data); 789 if (android_boot_flow(load_address)) { 790 printf("Cannot boot the system, goto the fastboot!\n"); 791 avb_ops_user_free(ops); 792 goto fail; 793 } 794 avb_ops_user_free(ops); 795 } else { 796 return CMD_RET_USAGE; 797 } 798 799 return CMD_RET_SUCCESS; 800 fail: 801 if (fastboot_cmd == NULL) { 802 printf("fastboot_cmd is null, run default fastboot_cmd!\n"); 803 fastboot_cmd = "fastboot usb 0"; 804 } 805 806 return run_command(fastboot_cmd, CMD_FLAG_ENV); 807 } 808 809 static cmd_tbl_t cmd_avb[] = { 810 U_BOOT_CMD_MKENT(init, 1, 1, do_avb_init_ab_metadata, "", ""), 811 U_BOOT_CMD_MKENT(version, 1, 1, do_avb_version, "", ""), 812 U_BOOT_CMD_MKENT(slot_active, 2, 1, 813 do_avb_ab_mark_slot_active, "", ""), 814 U_BOOT_CMD_MKENT(slot_unbootable, 2, 1, 815 do_avb_ab_mark_slot_unbootable, "", ""), 816 U_BOOT_CMD_MKENT(slot_successful, 2, 1, 817 do_avb_ab_mark_slot_successful, "", ""), 818 U_BOOT_CMD_MKENT(read_rollback, 2, 1, 819 do_avb_read_rollback_index, "", ""), 820 U_BOOT_CMD_MKENT(write_rollback, 3, 1, 821 do_avb_write_rollback_index, "", ""), 822 U_BOOT_CMD_MKENT(read_lock_status, 1, 1, 823 do_avb_read_is_device_unlocked, "", ""), 824 U_BOOT_CMD_MKENT(write_lock_status, 2, 1, 825 do_avb_write_is_device_unlocked, "", ""), 826 U_BOOT_CMD_MKENT(part_size, 2, 1, 827 do_avb_get_size_of_partition, "", ""), 828 U_BOOT_CMD_MKENT(part_guid, 2, 1, 829 do_avb_get_get_unique_guid_for_partition, "", ""), 830 U_BOOT_CMD_MKENT(read, 4, 1, do_avb_read, "", ""), 831 U_BOOT_CMD_MKENT(readabmisc, 1, 1, do_avb_read_ab_metadata, "", ""), 832 U_BOOT_CMD_MKENT(perm_attr_test, 1, 1, do_perm_attr_test, "", ""), 833 U_BOOT_CMD_MKENT(verify, 3, 1, do_avb_verify_partition, "", ""), 834 U_BOOT_CMD_MKENT(flow, 2, 1, do_avb_flow, "", "") 835 }; 836 837 static int do_boot_avb(cmd_tbl_t *cmdtp, 838 int flag, 839 int argc, 840 char * const argv[]) 841 { 842 cmd_tbl_t *cp; 843 844 cp = find_cmd_tbl(argv[1], cmd_avb, ARRAY_SIZE(cmd_avb)); 845 846 argc--; 847 argv++; 848 849 if (cp == NULL || argc > cp->maxargs) 850 return CMD_RET_USAGE; 851 if (flag == CMD_FLAG_REPEAT && !cp->repeatable) 852 return CMD_RET_SUCCESS; 853 854 return cp->cmd(cmdtp, flag, argc, argv); 855 } 856 857 U_BOOT_CMD( 858 bootavb, 29, 1, do_boot_avb, 859 "Execute the Android avb a/b boot flow.", 860 "init - initialize the avbabmeta\n" 861 "bootavb version - display info of bootavb version\n" 862 "bootavb slot_active cnt\n" 863 "bootavb slot_unbootable cnt\n" 864 "bootavb slot_successful cnt\n" 865 "bootavb read_rollback rollback_index_location\n" 866 "bootavb write_rollback rollback_index_location rollback_index\n" 867 "bootavb read_lock_status\n" 868 "bootavb write_lock_status 0 or 1\n" 869 "bootavb part_size partitions_name\n" 870 "bootavb part_guid partitions_name\n" 871 "bootavb read partition offset_blk cnt\n" 872 "bootavb readabmisc\n" 873 "bootavb perm_attr_test\n" 874 "bootavb verify partition slot_cnt;partion name without '_a' or '_b'\n" 875 "bootavb flow v/n\n" 876 ); 877 #endif 878