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_bootloader_message.h> 9 #include <android_avb/avb_slot_verify.h> 10 #include <android_avb/avb_ops_user.h> 11 #include <android_avb/rk_avb_ops_user.h> 12 #include <android_image.h> 13 #include <cli.h> 14 #include <common.h> 15 #include <dt_table.h> 16 #include <image-android-dt.h> 17 #include <malloc.h> 18 #include <fs.h> 19 #include <boot_rkimg.h> 20 #include <attestation_key.h> 21 #include <optee_include/OpteeClientInterface.h> 22 #include <linux/libfdt_env.h> 23 24 #define ANDROID_PARTITION_BOOT "boot" 25 #define ANDROID_PARTITION_MISC "misc" 26 #define ANDROID_PARTITION_OEM "oem" 27 #define ANDROID_PARTITION_RECOVERY "recovery" 28 #define ANDROID_PARTITION_SYSTEM "system" 29 30 #define ANDROID_ARG_SLOT_SUFFIX "androidboot.slot_suffix=" 31 #define ANDROID_ARG_ROOT "root=" 32 #define ANDROID_ARG_SERIALNO "androidboot.serialno=" 33 #define ANDROID_VERIFY_STATE "androidboot.verifiedbootstate=" 34 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 35 #define ANDROID_ARG_FDT_FILENAME "rk-kernel.dtb" 36 #define BOOTLOADER_MESSAGE_OFFSET_IN_MISC (16 * 1024) 37 #define BOOTLOADER_MESSAGE_BLK_OFFSET (BOOTLOADER_MESSAGE_OFFSET_IN_MISC >> 9) 38 #else 39 #define ANDROID_ARG_FDT_FILENAME "kernel.dtb" 40 #endif 41 #define OEM_UNLOCK_ARG_SIZE 30 42 43 char *android_str_append(char *base_name, char *slot_suffix) 44 { 45 char *part_name; 46 size_t part_name_len; 47 48 part_name_len = strlen(base_name) + 1; 49 if (slot_suffix) 50 part_name_len += strlen(slot_suffix); 51 part_name = malloc(part_name_len); 52 if (!part_name) 53 return NULL; 54 strcpy(part_name, base_name); 55 if (slot_suffix && (slot_suffix[0] != '\0')) 56 strcat(part_name, slot_suffix); 57 58 return part_name; 59 } 60 61 int android_bootloader_message_load( 62 struct blk_desc *dev_desc, 63 const disk_partition_t *part_info, 64 struct android_bootloader_message *message) 65 { 66 ulong message_blocks = sizeof(struct android_bootloader_message) / 67 part_info->blksz; 68 if (message_blocks > part_info->size) { 69 printf("misc partition too small.\n"); 70 return -1; 71 } 72 73 #ifdef CONFIG_RKIMG_BOOTLOADER 74 if (blk_dread(dev_desc, part_info->start + BOOTLOADER_MESSAGE_BLK_OFFSET, 75 message_blocks, message) != 76 #else 77 if (blk_dread(dev_desc, part_info->start, message_blocks, message) != 78 #endif 79 message_blocks) { 80 printf("Could not read from misc partition\n"); 81 return -1; 82 } 83 debug("ANDROID: Loaded BCB, %lu blocks.\n", message_blocks); 84 return 0; 85 } 86 87 static int android_bootloader_message_write( 88 struct blk_desc *dev_desc, 89 const disk_partition_t *part_info, 90 struct android_bootloader_message *message) 91 { 92 #ifdef CONFIG_RKIMG_BOOTLOADER 93 ulong message_blocks = sizeof(struct android_bootloader_message) / 94 part_info->blksz + BOOTLOADER_MESSAGE_BLK_OFFSET; 95 #else 96 ulong message_blocks = sizeof(struct android_bootloader_message) / 97 part_info->blksz; 98 #endif 99 if (message_blocks > part_info->size) { 100 printf("misc partition too small.\n"); 101 return -1; 102 } 103 104 if (blk_dwrite(dev_desc, part_info->start, message_blocks, message) != 105 message_blocks) { 106 printf("Could not write to misc partition\n"); 107 return -1; 108 } 109 debug("ANDROID: Wrote new BCB, %lu blocks.\n", message_blocks); 110 return 0; 111 } 112 113 static enum android_boot_mode android_bootloader_load_and_clear_mode( 114 struct blk_desc *dev_desc, 115 const disk_partition_t *misc_part_info) 116 { 117 struct android_bootloader_message bcb; 118 119 #ifdef CONFIG_FASTBOOT 120 char *bootloader_str; 121 122 /* Check for message from bootloader stored in RAM from a previous boot. 123 */ 124 bootloader_str = (char *)CONFIG_FASTBOOT_BUF_ADDR; 125 if (!strcmp("reboot-bootloader", bootloader_str)) { 126 bootloader_str[0] = '\0'; 127 return ANDROID_BOOT_MODE_BOOTLOADER; 128 } 129 #endif 130 131 /* Check and update the BCB message if needed. */ 132 if (android_bootloader_message_load(dev_desc, misc_part_info, &bcb) < 133 0) { 134 printf("WARNING: Unable to load the BCB.\n"); 135 return ANDROID_BOOT_MODE_NORMAL; 136 } 137 138 if (!strcmp("bootonce-bootloader", bcb.command)) { 139 /* Erase the message in the BCB since this value should be used 140 * only once. 141 */ 142 memset(bcb.command, 0, sizeof(bcb.command)); 143 android_bootloader_message_write(dev_desc, misc_part_info, 144 &bcb); 145 return ANDROID_BOOT_MODE_BOOTLOADER; 146 } 147 148 if (!strcmp("boot-recovery", bcb.command)) 149 return ANDROID_BOOT_MODE_RECOVERY; 150 151 return ANDROID_BOOT_MODE_NORMAL; 152 } 153 154 /** 155 * Return the reboot reason string for the passed boot mode. 156 * 157 * @param mode The Android Boot mode. 158 * @return a pointer to the reboot reason string for mode. 159 */ 160 static const char *android_boot_mode_str(enum android_boot_mode mode) 161 { 162 switch (mode) { 163 case ANDROID_BOOT_MODE_NORMAL: 164 return "(none)"; 165 case ANDROID_BOOT_MODE_RECOVERY: 166 return "recovery"; 167 case ANDROID_BOOT_MODE_BOOTLOADER: 168 return "bootloader"; 169 } 170 return NULL; 171 } 172 173 static int android_part_get_info_by_name_suffix(struct blk_desc *dev_desc, 174 const char *base_name, 175 const char *slot_suffix, 176 disk_partition_t *part_info) 177 { 178 char *part_name; 179 int part_num; 180 size_t part_name_len; 181 182 part_name_len = strlen(base_name) + 1; 183 if (slot_suffix) 184 part_name_len += strlen(slot_suffix); 185 part_name = malloc(part_name_len); 186 if (!part_name) 187 return -1; 188 strcpy(part_name, base_name); 189 if (slot_suffix && (slot_suffix[0] != '\0')) 190 strcat(part_name, slot_suffix); 191 192 part_num = part_get_info_by_name(dev_desc, part_name, part_info); 193 if (part_num < 0) { 194 debug("ANDROID: Could not find partition \"%s\"\n", part_name); 195 part_num = -1; 196 } 197 198 free(part_name); 199 return part_num; 200 } 201 202 static int android_bootloader_boot_bootloader(void) 203 { 204 const char *fastboot_cmd = env_get("fastbootcmd"); 205 206 if (fastboot_cmd == NULL) { 207 printf("fastboot_cmd is null, run default fastboot_cmd!\n"); 208 fastboot_cmd = "fastboot usb 0"; 209 } 210 211 return run_command(fastboot_cmd, CMD_FLAG_ENV); 212 } 213 214 #ifdef CONFIG_SUPPORT_OEM_DTB 215 static int android_bootloader_get_fdt(const char *part_name, 216 const char *load_file_name) 217 { 218 struct blk_desc *dev_desc; 219 disk_partition_t boot_part_info; 220 char *fdt_addr = NULL; 221 char slot_suffix[5] = {0}; 222 char dev_part[3] = {0}; 223 loff_t bytes = 0; 224 loff_t pos = 0; 225 loff_t len_read; 226 unsigned long addr = 0; 227 int part_num = -1; 228 int ret; 229 230 dev_desc = rockchip_get_bootdev(); 231 if (!dev_desc) { 232 printf("%s: dev_desc is NULL!\n", __func__); 233 return -1; 234 } 235 236 memset(&boot_part_info, 0, sizeof(boot_part_info)); 237 238 #ifdef CONFIG_RK_AVB_LIBAVB_USER 239 if (rk_avb_get_current_slot(slot_suffix)) { 240 printf("ANDROID: Get Current Slot error.\n"); 241 return -1; 242 } 243 244 part_num = android_part_get_info_by_name_suffix(dev_desc, 245 part_name, 246 slot_suffix, &boot_part_info); 247 #else 248 part_num = part_get_info_by_name(dev_desc, part_name, &boot_part_info); 249 if (part_num < 0) { 250 printf("ANDROID: Could not find partition \"%s\"\n", part_name); 251 return -1; 252 } 253 #endif 254 255 snprintf(dev_part, ARRAY_SIZE(dev_part), ":%x", part_num); 256 if (fs_set_blk_dev_with_part(dev_desc, part_num)) 257 return -1; 258 259 fdt_addr = env_get("fdt_addr_r"); 260 if (!fdt_addr) { 261 printf("ANDROID: No Found FDT Load Address.\n"); 262 return -1; 263 } 264 addr = simple_strtoul(fdt_addr, NULL, 16); 265 266 ret = fs_read(load_file_name, addr, pos, bytes, &len_read); 267 if (ret < 0) 268 return -1; 269 270 return 0; 271 } 272 #endif 273 274 int android_bootloader_boot_kernel(unsigned long kernel_address) 275 { 276 char kernel_addr_str[12]; 277 char *fdt_addr = env_get("fdt_addr"); 278 char *bootm_args[] = { 279 "bootm", kernel_addr_str, kernel_addr_str, fdt_addr, NULL }; 280 281 sprintf(kernel_addr_str, "0x%lx", kernel_address); 282 283 printf("Booting kernel at %s with fdt at %s...\n\n\n", 284 kernel_addr_str, fdt_addr); 285 do_bootm(NULL, 0, 4, bootm_args); 286 287 return -1; 288 } 289 290 static char *strjoin(const char **chunks, char separator) 291 { 292 int len, joined_len = 0; 293 char *ret, *current; 294 const char **p; 295 296 for (p = chunks; *p; p++) 297 joined_len += strlen(*p) + 1; 298 299 if (!joined_len) { 300 ret = malloc(1); 301 if (ret) 302 ret[0] = '\0'; 303 return ret; 304 } 305 306 ret = malloc(joined_len); 307 current = ret; 308 if (!ret) 309 return ret; 310 311 for (p = chunks; *p; p++) { 312 len = strlen(*p); 313 memcpy(current, *p, len); 314 current += len; 315 *current = separator; 316 current++; 317 } 318 /* Replace the last separator by a \0. */ 319 current[-1] = '\0'; 320 return ret; 321 } 322 323 /** android_assemble_cmdline - Assemble the command line to pass to the kernel 324 * @return a newly allocated string 325 */ 326 char *android_assemble_cmdline(const char *slot_suffix, 327 const char *extra_args) 328 { 329 const char *cmdline_chunks[16]; 330 const char **current_chunk = cmdline_chunks; 331 char *env_cmdline, *cmdline, *rootdev_input, *serialno; 332 char *allocated_suffix = NULL; 333 char *allocated_serialno = NULL; 334 char *allocated_rootdev = NULL; 335 unsigned long rootdev_len; 336 337 env_cmdline = env_get("bootargs"); 338 if (env_cmdline) 339 *(current_chunk++) = env_cmdline; 340 341 /* The |slot_suffix| needs to be passed to the kernel to know what 342 * slot to boot from. 343 */ 344 if (slot_suffix) { 345 allocated_suffix = malloc(strlen(ANDROID_ARG_SLOT_SUFFIX) + 346 strlen(slot_suffix) + 1); 347 memset(allocated_suffix, 0, strlen(ANDROID_ARG_SLOT_SUFFIX) 348 + strlen(slot_suffix) + 1); 349 strcpy(allocated_suffix, ANDROID_ARG_SLOT_SUFFIX); 350 strcat(allocated_suffix, slot_suffix); 351 *(current_chunk++) = allocated_suffix; 352 } 353 354 serialno = env_get("serial#"); 355 if (serialno) { 356 allocated_serialno = malloc(strlen(ANDROID_ARG_SERIALNO) + 357 strlen(serialno) + 1); 358 memset(allocated_serialno, 0, strlen(ANDROID_ARG_SERIALNO) + 359 strlen(serialno) + 1); 360 strcpy(allocated_serialno, ANDROID_ARG_SERIALNO); 361 strcat(allocated_serialno, serialno); 362 *(current_chunk++) = allocated_serialno; 363 } 364 365 rootdev_input = env_get("android_rootdev"); 366 if (rootdev_input) { 367 rootdev_len = strlen(ANDROID_ARG_ROOT) + CONFIG_SYS_CBSIZE + 1; 368 allocated_rootdev = malloc(rootdev_len); 369 strcpy(allocated_rootdev, ANDROID_ARG_ROOT); 370 cli_simple_process_macros(rootdev_input, 371 allocated_rootdev + 372 strlen(ANDROID_ARG_ROOT)); 373 /* Make sure that the string is null-terminated since the 374 * previous could not copy to the end of the input string if it 375 * is too big. 376 */ 377 allocated_rootdev[rootdev_len - 1] = '\0'; 378 *(current_chunk++) = allocated_rootdev; 379 } 380 381 if (extra_args) 382 *(current_chunk++) = extra_args; 383 384 *(current_chunk++) = NULL; 385 cmdline = strjoin(cmdline_chunks, ' '); 386 free(allocated_suffix); 387 free(allocated_rootdev); 388 return cmdline; 389 } 390 391 #ifdef CONFIG_ANDROID_AVB 392 static void slot_set_unbootable(AvbABSlotData* slot) 393 { 394 slot->priority = 0; 395 slot->tries_remaining = 0; 396 slot->successful_boot = 0; 397 } 398 399 static AvbSlotVerifyResult android_slot_verify(char *boot_partname, 400 unsigned long load_address, 401 char *slot_suffix) 402 { 403 const char *requested_partitions[1] = {NULL}; 404 uint8_t unlocked = true; 405 AvbOps *ops; 406 AvbSlotVerifyFlags flags; 407 AvbSlotVerifyData *slot_data[1] = {NULL}; 408 AvbSlotVerifyResult verify_result; 409 AvbABData ab_data, ab_data_orig; 410 size_t slot_index_to_boot = 0; 411 char verify_state[38] = {0}; 412 413 requested_partitions[0] = boot_partname; 414 ops = avb_ops_user_new(); 415 if (ops == NULL) { 416 printf("avb_ops_user_new() failed!\n"); 417 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 418 } 419 420 if (ops->read_is_device_unlocked(ops, (bool *)&unlocked) != AVB_IO_RESULT_OK) 421 printf("Error determining whether device is unlocked.\n"); 422 423 printf("read_is_device_unlocked() ops returned that device is %s\n", 424 (unlocked & LOCK_MASK)? "UNLOCKED" : "LOCKED"); 425 426 flags = AVB_SLOT_VERIFY_FLAGS_NONE; 427 if (unlocked & LOCK_MASK) 428 flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR; 429 430 if(load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) { 431 printf("Can not load metadata\n"); 432 return AVB_SLOT_VERIFY_RESULT_ERROR_IO; 433 } 434 435 if (strncmp(slot_suffix, "_a", 2)) 436 slot_index_to_boot = 0; 437 else if(strncmp(slot_suffix, "_b", 2)) 438 slot_index_to_boot = 1; 439 else 440 slot_index_to_boot = 0; 441 442 verify_result = 443 avb_slot_verify(ops, 444 requested_partitions, 445 slot_suffix, 446 flags, 447 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 448 &slot_data[0]); 449 450 strcat(verify_state, ANDROID_VERIFY_STATE); 451 switch (verify_result) { 452 case AVB_SLOT_VERIFY_RESULT_OK: 453 if (unlocked & LOCK_MASK) 454 strcat(verify_state, "orange"); 455 else 456 strcat(verify_state, "green"); 457 break; 458 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: 459 if (unlocked & LOCK_MASK) 460 strcat(verify_state, "orange"); 461 else 462 strcat(verify_state, "yellow"); 463 break; 464 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: 465 case AVB_SLOT_VERIFY_RESULT_ERROR_IO: 466 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: 467 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: 468 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: 469 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: 470 default: 471 if (unlocked & LOCK_MASK) 472 strcat(verify_state, "orange"); 473 else 474 strcat(verify_state, "red"); 475 break; 476 } 477 478 if (verify_result == AVB_SLOT_VERIFY_RESULT_OK || 479 verify_result == AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED || 480 (unlocked & LOCK_MASK)) { 481 memcpy((uint8_t *)load_address, 482 slot_data[0]->loaded_partitions->data, 483 slot_data[0]->loaded_partitions->data_size); 484 env_set("bootargs", slot_data[0]->cmdline); 485 486 /* ... and decrement tries remaining, if applicable. */ 487 if (!ab_data.slots[slot_index_to_boot].successful_boot && 488 ab_data.slots[slot_index_to_boot].tries_remaining > 0) { 489 ab_data.slots[slot_index_to_boot].tries_remaining -= 1; 490 } 491 } else { 492 slot_set_unbootable(&ab_data.slots[slot_index_to_boot]); 493 } 494 495 env_update("bootargs", verify_state); 496 if (save_metadata_if_changed(ops->ab_ops, &ab_data, &ab_data_orig)) { 497 printf("Can not save metadata\n"); 498 verify_result = AVB_SLOT_VERIFY_RESULT_ERROR_IO; 499 } 500 501 if (slot_data[0] != NULL) 502 avb_slot_verify_data_free(slot_data[0]); 503 504 if (unlocked & LOCK_MASK) 505 return 0; 506 else 507 return verify_result; 508 } 509 #endif 510 511 #if defined(CONFIG_CMD_DTIMG) && defined(CONFIG_OF_LIBFDT_OVERLAY) 512 513 /* 514 * Default return index 0. 515 */ 516 __weak int board_select_fdt_index(ulong dt_table_hdr) 517 { 518 /* 519 * User can use "dt_for_each_entry(entry, hdr, idx)" to iterate 520 * over all dt entry of DT image and pick up which they want. 521 * 522 * Example: 523 * struct dt_table_entry *entry; 524 * int index; 525 * 526 * dt_for_each_entry(entry, dt_table_hdr, index) { 527 * 528 * .... (use entry) 529 * } 530 * 531 * return index; 532 */ 533 return 0; 534 } 535 536 static int android_get_dtbo(ulong *fdt_dtbo, 537 const struct andr_img_hdr *hdr, 538 int *index) 539 { 540 struct dt_table_header *dt_hdr = NULL; 541 struct blk_desc *dev_desc; 542 const char *part_name; 543 disk_partition_t part_info; 544 u32 blk_offset, blk_cnt; 545 void *buf; 546 ulong e_addr; 547 u32 e_size; 548 int e_idx; 549 int ret; 550 551 /* Get partition according to boot mode */ 552 if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY) 553 part_name = PART_RECOVERY; 554 else 555 part_name = PART_DTBO; 556 557 /* Get partition info */ 558 dev_desc = rockchip_get_bootdev(); 559 if (!dev_desc) { 560 printf("%s: dev_desc is NULL!\n", __func__); 561 return -ENODEV; 562 } 563 564 ret = part_get_info_by_name(dev_desc, part_name, &part_info); 565 if (ret < 0) { 566 printf("%s: failed to get %s part info, ret=%d\n", 567 __func__, part_name, ret); 568 return ret; 569 } 570 571 /* Check dt table header */ 572 if (!strcmp(part_name, PART_RECOVERY)) 573 blk_offset = part_info.start + 574 (hdr->recovery_dtbo_offset / part_info.blksz); 575 else 576 blk_offset = part_info.start; 577 578 dt_hdr = memalign(ARCH_DMA_MINALIGN, part_info.blksz); 579 if (!dt_hdr) { 580 printf("%s: out of memory for dt header!\n", __func__); 581 return -ENOMEM; 582 } 583 584 ret = blk_dread(dev_desc, blk_offset, 1, dt_hdr); 585 if (ret != 1) { 586 printf("%s: failed to read dt table header\n", 587 __func__); 588 goto out1; 589 } 590 591 if (!android_dt_check_header((ulong)dt_hdr)) { 592 printf("%s: Error: invalid dt table header: 0x%x\n", 593 __func__, dt_hdr->magic); 594 ret = -EINVAL; 595 goto out1; 596 } 597 598 #ifdef DEBUG 599 android_dt_print_contents((ulong)dt_hdr); 600 #endif 601 602 blk_cnt = DIV_ROUND_UP(fdt32_to_cpu(dt_hdr->total_size), 603 part_info.blksz); 604 /* Read all DT Image */ 605 buf = memalign(ARCH_DMA_MINALIGN, part_info.blksz * blk_cnt); 606 if (!buf) { 607 printf("%s: out of memory for %s part!\n", __func__, part_name); 608 ret = -ENOMEM; 609 goto out1; 610 } 611 612 ret = blk_dread(dev_desc, blk_offset, blk_cnt, buf); 613 if (ret != blk_cnt) { 614 printf("%s: failed to read dtbo, blk_cnt=%d, ret=%d\n", 615 __func__, blk_cnt, ret); 616 goto out2; 617 } 618 619 e_idx = board_select_fdt_index((ulong)buf); 620 if (e_idx < 0) { 621 printf("%s: failed to select board fdt index\n", __func__); 622 ret = -EINVAL; 623 goto out2; 624 } 625 626 ret = android_dt_get_fdt_by_index((ulong)buf, e_idx, &e_addr, &e_size); 627 if (!ret) { 628 printf("%s: failed to get fdt, index=%d\n", __func__, e_idx); 629 ret = -EINVAL; 630 goto out2; 631 } 632 633 if (fdt_dtbo) 634 *fdt_dtbo = e_addr; 635 if (index) 636 *index = e_idx; 637 638 free(dt_hdr); 639 debug("ANDROID: Loading dt entry to 0x%lx size 0x%x idx %d from \"%s\" part\n", 640 e_addr, e_size, e_idx, part_name); 641 642 return 0; 643 644 out2: 645 free(buf); 646 out1: 647 free(dt_hdr); 648 649 return ret; 650 } 651 652 int android_fdt_overlay_apply(void *fdt_addr) 653 { 654 struct andr_img_hdr *hdr; 655 struct blk_desc *dev_desc; 656 const char *part_name; 657 disk_partition_t part_info; 658 char buf[32] = {0}; 659 u32 blk_cnt; 660 ulong fdt_dtbo = -1; 661 int index = -1; 662 int ret; 663 664 /* Get partition according to boot mode */ 665 if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY) 666 part_name = PART_RECOVERY; 667 else 668 part_name = PART_BOOT; 669 670 /* Get partition info */ 671 dev_desc = rockchip_get_bootdev(); 672 if (!dev_desc) { 673 printf("%s: dev_desc is NULL!\n", __func__); 674 return -ENODEV; 675 } 676 677 ret = part_get_info_by_name(dev_desc, part_name, &part_info); 678 if (ret < 0) { 679 printf("%s: failed to get %s part info, ret=%d\n", 680 __func__, part_name, ret); 681 return ret; 682 } 683 684 blk_cnt = DIV_ROUND_UP(sizeof(*hdr), part_info.blksz); 685 hdr = memalign(ARCH_DMA_MINALIGN, part_info.blksz * blk_cnt); 686 if (!hdr) { 687 printf("%s: out of memory!\n", __func__); 688 return -ENOMEM; 689 } 690 691 ret = blk_dread(dev_desc, part_info.start, blk_cnt, hdr); 692 if (ret != blk_cnt) { 693 printf("%s: failed to read %s hdr!\n", __func__, part_name); 694 goto out; 695 } 696 697 #ifdef DEBUG 698 android_print_contents(hdr); 699 #endif 700 701 if (android_image_check_header(hdr)) { 702 printf("%s: Invalid Android header %s\n", __func__, hdr->magic); 703 return -EINVAL; 704 } 705 706 /* Check header version */ 707 if (!hdr->header_version) { 708 printf("Android header version 0\n"); 709 ret = -EINVAL; 710 goto out; 711 } 712 713 ret = android_get_dtbo(&fdt_dtbo, (void *)hdr, &index); 714 if (!ret) { 715 /* Must incease size before overlay */ 716 fdt_increase_size(fdt_addr, fdt_totalsize((void *)fdt_dtbo)); 717 ret = fdt_overlay_apply(fdt_addr, (void *)fdt_dtbo); 718 if (!ret) { 719 snprintf(buf, 32, "%s%d", "androidboot.dtbo_", index); 720 env_update("bootargs", buf); 721 printf("ANDROID: fdt overlay OK\n"); 722 } else { 723 printf("ANDROID: fdt overlay failed, ret=%d\n", ret); 724 } 725 } 726 727 out: 728 free(hdr); 729 730 return 0; 731 } 732 #endif 733 734 int android_bootloader_boot_flow(struct blk_desc *dev_desc, 735 unsigned long load_address) 736 { 737 enum android_boot_mode mode; 738 disk_partition_t misc_part_info; 739 int part_num; 740 int ret; 741 char *command_line; 742 char slot_suffix[3] = {0}; 743 const char *mode_cmdline = NULL; 744 char *boot_partname = ANDROID_PARTITION_BOOT; 745 ulong fdt_addr; 746 747 /* 748 * 1. Load MISC partition and determine the boot mode 749 * clear its value for the next boot if needed. 750 */ 751 part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_MISC, 752 &misc_part_info); 753 if (part_num < 0) 754 printf("%s Could not find misc partition\n", __func__); 755 756 #ifdef CONFIG_OPTEE_CLIENT 757 /* load attestation key from misc partition. */ 758 load_attestation_key(dev_desc, &misc_part_info); 759 #endif 760 761 mode = android_bootloader_load_and_clear_mode(dev_desc, &misc_part_info); 762 #ifdef CONFIG_RKIMG_BOOTLOADER 763 if (mode == ANDROID_BOOT_MODE_NORMAL) { 764 if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY) 765 mode = ANDROID_BOOT_MODE_RECOVERY; 766 } 767 #endif 768 printf("ANDROID: reboot reason: \"%s\"\n", android_boot_mode_str(mode)); 769 770 switch (mode) { 771 case ANDROID_BOOT_MODE_NORMAL: 772 /* In normal mode, we load the kernel from "boot" but append 773 * "skip_initramfs" to the cmdline to make it ignore the 774 * recovery initramfs in the boot partition. 775 */ 776 #ifdef CONFIG_ANDROID_AB 777 mode_cmdline = "skip_initramfs"; 778 #endif 779 break; 780 case ANDROID_BOOT_MODE_RECOVERY: 781 /* In recovery mode we still boot the kernel from "boot" but 782 * don't skip the initramfs so it boots to recovery. 783 */ 784 #ifndef CONFIG_ANDROID_AB 785 boot_partname = ANDROID_PARTITION_RECOVERY; 786 #endif 787 break; 788 case ANDROID_BOOT_MODE_BOOTLOADER: 789 /* Bootloader mode enters fastboot. If this operation fails we 790 * simply return since we can't recover from this situation by 791 * switching to another slot. 792 */ 793 return android_bootloader_boot_bootloader(); 794 } 795 796 #ifdef CONFIG_ANDROID_AB 797 /*TODO: get from pre-loader or misc partition*/ 798 if (rk_avb_get_current_slot(slot_suffix)) 799 return -1; 800 801 if (slot_suffix[0] != '_') { 802 printf("There is no bootable slot!\n"); 803 return -1; 804 } 805 #endif 806 807 #ifdef CONFIG_ANDROID_AVB 808 if (android_slot_verify(boot_partname, load_address, slot_suffix)) 809 return -1; 810 #else 811 /* 812 * 2. Load the boot/recovery from the desired "boot" partition. 813 * Determine if this is an AOSP image. 814 */ 815 disk_partition_t boot_part_info; 816 part_num = 817 android_part_get_info_by_name_suffix(dev_desc, 818 boot_partname, 819 slot_suffix, &boot_part_info); 820 if (part_num < 0) { 821 printf("%s Could not found bootable partition %s\n", __func__, 822 boot_partname); 823 return -1; 824 } 825 debug("ANDROID: Loading kernel from \"%s\", partition %d.\n", 826 boot_part_info.name, part_num); 827 828 ret = android_image_load(dev_desc, &boot_part_info, load_address, 829 -1UL); 830 if (ret < 0) { 831 printf("%s %s part load fail\n", __func__, boot_part_info.name); 832 return ret; 833 } 834 load_address = ret; 835 #endif 836 837 /* Set Android root variables. */ 838 env_set_ulong("android_root_devnum", dev_desc->devnum); 839 env_set("android_slotsufix", slot_suffix); 840 841 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK 842 /* read oem unlock status and attach to bootargs */ 843 uint8_t unlock = 0; 844 TEEC_Result result; 845 char oem_unlock[OEM_UNLOCK_ARG_SIZE] = {0}; 846 result = trusty_read_oem_unlock(&unlock); 847 if (result) { 848 printf("read oem unlock status with error : 0x%x\n", result); 849 } else { 850 snprintf(oem_unlock, OEM_UNLOCK_ARG_SIZE, "androidboot.oem_unlocked=%d", unlock); 851 env_update("bootargs", oem_unlock); 852 } 853 #endif 854 855 /* Assemble the command line */ 856 command_line = android_assemble_cmdline(slot_suffix, mode_cmdline); 857 env_update("bootargs", command_line); 858 859 debug("ANDROID: bootargs: \"%s\"\n", command_line); 860 861 #ifdef CONFIG_SUPPORT_OEM_DTB 862 if (android_bootloader_get_fdt(ANDROID_PARTITION_OEM, 863 ANDROID_ARG_FDT_FILENAME)) { 864 printf("Can not get the fdt data from oem!\n"); 865 } 866 #else 867 ret = android_image_get_fdt((void *)load_address, &fdt_addr); 868 if (!ret) 869 env_set_hex("fdt_addr", fdt_addr); 870 871 /* 872 * Actually if CONFIG_USING_KERNEL_DTB is enbled, we have already read kernel 873 * dtb and apply overlay in init_kernel_dtb(), so that we don't need to apply 874 * again, we would pass the current fdt to kernel. 875 */ 876 #if defined(CONFIG_CMD_DTIMG) && \ 877 defined(CONFIG_OF_LIBFDT_OVERLAY) && !defined(CONFIG_USING_KERNEL_DTB) 878 android_fdt_overlay_apply((void *)fdt_addr); 879 #endif 880 #endif 881 android_bootloader_boot_kernel(load_address); 882 883 /* TODO: If the kernel doesn't boot mark the selected slot as bad. */ 884 return -1; 885 } 886 887 int android_avb_boot_flow(char *slot_suffix, unsigned long kernel_address) 888 { 889 struct blk_desc *dev_desc; 890 disk_partition_t boot_part_info; 891 int ret; 892 dev_desc = rockchip_get_bootdev(); 893 if (!dev_desc) { 894 printf("%s: dev_desc is NULL!\n", __func__); 895 return -1; 896 } 897 /* Load the kernel from the desired "boot" partition. */ 898 android_part_get_info_by_name_suffix(dev_desc, 899 ANDROID_PARTITION_BOOT, 900 slot_suffix, &boot_part_info); 901 ret = android_image_load(dev_desc, &boot_part_info, kernel_address, 902 -1UL); 903 if (ret < 0) 904 return ret; 905 android_bootloader_boot_kernel(kernel_address); 906 907 /* TODO: If the kernel doesn't boot mark the selected slot as bad. */ 908 return -1; 909 } 910 911 int android_boot_flow(unsigned long kernel_address) 912 { 913 struct blk_desc *dev_desc; 914 disk_partition_t boot_part_info; 915 int ret; 916 dev_desc = rockchip_get_bootdev(); 917 if (!dev_desc) { 918 printf("%s: dev_desc is NULL!\n", __func__); 919 return -1; 920 } 921 /* Load the kernel from the desired "boot" partition. */ 922 part_get_info_by_name(dev_desc, ANDROID_PARTITION_BOOT, &boot_part_info); 923 ret = android_image_load(dev_desc, &boot_part_info, kernel_address, 924 -1UL); 925 if (ret < 0) 926 return ret; 927 android_bootloader_boot_kernel(kernel_address); 928 929 /* TODO: If the kernel doesn't boot mark the selected slot as bad. */ 930 return -1; 931 } 932