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