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 <asm/arch/hotkey.h> 14 #include <cli.h> 15 #include <common.h> 16 #include <dt_table.h> 17 #include <image-android-dt.h> 18 #include <malloc.h> 19 #include <fdt_support.h> 20 #include <fs.h> 21 #include <boot_rkimg.h> 22 #include <attestation_key.h> 23 #include <keymaster.h> 24 #include <linux/libfdt_env.h> 25 #include <optee_include/OpteeClientInterface.h> 26 #include <bidram.h> 27 #include <console.h> 28 #include <sysmem.h> 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 #define ANDROID_PARTITION_BOOT "boot" 33 #define ANDROID_PARTITION_MISC "misc" 34 #define ANDROID_PARTITION_OEM "oem" 35 #define ANDROID_PARTITION_RECOVERY "recovery" 36 #define ANDROID_PARTITION_SYSTEM "system" 37 #define ANDROID_PARTITION_VBMETA "vbmeta" 38 39 #define ANDROID_ARG_SLOT_SUFFIX "androidboot.slot_suffix=" 40 #define ANDROID_ARG_ROOT "root=" 41 #define ANDROID_ARG_SERIALNO "androidboot.serialno=" 42 #define ANDROID_VERIFY_STATE "androidboot.verifiedbootstate=" 43 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 44 #define ANDROID_ARG_FDT_FILENAME "rk-kernel.dtb" 45 #define BOOTLOADER_MESSAGE_OFFSET_IN_MISC (16 * 1024) 46 #define BOOTLOADER_MESSAGE_BLK_OFFSET (BOOTLOADER_MESSAGE_OFFSET_IN_MISC >> 9) 47 #else 48 #define ANDROID_ARG_FDT_FILENAME "kernel.dtb" 49 #endif 50 #define OEM_UNLOCK_ARG_SIZE 30 51 #define UUID_SIZE 37 52 53 #if defined(CONFIG_ANDROID_AB) && !defined(CONFIG_ANDROID_AVB) 54 static int get_partition_unique_uuid(char *partition, 55 char *guid_buf, 56 size_t guid_buf_size) 57 { 58 struct blk_desc *dev_desc; 59 disk_partition_t part_info; 60 61 dev_desc = rockchip_get_bootdev(); 62 if (!dev_desc) { 63 printf("%s: Could not find device\n", __func__); 64 return -1; 65 } 66 67 if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 68 printf("Could not find \"%s\" partition\n", partition); 69 return -1; 70 } 71 72 if (guid_buf && guid_buf_size > 0) 73 memcpy(guid_buf, part_info.uuid, guid_buf_size); 74 75 return 0; 76 } 77 #endif 78 79 char *android_str_append(char *base_name, char *slot_suffix) 80 { 81 char *part_name; 82 size_t part_name_len; 83 84 part_name_len = strlen(base_name) + 1; 85 if (slot_suffix) 86 part_name_len += strlen(slot_suffix); 87 part_name = malloc(part_name_len); 88 if (!part_name) 89 return NULL; 90 strcpy(part_name, base_name); 91 if (slot_suffix && (slot_suffix[0] != '\0')) 92 strcat(part_name, slot_suffix); 93 94 return part_name; 95 } 96 97 int android_bootloader_message_load( 98 struct blk_desc *dev_desc, 99 const disk_partition_t *part_info, 100 struct android_bootloader_message *message) 101 { 102 ulong message_blocks = sizeof(struct android_bootloader_message) / 103 part_info->blksz; 104 if (message_blocks > part_info->size) { 105 printf("misc partition too small.\n"); 106 return -1; 107 } 108 109 #ifdef CONFIG_RKIMG_BOOTLOADER 110 if (blk_dread(dev_desc, part_info->start + BOOTLOADER_MESSAGE_BLK_OFFSET, 111 message_blocks, message) != 112 #else 113 if (blk_dread(dev_desc, part_info->start, message_blocks, message) != 114 #endif 115 message_blocks) { 116 printf("Could not read from misc partition\n"); 117 return -1; 118 } 119 debug("ANDROID: Loaded BCB, %lu blocks.\n", message_blocks); 120 return 0; 121 } 122 123 static int android_bootloader_message_write( 124 struct blk_desc *dev_desc, 125 const disk_partition_t *part_info, 126 struct android_bootloader_message *message) 127 { 128 #ifdef CONFIG_RKIMG_BOOTLOADER 129 ulong message_blocks = sizeof(struct android_bootloader_message) / 130 part_info->blksz + BOOTLOADER_MESSAGE_BLK_OFFSET; 131 #else 132 ulong message_blocks = sizeof(struct android_bootloader_message) / 133 part_info->blksz; 134 #endif 135 if (message_blocks > part_info->size) { 136 printf("misc partition too small.\n"); 137 return -1; 138 } 139 140 if (blk_dwrite(dev_desc, part_info->start, message_blocks, message) != 141 message_blocks) { 142 printf("Could not write to misc partition\n"); 143 return -1; 144 } 145 debug("ANDROID: Wrote new BCB, %lu blocks.\n", message_blocks); 146 return 0; 147 } 148 149 static enum android_boot_mode android_bootloader_load_and_clear_mode( 150 struct blk_desc *dev_desc, 151 const disk_partition_t *misc_part_info) 152 { 153 struct android_bootloader_message bcb; 154 155 #ifdef CONFIG_FASTBOOT 156 char *bootloader_str; 157 158 /* Check for message from bootloader stored in RAM from a previous boot. 159 */ 160 bootloader_str = (char *)CONFIG_FASTBOOT_BUF_ADDR; 161 if (!strcmp("reboot-bootloader", bootloader_str)) { 162 bootloader_str[0] = '\0'; 163 return ANDROID_BOOT_MODE_BOOTLOADER; 164 } 165 #endif 166 167 /* Check and update the BCB message if needed. */ 168 if (android_bootloader_message_load(dev_desc, misc_part_info, &bcb) < 169 0) { 170 printf("WARNING: Unable to load the BCB.\n"); 171 return ANDROID_BOOT_MODE_NORMAL; 172 } 173 174 if (!strcmp("bootonce-bootloader", bcb.command)) { 175 /* Erase the message in the BCB since this value should be used 176 * only once. 177 */ 178 memset(bcb.command, 0, sizeof(bcb.command)); 179 android_bootloader_message_write(dev_desc, misc_part_info, 180 &bcb); 181 return ANDROID_BOOT_MODE_BOOTLOADER; 182 } 183 184 if (!strcmp("boot-recovery", bcb.command)) 185 return ANDROID_BOOT_MODE_RECOVERY; 186 187 return ANDROID_BOOT_MODE_NORMAL; 188 } 189 190 /** 191 * Return the reboot reason string for the passed boot mode. 192 * 193 * @param mode The Android Boot mode. 194 * @return a pointer to the reboot reason string for mode. 195 */ 196 static const char *android_boot_mode_str(enum android_boot_mode mode) 197 { 198 switch (mode) { 199 case ANDROID_BOOT_MODE_NORMAL: 200 return "(none)"; 201 case ANDROID_BOOT_MODE_RECOVERY: 202 return "recovery"; 203 case ANDROID_BOOT_MODE_BOOTLOADER: 204 return "bootloader"; 205 } 206 return NULL; 207 } 208 209 static int android_part_get_info_by_name_suffix(struct blk_desc *dev_desc, 210 const char *base_name, 211 const char *slot_suffix, 212 disk_partition_t *part_info) 213 { 214 char *part_name; 215 int part_num; 216 size_t part_name_len; 217 218 part_name_len = strlen(base_name) + 1; 219 if (slot_suffix) 220 part_name_len += strlen(slot_suffix); 221 part_name = malloc(part_name_len); 222 if (!part_name) 223 return -1; 224 strcpy(part_name, base_name); 225 if (slot_suffix && (slot_suffix[0] != '\0')) 226 strcat(part_name, slot_suffix); 227 228 part_num = part_get_info_by_name(dev_desc, part_name, part_info); 229 if (part_num < 0) { 230 debug("ANDROID: Could not find partition \"%s\"\n", part_name); 231 part_num = -1; 232 } 233 234 free(part_name); 235 return part_num; 236 } 237 238 static int android_bootloader_boot_bootloader(void) 239 { 240 const char *fastboot_cmd = env_get("fastbootcmd"); 241 242 if (fastboot_cmd == NULL) { 243 printf("fastboot_cmd is null, run default fastboot_cmd!\n"); 244 fastboot_cmd = "fastboot usb 0"; 245 } 246 247 return run_command(fastboot_cmd, CMD_FLAG_ENV); 248 } 249 250 #ifdef CONFIG_SUPPORT_OEM_DTB 251 static int android_bootloader_get_fdt(const char *part_name, 252 const char *load_file_name) 253 { 254 struct blk_desc *dev_desc; 255 disk_partition_t boot_part_info; 256 char *fdt_addr = NULL; 257 char slot_suffix[5] = {0}; 258 char dev_part[3] = {0}; 259 loff_t bytes = 0; 260 loff_t pos = 0; 261 loff_t len_read; 262 unsigned long addr = 0; 263 int part_num = -1; 264 int ret; 265 266 dev_desc = rockchip_get_bootdev(); 267 if (!dev_desc) { 268 printf("%s: dev_desc is NULL!\n", __func__); 269 return -1; 270 } 271 272 memset(&boot_part_info, 0, sizeof(boot_part_info)); 273 274 #ifdef CONFIG_RK_AVB_LIBAVB_USER 275 if (rk_avb_get_current_slot(slot_suffix)) { 276 printf("ANDROID: Get Current Slot error.\n"); 277 return -1; 278 } 279 280 part_num = android_part_get_info_by_name_suffix(dev_desc, 281 part_name, 282 slot_suffix, &boot_part_info); 283 #else 284 part_num = part_get_info_by_name(dev_desc, part_name, &boot_part_info); 285 if (part_num < 0) { 286 printf("ANDROID: Could not find partition \"%s\"\n", part_name); 287 return -1; 288 } 289 #endif 290 291 snprintf(dev_part, ARRAY_SIZE(dev_part), ":%x", part_num); 292 if (fs_set_blk_dev_with_part(dev_desc, part_num)) 293 return -1; 294 295 fdt_addr = env_get("fdt_addr_r"); 296 if (!fdt_addr) { 297 printf("ANDROID: No Found FDT Load Address.\n"); 298 return -1; 299 } 300 addr = simple_strtoul(fdt_addr, NULL, 16); 301 302 ret = fs_read(load_file_name, addr, pos, bytes, &len_read); 303 if (ret < 0) 304 return -1; 305 306 return 0; 307 } 308 #endif 309 310 /* 311 * Test on RK3308 AARCH64 mode (Cortex A35 816 MHZ) boot with eMMC: 312 * 313 * |-------------------------------------------------------------------| 314 * | Format | Size(Byte) | Ratio | Decomp time(ms) | Boot time(ms) | 315 * |-------------------------------------------------------------------| 316 * | Image | 7720968 | | | 488 | 317 * |-------------------------------------------------------------------| 318 * | Image.lz4 | 4119448 | 53% | 59 | 455 | 319 * |-------------------------------------------------------------------| 320 * | Image.lzo | 3858322 | 49% | 141 | 536 | 321 * |-------------------------------------------------------------------| 322 * | Image.gz | 3529108 | 45% | 222 | 609 | 323 * |-------------------------------------------------------------------| 324 * | Image.bz2 | 3295914 | 42% | 2940 | | 325 * |-------------------------------------------------------------------| 326 * | Image.lzma| 2683750 | 34% | | | 327 * |-------------------------------------------------------------------| 328 */ 329 static int sysmem_alloc_uncomp_kernel(ulong andr_hdr, 330 ulong uncomp_kaddr, u32 comp) 331 { 332 struct andr_img_hdr *hdr = (struct andr_img_hdr *)andr_hdr; 333 ulong ksize, kaddr; 334 335 if (comp != IH_COMP_NONE) { 336 /* Release compressed sysmem */ 337 kaddr = env_get_hex("kernel_addr_c", 0); 338 if (!kaddr) 339 kaddr = env_get_hex("kernel_addr_r", 0); 340 kaddr -= hdr->page_size; 341 if (sysmem_free((phys_addr_t)kaddr)) 342 return -EINVAL; 343 344 /* 345 * Use smaller Ratio to get larger estimated uncompress 346 * kernel size. 347 */ 348 if (comp == IH_COMP_ZIMAGE) 349 ksize = hdr->kernel_size * 100 / 45; 350 else if (comp == IH_COMP_LZ4) 351 ksize = hdr->kernel_size * 100 / 50; 352 else if (comp == IH_COMP_LZO) 353 ksize = hdr->kernel_size * 100 / 45; 354 else if (comp == IH_COMP_GZIP) 355 ksize = hdr->kernel_size * 100 / 40; 356 else if (comp == IH_COMP_BZIP2) 357 ksize = hdr->kernel_size * 100 / 40; 358 else if (comp == IH_COMP_LZMA) 359 ksize = hdr->kernel_size * 100 / 30; 360 else 361 ksize = hdr->kernel_size; 362 363 kaddr = uncomp_kaddr; 364 ksize = ALIGN(ksize, 512); 365 if (!sysmem_alloc_base(MEMBLK_ID_UNCOMP_KERNEL, 366 (phys_addr_t)kaddr, ksize)) 367 return -ENOMEM; 368 369 hotkey_run(HK_SYSMEM); 370 } 371 372 return 0; 373 } 374 375 int android_bootloader_boot_kernel(unsigned long kernel_address) 376 { 377 char *kernel_addr_r = env_get("kernel_addr_r"); 378 char *kernel_addr_c = env_get("kernel_addr_c"); 379 char *fdt_addr = env_get("fdt_addr"); 380 char kernel_addr_str[12]; 381 char comp_str[32] = {0}; 382 ulong comp_type; 383 const char *comp_name[] = { 384 [IH_COMP_NONE] = "IMAGE", 385 [IH_COMP_GZIP] = "GZIP", 386 [IH_COMP_BZIP2] = "BZIP2", 387 [IH_COMP_LZMA] = "LZMA", 388 [IH_COMP_LZO] = "LZO", 389 [IH_COMP_LZ4] = "LZ4", 390 [IH_COMP_ZIMAGE]= "ZIMAGE", 391 }; 392 char *bootm_args[] = { 393 "bootm", kernel_addr_str, kernel_addr_str, fdt_addr, NULL }; 394 395 comp_type = env_get_ulong("os_comp", 10, 0); 396 sprintf(kernel_addr_str, "0x%lx", kernel_address); 397 398 if (comp_type != IH_COMP_NONE) { 399 if (comp_type == IH_COMP_ZIMAGE && 400 kernel_addr_r && !kernel_addr_c) { 401 kernel_addr_c = kernel_addr_r; 402 kernel_addr_r = __stringify(CONFIG_SYS_SDRAM_BASE); 403 } 404 snprintf(comp_str, 32, "%s%s%s", 405 "(Uncompress to ", kernel_addr_r, ")"); 406 } 407 408 printf("Booting %s kernel at %s%s with fdt at %s...\n\n\n", 409 comp_name[comp_type], 410 comp_type != IH_COMP_NONE ? kernel_addr_c : kernel_addr_r, 411 comp_str, fdt_addr); 412 413 hotkey_run(HK_SYSMEM); 414 415 /* 416 * Check whether there is enough space for uncompress kernel, 417 * Actually, here only gives a sysmem warning message when failed 418 * but never return -1. 419 */ 420 if (sysmem_alloc_uncomp_kernel(kernel_address, 421 simple_strtoul(kernel_addr_r, NULL, 16), 422 comp_type)) 423 return -1; 424 425 do_bootm(NULL, 0, 4, bootm_args); 426 427 return -1; 428 } 429 430 static char *strjoin(const char **chunks, char separator) 431 { 432 int len, joined_len = 0; 433 char *ret, *current; 434 const char **p; 435 436 for (p = chunks; *p; p++) 437 joined_len += strlen(*p) + 1; 438 439 if (!joined_len) { 440 ret = malloc(1); 441 if (ret) 442 ret[0] = '\0'; 443 return ret; 444 } 445 446 ret = malloc(joined_len); 447 current = ret; 448 if (!ret) 449 return ret; 450 451 for (p = chunks; *p; p++) { 452 len = strlen(*p); 453 memcpy(current, *p, len); 454 current += len; 455 *current = separator; 456 current++; 457 } 458 /* Replace the last separator by a \0. */ 459 current[-1] = '\0'; 460 return ret; 461 } 462 463 /** android_assemble_cmdline - Assemble the command line to pass to the kernel 464 * @return a newly allocated string 465 */ 466 char *android_assemble_cmdline(const char *slot_suffix, 467 const char *extra_args) 468 { 469 const char *cmdline_chunks[16]; 470 const char **current_chunk = cmdline_chunks; 471 char *env_cmdline, *cmdline, *rootdev_input, *serialno; 472 char *allocated_suffix = NULL; 473 char *allocated_serialno = NULL; 474 char *allocated_rootdev = NULL; 475 unsigned long rootdev_len; 476 477 env_cmdline = env_get("bootargs"); 478 if (env_cmdline) 479 *(current_chunk++) = env_cmdline; 480 481 /* The |slot_suffix| needs to be passed to the kernel to know what 482 * slot to boot from. 483 */ 484 if (slot_suffix) { 485 allocated_suffix = malloc(strlen(ANDROID_ARG_SLOT_SUFFIX) + 486 strlen(slot_suffix) + 1); 487 memset(allocated_suffix, 0, strlen(ANDROID_ARG_SLOT_SUFFIX) 488 + strlen(slot_suffix) + 1); 489 strcpy(allocated_suffix, ANDROID_ARG_SLOT_SUFFIX); 490 strcat(allocated_suffix, slot_suffix); 491 *(current_chunk++) = allocated_suffix; 492 } 493 494 serialno = env_get("serial#"); 495 if (serialno) { 496 allocated_serialno = malloc(strlen(ANDROID_ARG_SERIALNO) + 497 strlen(serialno) + 1); 498 memset(allocated_serialno, 0, strlen(ANDROID_ARG_SERIALNO) + 499 strlen(serialno) + 1); 500 strcpy(allocated_serialno, ANDROID_ARG_SERIALNO); 501 strcat(allocated_serialno, serialno); 502 *(current_chunk++) = allocated_serialno; 503 } 504 505 rootdev_input = env_get("android_rootdev"); 506 if (rootdev_input) { 507 rootdev_len = strlen(ANDROID_ARG_ROOT) + CONFIG_SYS_CBSIZE + 1; 508 allocated_rootdev = malloc(rootdev_len); 509 strcpy(allocated_rootdev, ANDROID_ARG_ROOT); 510 cli_simple_process_macros(rootdev_input, 511 allocated_rootdev + 512 strlen(ANDROID_ARG_ROOT)); 513 /* Make sure that the string is null-terminated since the 514 * previous could not copy to the end of the input string if it 515 * is too big. 516 */ 517 allocated_rootdev[rootdev_len - 1] = '\0'; 518 *(current_chunk++) = allocated_rootdev; 519 } 520 521 if (extra_args) 522 *(current_chunk++) = extra_args; 523 524 *(current_chunk++) = NULL; 525 cmdline = strjoin(cmdline_chunks, ' '); 526 free(allocated_suffix); 527 free(allocated_rootdev); 528 return cmdline; 529 } 530 531 #ifdef CONFIG_ANDROID_AVB 532 static void slot_set_unbootable(AvbABSlotData* slot) 533 { 534 slot->priority = 0; 535 slot->tries_remaining = 0; 536 slot->successful_boot = 0; 537 } 538 539 static AvbSlotVerifyResult android_slot_verify(char *boot_partname, 540 unsigned long *android_load_address, 541 char *slot_suffix) 542 { 543 const char *requested_partitions[1] = {NULL}; 544 uint8_t unlocked = true; 545 AvbOps *ops; 546 AvbSlotVerifyFlags flags; 547 AvbSlotVerifyData *slot_data[1] = {NULL}; 548 AvbSlotVerifyResult verify_result; 549 AvbABData ab_data, ab_data_orig; 550 size_t slot_index_to_boot = 0; 551 char verify_state[38] = {0}; 552 char can_boot = 1; 553 unsigned long load_address = *android_load_address; 554 struct andr_img_hdr *hdr; 555 556 requested_partitions[0] = boot_partname; 557 ops = avb_ops_user_new(); 558 if (ops == NULL) { 559 printf("avb_ops_user_new() failed!\n"); 560 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 561 } 562 563 if (ops->read_is_device_unlocked(ops, (bool *)&unlocked) != AVB_IO_RESULT_OK) 564 printf("Error determining whether device is unlocked.\n"); 565 566 printf("read_is_device_unlocked() ops returned that device is %s\n", 567 (unlocked & LOCK_MASK)? "UNLOCKED" : "LOCKED"); 568 569 flags = AVB_SLOT_VERIFY_FLAGS_NONE; 570 if (unlocked & LOCK_MASK) 571 flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR; 572 573 if(load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) { 574 printf("Can not load metadata\n"); 575 return AVB_SLOT_VERIFY_RESULT_ERROR_IO; 576 } 577 578 if (!strncmp(slot_suffix, "_a", 2)) 579 slot_index_to_boot = 0; 580 else if (!strncmp(slot_suffix, "_b", 2)) 581 slot_index_to_boot = 1; 582 else 583 slot_index_to_boot = 0; 584 585 verify_result = 586 avb_slot_verify(ops, 587 requested_partitions, 588 slot_suffix, 589 flags, 590 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 591 &slot_data[0]); 592 593 strcat(verify_state, ANDROID_VERIFY_STATE); 594 switch (verify_result) { 595 case AVB_SLOT_VERIFY_RESULT_OK: 596 if (unlocked & LOCK_MASK) 597 strcat(verify_state, "orange"); 598 else 599 strcat(verify_state, "green"); 600 break; 601 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: 602 if (unlocked & LOCK_MASK) 603 strcat(verify_state, "orange"); 604 else 605 strcat(verify_state, "yellow"); 606 break; 607 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: 608 case AVB_SLOT_VERIFY_RESULT_ERROR_IO: 609 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: 610 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: 611 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: 612 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: 613 default: 614 if (unlocked & LOCK_MASK) 615 strcat(verify_state, "orange"); 616 else 617 strcat(verify_state, "red"); 618 break; 619 } 620 621 if (!slot_data[0]) { 622 can_boot = 0; 623 goto out; 624 } 625 626 if (verify_result == AVB_SLOT_VERIFY_RESULT_OK || 627 verify_result == AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED || 628 (unlocked & LOCK_MASK)) { 629 int len = 0; 630 char *bootargs, *newbootargs; 631 632 if (*slot_data[0]->cmdline) { 633 debug("Kernel command line: %s\n", slot_data[0]->cmdline); 634 len += strlen(slot_data[0]->cmdline); 635 } 636 637 bootargs = env_get("bootargs"); 638 if (bootargs) 639 len += strlen(bootargs); 640 641 newbootargs = malloc(len + 2); 642 643 if (!newbootargs) { 644 puts("Error: malloc in android_slot_verify failed!\n"); 645 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 646 } 647 *newbootargs = '\0'; 648 649 if (bootargs) { 650 strcpy(newbootargs, bootargs); 651 strcat(newbootargs, " "); 652 } 653 if (*slot_data[0]->cmdline) 654 strcat(newbootargs, slot_data[0]->cmdline); 655 env_set("bootargs", newbootargs); 656 657 /* Reserve page_size */ 658 hdr = (void *)slot_data[0]->loaded_partitions->data; 659 load_address -= hdr->page_size; 660 *android_load_address = load_address; 661 662 memcpy((uint8_t *)load_address, 663 slot_data[0]->loaded_partitions->data, 664 slot_data[0]->loaded_partitions->data_size); 665 } else { 666 slot_set_unbootable(&ab_data.slots[slot_index_to_boot]); 667 } 668 669 out: 670 #ifdef CONFIG_ANDROID_AB 671 /* ... and decrement tries remaining, if applicable. */ 672 if (!ab_data.slots[slot_index_to_boot].successful_boot && 673 ab_data.slots[slot_index_to_boot].tries_remaining > 0) { 674 ab_data.slots[slot_index_to_boot].tries_remaining -= 1; 675 } 676 #endif 677 env_update("bootargs", verify_state); 678 if (save_metadata_if_changed(ops->ab_ops, &ab_data, &ab_data_orig)) { 679 printf("Can not save metadata\n"); 680 verify_result = AVB_SLOT_VERIFY_RESULT_ERROR_IO; 681 } 682 683 if (slot_data[0] != NULL) 684 avb_slot_verify_data_free(slot_data[0]); 685 686 if ((unlocked & LOCK_MASK) && can_boot) 687 return 0; 688 else 689 return verify_result; 690 } 691 #endif 692 693 #if defined(CONFIG_CMD_DTIMG) && defined(CONFIG_OF_LIBFDT_OVERLAY) 694 695 /* 696 * Default return index 0. 697 */ 698 __weak int board_select_fdt_index(ulong dt_table_hdr) 699 { 700 /* 701 * User can use "dt_for_each_entry(entry, hdr, idx)" to iterate 702 * over all dt entry of DT image and pick up which they want. 703 * 704 * Example: 705 * struct dt_table_entry *entry; 706 * int index; 707 * 708 * dt_for_each_entry(entry, dt_table_hdr, index) { 709 * 710 * .... (use entry) 711 * } 712 * 713 * return index; 714 */ 715 return 0; 716 } 717 718 static int android_get_dtbo(ulong *fdt_dtbo, 719 const struct andr_img_hdr *hdr, 720 int *index) 721 { 722 struct dt_table_header *dt_hdr = NULL; 723 struct blk_desc *dev_desc; 724 const char *part_name; 725 disk_partition_t part_info; 726 u32 blk_offset, blk_cnt; 727 void *buf; 728 ulong e_addr; 729 u32 e_size; 730 int e_idx; 731 int ret; 732 733 /* Get partition according to boot mode */ 734 if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY) 735 part_name = PART_RECOVERY; 736 else 737 part_name = PART_DTBO; 738 739 /* Get partition info */ 740 dev_desc = rockchip_get_bootdev(); 741 if (!dev_desc) { 742 printf("%s: dev_desc is NULL!\n", __func__); 743 return -ENODEV; 744 } 745 746 ret = part_get_info_by_name(dev_desc, part_name, &part_info); 747 if (ret < 0) { 748 printf("%s: failed to get %s part info, ret=%d\n", 749 __func__, part_name, ret); 750 return ret; 751 } 752 753 /* Check dt table header */ 754 if (!strcmp(part_name, PART_RECOVERY)) 755 blk_offset = part_info.start + 756 (hdr->recovery_dtbo_offset / part_info.blksz); 757 else 758 blk_offset = part_info.start; 759 760 dt_hdr = memalign(ARCH_DMA_MINALIGN, part_info.blksz); 761 if (!dt_hdr) { 762 printf("%s: out of memory for dt header!\n", __func__); 763 return -ENOMEM; 764 } 765 766 ret = blk_dread(dev_desc, blk_offset, 1, dt_hdr); 767 if (ret != 1) { 768 printf("%s: failed to read dt table header\n", 769 __func__); 770 goto out1; 771 } 772 773 if (!android_dt_check_header((ulong)dt_hdr)) { 774 printf("%s: Error: invalid dt table header: 0x%x\n", 775 __func__, dt_hdr->magic); 776 ret = -EINVAL; 777 goto out1; 778 } 779 780 #ifdef DEBUG 781 android_dt_print_contents((ulong)dt_hdr); 782 #endif 783 784 blk_cnt = DIV_ROUND_UP(fdt32_to_cpu(dt_hdr->total_size), 785 part_info.blksz); 786 /* Read all DT Image */ 787 buf = memalign(ARCH_DMA_MINALIGN, part_info.blksz * blk_cnt); 788 if (!buf) { 789 printf("%s: out of memory for %s part!\n", __func__, part_name); 790 ret = -ENOMEM; 791 goto out1; 792 } 793 794 ret = blk_dread(dev_desc, blk_offset, blk_cnt, buf); 795 if (ret != blk_cnt) { 796 printf("%s: failed to read dtbo, blk_cnt=%d, ret=%d\n", 797 __func__, blk_cnt, ret); 798 goto out2; 799 } 800 801 e_idx = board_select_fdt_index((ulong)buf); 802 if (e_idx < 0) { 803 printf("%s: failed to select board fdt index\n", __func__); 804 ret = -EINVAL; 805 goto out2; 806 } 807 808 ret = android_dt_get_fdt_by_index((ulong)buf, e_idx, &e_addr, &e_size); 809 if (!ret) { 810 printf("%s: failed to get fdt, index=%d\n", __func__, e_idx); 811 ret = -EINVAL; 812 goto out2; 813 } 814 815 if (fdt_dtbo) 816 *fdt_dtbo = e_addr; 817 if (index) 818 *index = e_idx; 819 820 free(dt_hdr); 821 debug("ANDROID: Loading dt entry to 0x%lx size 0x%x idx %d from \"%s\" part\n", 822 e_addr, e_size, e_idx, part_name); 823 824 return 0; 825 826 out2: 827 free(buf); 828 out1: 829 free(dt_hdr); 830 831 return ret; 832 } 833 834 int android_fdt_overlay_apply(void *fdt_addr) 835 { 836 struct andr_img_hdr *hdr; 837 struct blk_desc *dev_desc; 838 const char *part_name; 839 disk_partition_t part_info; 840 char buf[32] = {0}; 841 u32 blk_cnt; 842 ulong fdt_dtbo = -1; 843 int index = -1; 844 int ret; 845 846 /* Get partition according to boot mode */ 847 if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY) 848 part_name = PART_RECOVERY; 849 else 850 part_name = PART_BOOT; 851 852 /* Get partition info */ 853 dev_desc = rockchip_get_bootdev(); 854 if (!dev_desc) { 855 printf("%s: dev_desc is NULL!\n", __func__); 856 return -ENODEV; 857 } 858 859 ret = part_get_info_by_name(dev_desc, part_name, &part_info); 860 if (ret < 0) { 861 printf("%s: failed to get %s part info, ret=%d\n", 862 __func__, part_name, ret); 863 return ret; 864 } 865 866 blk_cnt = DIV_ROUND_UP(sizeof(*hdr), part_info.blksz); 867 hdr = memalign(ARCH_DMA_MINALIGN, part_info.blksz * blk_cnt); 868 if (!hdr) { 869 printf("%s: out of memory!\n", __func__); 870 return -ENOMEM; 871 } 872 873 ret = blk_dread(dev_desc, part_info.start, blk_cnt, hdr); 874 if (ret != blk_cnt) { 875 printf("%s: failed to read %s hdr!\n", __func__, part_name); 876 goto out; 877 } 878 879 #ifdef DEBUG 880 android_print_contents(hdr); 881 #endif 882 883 if (android_image_check_header(hdr)) 884 return -EINVAL; 885 886 /* Check header version */ 887 if (!hdr->header_version) { 888 printf("Android header version 0\n"); 889 ret = -EINVAL; 890 goto out; 891 } 892 893 ret = android_get_dtbo(&fdt_dtbo, (void *)hdr, &index); 894 if (!ret) { 895 phys_size_t fdt_size; 896 /* Must incease size before overlay */ 897 fdt_size = fdt_totalsize((void *)fdt_addr) + 898 fdt_totalsize((void *)fdt_dtbo); 899 if (sysmem_free((phys_addr_t)fdt_addr)) 900 goto out; 901 902 if (!sysmem_alloc_base(MEMBLK_ID_FDT_DTBO, 903 (phys_addr_t)fdt_addr, 904 fdt_size + CONFIG_SYS_FDT_PAD)) 905 goto out; 906 fdt_increase_size(fdt_addr, fdt_totalsize((void *)fdt_dtbo)); 907 ret = fdt_overlay_apply(fdt_addr, (void *)fdt_dtbo); 908 if (!ret) { 909 snprintf(buf, 32, "%s%d", "androidboot.dtbo_idx=", index); 910 env_update("bootargs", buf); 911 printf("ANDROID: fdt overlay OK\n"); 912 } else { 913 printf("ANDROID: fdt overlay failed, ret=%d\n", ret); 914 } 915 } 916 917 out: 918 free(hdr); 919 920 return 0; 921 } 922 #endif 923 924 static int load_android_image(struct blk_desc *dev_desc, 925 char *boot_partname, 926 char *slot_suffix, 927 unsigned long *load_address) 928 { 929 disk_partition_t boot_part; 930 int ret, part_num; 931 932 part_num = android_part_get_info_by_name_suffix(dev_desc, 933 boot_partname, 934 slot_suffix, 935 &boot_part); 936 if (part_num < 0) { 937 printf("%s: Can't find part: %s\n", __func__, boot_partname); 938 return -1; 939 } 940 debug("ANDROID: Loading kernel from \"%s\", partition %d.\n", 941 boot_part.name, part_num); 942 943 ret = android_image_load(dev_desc, &boot_part, *load_address, -1UL); 944 if (ret < 0) { 945 debug("%s: %s part load fail, ret=%d\n", 946 __func__, boot_part.name, ret); 947 return ret; 948 } 949 *load_address = ret; 950 951 return 0; 952 } 953 954 static bool avb_enabled; 955 void android_avb_set_enabled(bool enable) 956 { 957 avb_enabled = enable; 958 } 959 960 bool android_avb_is_enabled(void) 961 { 962 return avb_enabled; 963 } 964 965 int android_bootloader_boot_flow(struct blk_desc *dev_desc, 966 unsigned long load_address) 967 { 968 enum android_boot_mode mode = ANDROID_BOOT_MODE_NORMAL; 969 disk_partition_t misc_part_info; 970 int part_num; 971 int ret; 972 char *command_line; 973 char slot_suffix[3] = {0}; 974 const char *mode_cmdline = NULL; 975 char *boot_partname = ANDROID_PARTITION_BOOT; 976 ulong fdt_addr; 977 978 /* 979 * 1. Load MISC partition and determine the boot mode 980 * clear its value for the next boot if needed. 981 */ 982 part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_MISC, 983 &misc_part_info); 984 if (part_num < 0) { 985 printf("Could not find misc partition\n"); 986 } else { 987 #ifdef CONFIG_ANDROID_KEYMASTER_CA 988 /* load attestation key from misc partition. */ 989 load_attestation_key(dev_desc, &misc_part_info); 990 #endif 991 992 mode = android_bootloader_load_and_clear_mode(dev_desc, 993 &misc_part_info); 994 #ifdef CONFIG_RKIMG_BOOTLOADER 995 if (mode == ANDROID_BOOT_MODE_NORMAL) { 996 if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY) 997 mode = ANDROID_BOOT_MODE_RECOVERY; 998 } 999 #endif 1000 } 1001 1002 printf("ANDROID: reboot reason: \"%s\"\n", android_boot_mode_str(mode)); 1003 1004 #ifdef CONFIG_ANDROID_AB 1005 /*TODO: get from pre-loader or misc partition*/ 1006 if (rk_avb_get_current_slot(slot_suffix)) 1007 return -1; 1008 1009 AvbOps *ops; 1010 AvbABData ab_data; 1011 AvbABData ab_data_orig; 1012 size_t slot_index_to_boot = 0; 1013 1014 if (!strncmp(slot_suffix, "_a", 2)) 1015 slot_index_to_boot = 0; 1016 else if (!strncmp(slot_suffix, "_b", 2)) 1017 slot_index_to_boot = 1; 1018 else 1019 slot_index_to_boot = 0; 1020 ops = avb_ops_user_new(); 1021 if (ops == NULL) { 1022 printf("avb_ops_user_new() failed!\n"); 1023 return -1; 1024 } 1025 1026 if(load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) { 1027 printf("Can not load metadata\n"); 1028 return -1; 1029 } 1030 1031 /* ... and decrement tries remaining, if applicable. */ 1032 if (!ab_data.slots[slot_index_to_boot].successful_boot && 1033 ab_data.slots[slot_index_to_boot].tries_remaining > 0) { 1034 ab_data.slots[slot_index_to_boot].tries_remaining -= 1; 1035 } 1036 1037 if (save_metadata_if_changed(ops->ab_ops, &ab_data, &ab_data_orig)) { 1038 printf("Can not save metadata\n"); 1039 return -1; 1040 } 1041 1042 if (slot_suffix[0] != '_') { 1043 printf("###There is no bootable slot, bring up lastboot!###\n"); 1044 if (rk_get_lastboot() == 1) 1045 memcpy(slot_suffix, "_b", 2); 1046 else if(rk_get_lastboot() == 0) 1047 memcpy(slot_suffix, "_a", 2); 1048 else 1049 return -1; 1050 } 1051 #endif 1052 1053 switch (mode) { 1054 case ANDROID_BOOT_MODE_NORMAL: 1055 /* In normal mode, we load the kernel from "boot" but append 1056 * "skip_initramfs" to the cmdline to make it ignore the 1057 * recovery initramfs in the boot partition. 1058 */ 1059 #if (defined(CONFIG_ANDROID_AB) && !defined(CONFIG_ANDROID_AVB)) 1060 { 1061 char root_partition[20] = {0}; 1062 char guid_buf[UUID_SIZE] = {0}; 1063 char root_partuuid[70] = "root=PARTUUID="; 1064 1065 strcat(root_partition, ANDROID_PARTITION_SYSTEM); 1066 strcat(root_partition, slot_suffix); 1067 get_partition_unique_uuid(root_partition, guid_buf, UUID_SIZE); 1068 strcat(root_partuuid, guid_buf); 1069 env_update("bootargs", root_partuuid); 1070 } 1071 #endif 1072 1073 #ifdef CONFIG_ANDROID_AB 1074 mode_cmdline = "skip_initramfs"; 1075 #endif 1076 break; 1077 case ANDROID_BOOT_MODE_RECOVERY: 1078 /* In recovery mode we still boot the kernel from "boot" but 1079 * don't skip the initramfs so it boots to recovery. 1080 */ 1081 #ifndef CONFIG_ANDROID_AB 1082 boot_partname = ANDROID_PARTITION_RECOVERY; 1083 #endif 1084 break; 1085 case ANDROID_BOOT_MODE_BOOTLOADER: 1086 /* Bootloader mode enters fastboot. If this operation fails we 1087 * simply return since we can't recover from this situation by 1088 * switching to another slot. 1089 */ 1090 return android_bootloader_boot_bootloader(); 1091 } 1092 1093 #ifdef CONFIG_ANDROID_AVB 1094 uint8_t vboot_flag = 0; 1095 char vbmeta_partition[9] = {0}; 1096 disk_partition_t vbmeta_part_info; 1097 1098 if (trusty_read_vbootkey_enable_flag(&vboot_flag)) 1099 return -1; 1100 1101 if (vboot_flag) { 1102 printf("SecureBoot enabled, AVB verify\n"); 1103 android_avb_set_enabled(true); 1104 if (android_slot_verify(boot_partname, &load_address, 1105 slot_suffix)) 1106 return -1; 1107 } else { 1108 strcat(vbmeta_partition, ANDROID_PARTITION_VBMETA); 1109 strcat(vbmeta_partition, slot_suffix); 1110 part_num = part_get_info_by_name(dev_desc, vbmeta_partition, 1111 &vbmeta_part_info); 1112 if (part_num < 0) { 1113 printf("SecureBoot disabled, AVB skip\n"); 1114 env_update("bootargs", 1115 "androidboot.verifiedbootstate=orange"); 1116 android_avb_set_enabled(false); 1117 if (load_android_image(dev_desc, boot_partname, 1118 slot_suffix, &load_address)) 1119 return -1; 1120 } else { 1121 printf("SecureBoot enabled, AVB verify\n"); 1122 android_avb_set_enabled(true); 1123 if (android_slot_verify(boot_partname, &load_address, 1124 slot_suffix)) 1125 return -1; 1126 } 1127 } 1128 #else 1129 /* 1130 * 2. Load the boot/recovery from the desired "boot" partition. 1131 * Determine if this is an AOSP image. 1132 */ 1133 if (load_android_image(dev_desc, boot_partname, 1134 slot_suffix, &load_address)) 1135 return -1; 1136 #endif 1137 1138 /* Set Android root variables. */ 1139 env_set_ulong("android_root_devnum", dev_desc->devnum); 1140 env_set("android_slotsufix", slot_suffix); 1141 1142 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK 1143 /* read oem unlock status and attach to bootargs */ 1144 uint8_t unlock = 0; 1145 TEEC_Result result; 1146 char oem_unlock[OEM_UNLOCK_ARG_SIZE] = {0}; 1147 result = trusty_read_oem_unlock(&unlock); 1148 if (result) { 1149 printf("read oem unlock status with error : 0x%x\n", result); 1150 } else { 1151 snprintf(oem_unlock, OEM_UNLOCK_ARG_SIZE, "androidboot.oem_unlocked=%d", unlock); 1152 env_update("bootargs", oem_unlock); 1153 } 1154 #endif 1155 1156 /* Assemble the command line */ 1157 command_line = android_assemble_cmdline(slot_suffix, mode_cmdline); 1158 env_update("bootargs", command_line); 1159 1160 debug("ANDROID: bootargs: \"%s\"\n", command_line); 1161 1162 #ifdef CONFIG_SUPPORT_OEM_DTB 1163 if (android_bootloader_get_fdt(ANDROID_PARTITION_OEM, 1164 ANDROID_ARG_FDT_FILENAME)) { 1165 printf("Can not get the fdt data from oem!\n"); 1166 } 1167 #else 1168 ret = android_image_get_fdt((void *)load_address, &fdt_addr); 1169 if (!ret) 1170 env_set_hex("fdt_addr", fdt_addr); 1171 #endif 1172 android_bootloader_boot_kernel(load_address); 1173 1174 /* TODO: If the kernel doesn't boot mark the selected slot as bad. */ 1175 return -1; 1176 } 1177 1178 int android_avb_boot_flow(char *slot_suffix, unsigned long kernel_address) 1179 { 1180 struct blk_desc *dev_desc; 1181 disk_partition_t boot_part_info; 1182 int ret; 1183 dev_desc = rockchip_get_bootdev(); 1184 if (!dev_desc) { 1185 printf("%s: dev_desc is NULL!\n", __func__); 1186 return -1; 1187 } 1188 /* Load the kernel from the desired "boot" partition. */ 1189 android_part_get_info_by_name_suffix(dev_desc, 1190 ANDROID_PARTITION_BOOT, 1191 slot_suffix, &boot_part_info); 1192 ret = android_image_load(dev_desc, &boot_part_info, kernel_address, 1193 -1UL); 1194 if (ret < 0) 1195 return ret; 1196 android_bootloader_boot_kernel(kernel_address); 1197 1198 /* TODO: If the kernel doesn't boot mark the selected slot as bad. */ 1199 return -1; 1200 } 1201 1202 int android_boot_flow(unsigned long kernel_address) 1203 { 1204 struct blk_desc *dev_desc; 1205 disk_partition_t boot_part_info; 1206 int ret; 1207 dev_desc = rockchip_get_bootdev(); 1208 if (!dev_desc) { 1209 printf("%s: dev_desc is NULL!\n", __func__); 1210 return -1; 1211 } 1212 /* Load the kernel from the desired "boot" partition. */ 1213 part_get_info_by_name(dev_desc, ANDROID_PARTITION_BOOT, &boot_part_info); 1214 ret = android_image_load(dev_desc, &boot_part_info, kernel_address, 1215 -1UL); 1216 if (ret < 0) 1217 return ret; 1218 android_bootloader_boot_kernel(kernel_address); 1219 1220 /* TODO: If the kernel doesn't boot mark the selected slot as bad. */ 1221 return -1; 1222 } 1223