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