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