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