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