| .. | .. |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | #include <common.h> |
|---|
| 8 | 8 | #include <image.h> |
|---|
| 9 | | -#include <android_image.h> |
|---|
| 9 | +#include <android_ab.h> |
|---|
| 10 | 10 | #include <android_bootloader.h> |
|---|
| 11 | +#include <android_image.h> |
|---|
| 11 | 12 | #include <malloc.h> |
|---|
| 12 | 13 | #include <mapmem.h> |
|---|
| 13 | 14 | #include <errno.h> |
|---|
| 14 | 15 | #include <boot_rkimg.h> |
|---|
| 15 | 16 | #include <crypto.h> |
|---|
| 16 | 17 | #include <sysmem.h> |
|---|
| 18 | +#include <mp_boot.h> |
|---|
| 17 | 19 | #include <u-boot/sha1.h> |
|---|
| 18 | 20 | #ifdef CONFIG_RKIMG_BOOTLOADER |
|---|
| 19 | 21 | #include <asm/arch/resource_img.h> |
|---|
| .. | .. |
|---|
| 28 | 30 | DECLARE_GLOBAL_DATA_PTR; |
|---|
| 29 | 31 | |
|---|
| 30 | 32 | #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000 |
|---|
| 31 | | -#define ANDROID_Q_VER 10 |
|---|
| 32 | 33 | #define ANDROID_PARTITION_VENDOR_BOOT "vendor_boot" |
|---|
| 34 | +#define ANDROID_PARTITION_INIT_BOOT "init_boot" |
|---|
| 33 | 35 | |
|---|
| 34 | 36 | #define BLK_CNT(_num_bytes, _block_size) \ |
|---|
| 35 | 37 | ((_num_bytes + _block_size - 1) / _block_size) |
|---|
| .. | .. |
|---|
| 37 | 39 | static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; |
|---|
| 38 | 40 | static u32 android_kernel_comp_type = IH_COMP_NONE; |
|---|
| 39 | 41 | |
|---|
| 40 | | -u32 android_image_major_version(void) |
|---|
| 42 | +static int android_version_init(void) |
|---|
| 41 | 43 | { |
|---|
| 42 | | - /* MSB 7-bits */ |
|---|
| 43 | | - return gd->bd->bi_andr_version >> 25; |
|---|
| 44 | + struct andr_img_hdr *hdr = NULL; |
|---|
| 45 | + struct blk_desc *desc; |
|---|
| 46 | + const char *part_name = PART_BOOT; |
|---|
| 47 | + disk_partition_t part; |
|---|
| 48 | + int os_version; |
|---|
| 49 | + |
|---|
| 50 | + desc = rockchip_get_bootdev(); |
|---|
| 51 | + if (!desc) { |
|---|
| 52 | + printf("No bootdev\n"); |
|---|
| 53 | + return -1; |
|---|
| 54 | + } |
|---|
| 55 | + |
|---|
| 56 | +#ifdef CONFIG_ANDROID_AB |
|---|
| 57 | + part_name = ab_can_find_recovery_part() ? PART_RECOVERY : PART_BOOT; |
|---|
| 58 | +#endif |
|---|
| 59 | + if (part_get_info_by_name(desc, part_name, &part) < 0) |
|---|
| 60 | + return -1; |
|---|
| 61 | + |
|---|
| 62 | + hdr = populate_andr_img_hdr(desc, &part); |
|---|
| 63 | + if (!hdr) |
|---|
| 64 | + return -1; |
|---|
| 65 | + |
|---|
| 66 | + os_version = hdr->os_version; |
|---|
| 67 | + if (os_version) |
|---|
| 68 | + printf("Android %u.%u, Build %u.%u, v%d\n", |
|---|
| 69 | + (os_version >> 25) & 0x7f, (os_version >> 18) & 0x7F, |
|---|
| 70 | + ((os_version >> 4) & 0x7f) + 2000, os_version & 0x0F, |
|---|
| 71 | + hdr->header_version); |
|---|
| 72 | + free(hdr); |
|---|
| 73 | + |
|---|
| 74 | + return (os_version >> 25) & 0x7f; |
|---|
| 44 | 75 | } |
|---|
| 45 | 76 | |
|---|
| 46 | 77 | u32 android_bcb_msg_sector_offset(void) |
|---|
| 47 | 78 | { |
|---|
| 79 | + static int android_version = -1; /* static */ |
|---|
| 80 | + |
|---|
| 48 | 81 | /* |
|---|
| 49 | | - * Rockchip platforms defines BCB message at the 16KB offset of |
|---|
| 50 | | - * misc partition while the Google defines it at 0x00 offset. |
|---|
| 82 | + * get android os version: |
|---|
| 51 | 83 | * |
|---|
| 52 | | - * From Android-Q, the 0x00 offset is mandary on Google VTS, so that |
|---|
| 53 | | - * this is a compatibility according to android image 'os_version'. |
|---|
| 84 | + * There are two types of misc.img: |
|---|
| 85 | + * Rockchip platforms defines BCB message at the 16KB offset of |
|---|
| 86 | + * misc.img except for the Android version >= 10. Because Google |
|---|
| 87 | + * defines it at 0x00 offset, and from Android-10 it becoms mandary |
|---|
| 88 | + * on Google VTS. |
|---|
| 89 | + * |
|---|
| 90 | + * So we must get android 'os_version' to identify which type we |
|---|
| 91 | + * are using, then we could able to use rockchip_get_boot_mode() |
|---|
| 92 | + * which reads BCB from misc.img. |
|---|
| 54 | 93 | */ |
|---|
| 55 | 94 | #ifdef CONFIG_RKIMG_BOOTLOADER |
|---|
| 56 | | - return (android_image_major_version() >= ANDROID_Q_VER) ? 0x00 : 0x20; |
|---|
| 95 | + if (android_version < 0) |
|---|
| 96 | + android_version = android_version_init(); |
|---|
| 97 | + |
|---|
| 98 | + return (android_version >= 10) ? 0x00 : 0x20; |
|---|
| 57 | 99 | #else |
|---|
| 58 | 100 | return 0x00; |
|---|
| 59 | 101 | #endif |
|---|
| 60 | 102 | } |
|---|
| 103 | + |
|---|
| 104 | +#ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE |
|---|
| 105 | +int android_image_init_resource(struct blk_desc *desc, |
|---|
| 106 | + disk_partition_t *out_part, |
|---|
| 107 | + ulong *out_blk_offset) |
|---|
| 108 | +{ |
|---|
| 109 | + struct andr_img_hdr *hdr = NULL; |
|---|
| 110 | + const char *part_name = ANDROID_PARTITION_BOOT; |
|---|
| 111 | + disk_partition_t part; |
|---|
| 112 | + ulong offset; |
|---|
| 113 | + int ret = 0; |
|---|
| 114 | + |
|---|
| 115 | + if (!desc) |
|---|
| 116 | + return -ENODEV; |
|---|
| 117 | + |
|---|
| 118 | +#ifndef CONFIG_ANDROID_AB |
|---|
| 119 | + if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY) |
|---|
| 120 | + part_name = ANDROID_PARTITION_RECOVERY; |
|---|
| 121 | +#endif |
|---|
| 122 | + if (part_get_info_by_name(desc, part_name, &part) < 0) |
|---|
| 123 | + return -ENOENT; |
|---|
| 124 | + |
|---|
| 125 | + hdr = populate_andr_img_hdr(desc, &part); |
|---|
| 126 | + if (!hdr) |
|---|
| 127 | + return -EINVAL; |
|---|
| 128 | + |
|---|
| 129 | + if (hdr->header_version >= 2 && hdr->dtb_size) |
|---|
| 130 | + env_update("bootargs", "androidboot.dtb_idx=0"); |
|---|
| 131 | + |
|---|
| 132 | + if (hdr->header_version <= 2) { |
|---|
| 133 | + offset = hdr->page_size + |
|---|
| 134 | + ALIGN(hdr->kernel_size, hdr->page_size) + |
|---|
| 135 | + ALIGN(hdr->ramdisk_size, hdr->page_size); |
|---|
| 136 | + *out_part = part; |
|---|
| 137 | + *out_blk_offset = DIV_ROUND_UP(offset, desc->blksz); |
|---|
| 138 | + } else { |
|---|
| 139 | + ret = -EINVAL; |
|---|
| 140 | + } |
|---|
| 141 | + free(hdr); |
|---|
| 142 | + |
|---|
| 143 | + return ret; |
|---|
| 144 | +} |
|---|
| 145 | +#endif |
|---|
| 61 | 146 | |
|---|
| 62 | 147 | static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr) |
|---|
| 63 | 148 | { |
|---|
| .. | .. |
|---|
| 323 | 408 | |
|---|
| 324 | 409 | typedef enum { |
|---|
| 325 | 410 | IMG_KERNEL, |
|---|
| 326 | | - IMG_RAMDISK, |
|---|
| 411 | + IMG_RAMDISK, /* within boot.img or init_boot.img(Android-13 or later) */ |
|---|
| 327 | 412 | IMG_SECOND, |
|---|
| 328 | 413 | IMG_RECOVERY_DTBO, |
|---|
| 329 | 414 | IMG_RK_DTB, /* within resource.img in second position */ |
|---|
| .. | .. |
|---|
| 343 | 428 | { |
|---|
| 344 | 429 | struct blk_desc *desc = rockchip_get_bootdev(); |
|---|
| 345 | 430 | disk_partition_t part_vendor_boot; |
|---|
| 431 | + disk_partition_t part_init_boot; |
|---|
| 346 | 432 | __maybe_unused u32 typesz; |
|---|
| 433 | + u32 andr_version = (hdr->os_version >> 25) & 0x7f; |
|---|
| 347 | 434 | ulong pgsz = hdr->page_size; |
|---|
| 348 | 435 | ulong blksz = desc->blksz; |
|---|
| 349 | 436 | ulong blkcnt, blkoff; |
|---|
| .. | .. |
|---|
| 352 | 439 | ulong extra = 0; |
|---|
| 353 | 440 | ulong length; |
|---|
| 354 | 441 | void *buffer; |
|---|
| 442 | + void *tmp = NULL; |
|---|
| 355 | 443 | int ret = 0; |
|---|
| 356 | 444 | |
|---|
| 357 | 445 | switch (img) { |
|---|
| .. | .. |
|---|
| 366 | 454 | return -ENOMEM; |
|---|
| 367 | 455 | break; |
|---|
| 368 | 456 | case IMG_VENDOR_RAMDISK: |
|---|
| 369 | | - if (part_get_info_by_name(desc, |
|---|
| 370 | | - ANDROID_PARTITION_VENDOR_BOOT, |
|---|
| 371 | | - &part_vendor_boot) < 0) { |
|---|
| 372 | | - printf("No vendor boot partition\n"); |
|---|
| 373 | | - return -ENOENT; |
|---|
| 457 | + if (hdr->vendor_boot_buf) { |
|---|
| 458 | + ram_base = hdr->vendor_boot_buf; |
|---|
| 459 | + } else { |
|---|
| 460 | + if (part_get_info_by_name(desc, |
|---|
| 461 | + ANDROID_PARTITION_VENDOR_BOOT, |
|---|
| 462 | + &part_vendor_boot) < 0) { |
|---|
| 463 | + printf("No vendor boot partition\n"); |
|---|
| 464 | + return -ENOENT; |
|---|
| 465 | + } |
|---|
| 466 | + ram_base = 0; |
|---|
| 374 | 467 | } |
|---|
| 375 | | - /* Always load vendor boot from storage: avb full load boot/recovery */ |
|---|
| 468 | + |
|---|
| 376 | 469 | blkstart = part_vendor_boot.start; |
|---|
| 377 | 470 | pgsz = hdr->vendor_page_size; |
|---|
| 378 | | - ram_base = 0; |
|---|
| 379 | | - |
|---|
| 380 | 471 | bsoffs = ALIGN(VENDOR_BOOT_HDRv3_SIZE, pgsz); |
|---|
| 381 | 472 | length = hdr->vendor_ramdisk_size; |
|---|
| 382 | 473 | buffer = (void *)env_get_ulong("ramdisk_addr_r", 16, 0); |
|---|
| .. | .. |
|---|
| 400 | 491 | return -ENOMEM; |
|---|
| 401 | 492 | break; |
|---|
| 402 | 493 | case IMG_RAMDISK: |
|---|
| 403 | | - bsoffs = pgsz + ALIGN(hdr->kernel_size, pgsz); |
|---|
| 494 | + /* get ramdisk from init_boot.img ? */ |
|---|
| 495 | + if (hdr->header_version >= 4 && andr_version >= 13) { |
|---|
| 496 | + if (hdr->init_boot_buf) { |
|---|
| 497 | + ram_base = hdr->init_boot_buf; |
|---|
| 498 | + } else { |
|---|
| 499 | + if (part_get_info_by_name(desc, |
|---|
| 500 | + ANDROID_PARTITION_INIT_BOOT, &part_init_boot) < 0) { |
|---|
| 501 | + printf("No init boot partition\n"); |
|---|
| 502 | + return -ENOENT; |
|---|
| 503 | + } |
|---|
| 504 | + blkstart = part_init_boot.start; |
|---|
| 505 | + ram_base = 0; |
|---|
| 506 | + } |
|---|
| 507 | + bsoffs = pgsz; |
|---|
| 508 | + } else { |
|---|
| 509 | + /* get ramdisk from generic boot.img */ |
|---|
| 510 | + bsoffs = pgsz + ALIGN(hdr->kernel_size, pgsz); |
|---|
| 511 | + } |
|---|
| 512 | + |
|---|
| 404 | 513 | length = hdr->ramdisk_size; |
|---|
| 405 | 514 | buffer = (void *)env_get_ulong("ramdisk_addr_r", 16, 0); |
|---|
| 406 | 515 | blkcnt = DIV_ROUND_UP(hdr->ramdisk_size, blksz); |
|---|
| .. | .. |
|---|
| 412 | 521 | * | ramdisk | |
|---|
| 413 | 522 | * |----------------| |
|---|
| 414 | 523 | * |
|---|
| 415 | | - * ramdisk_addr_r v3: |
|---|
| 524 | + * ramdisk_addr_r v3 (Android-11 and later): |
|---|
| 416 | 525 | * |----------------|---------| |
|---|
| 417 | 526 | * | vendor-ramdisk | ramdisk | |
|---|
| 418 | 527 | * |----------------|---------| |
|---|
| 419 | 528 | * |
|---|
| 420 | | - * ramdisk_addr_r v4: |
|---|
| 529 | + * ramdisk_addr_r v4 (Android-12 and later): |
|---|
| 421 | 530 | * |----------------|---------|------------|------------| |
|---|
| 422 | 531 | * | vendor-ramdisk | ramdisk | bootconfig | bootparams | |
|---|
| 423 | 532 | * |----------------|---------|------------|------------| |
|---|
| 533 | + * |
|---|
| 534 | + * ramdisk_addr_r v4 + init_boot(Android-13 and later): |
|---|
| 535 | + * |----------------|----------------|------------|------------| |
|---|
| 536 | + * | vendor-ramdisk | (init_)ramdisk | bootconfig | bootparams | |
|---|
| 537 | + * |----------------|----------------|------------|------------| |
|---|
| 424 | 538 | */ |
|---|
| 425 | 539 | if (hdr->header_version >= 3) { |
|---|
| 426 | 540 | buffer += hdr->vendor_ramdisk_size; |
|---|
| .. | .. |
|---|
| 439 | 553 | case IMG_BOOTCONFIG: |
|---|
| 440 | 554 | if (hdr->header_version < 4) |
|---|
| 441 | 555 | return 0; |
|---|
| 442 | | - if (part_get_info_by_name(desc, |
|---|
| 443 | | - ANDROID_PARTITION_VENDOR_BOOT, |
|---|
| 444 | | - &part_vendor_boot) < 0) { |
|---|
| 445 | | - printf("No vendor boot partition\n"); |
|---|
| 446 | | - return -ENOENT; |
|---|
| 447 | | - } |
|---|
| 448 | 556 | |
|---|
| 557 | + if (hdr->vendor_boot_buf) { |
|---|
| 558 | + ram_base = hdr->vendor_boot_buf; |
|---|
| 559 | + } else { |
|---|
| 560 | + if (part_get_info_by_name(desc, |
|---|
| 561 | + ANDROID_PARTITION_VENDOR_BOOT, |
|---|
| 562 | + &part_vendor_boot) < 0) { |
|---|
| 563 | + printf("No vendor boot partition\n"); |
|---|
| 564 | + return -ENOENT; |
|---|
| 565 | + } |
|---|
| 566 | + ram_base = 0; |
|---|
| 567 | + } |
|---|
| 449 | 568 | blkstart = part_vendor_boot.start; |
|---|
| 450 | 569 | pgsz = hdr->vendor_page_size; |
|---|
| 451 | | - ram_base = 0; |
|---|
| 452 | | - |
|---|
| 453 | 570 | bsoffs = ALIGN(VENDOR_BOOT_HDRv4_SIZE, pgsz) + |
|---|
| 454 | 571 | ALIGN(hdr->vendor_ramdisk_size, pgsz) + |
|---|
| 455 | 572 | ALIGN(hdr->dtb_size, pgsz) + |
|---|
| .. | .. |
|---|
| 471 | 588 | ALIGN(hdr->ramdisk_size, pgsz); |
|---|
| 472 | 589 | length = hdr->second_size; |
|---|
| 473 | 590 | blkcnt = DIV_ROUND_UP(hdr->second_size, blksz); |
|---|
| 474 | | - buffer = malloc(blkcnt * blksz); |
|---|
| 591 | + buffer = tmp = malloc(blkcnt * blksz); |
|---|
| 475 | 592 | typesz = sizeof(hdr->second_size); |
|---|
| 476 | 593 | break; |
|---|
| 477 | 594 | case IMG_RECOVERY_DTBO: |
|---|
| .. | .. |
|---|
| 481 | 598 | ALIGN(hdr->second_size, pgsz); |
|---|
| 482 | 599 | length = hdr->recovery_dtbo_size; |
|---|
| 483 | 600 | blkcnt = DIV_ROUND_UP(hdr->recovery_dtbo_size, blksz); |
|---|
| 484 | | - buffer = malloc(blkcnt * blksz); |
|---|
| 601 | + buffer = tmp = malloc(blkcnt * blksz); |
|---|
| 485 | 602 | typesz = sizeof(hdr->recovery_dtbo_size); |
|---|
| 486 | 603 | break; |
|---|
| 487 | 604 | case IMG_DTB: |
|---|
| .. | .. |
|---|
| 492 | 609 | ALIGN(hdr->recovery_dtbo_size, pgsz); |
|---|
| 493 | 610 | length = hdr->dtb_size; |
|---|
| 494 | 611 | blkcnt = DIV_ROUND_UP(hdr->dtb_size, blksz); |
|---|
| 495 | | - buffer = malloc(blkcnt * blksz); |
|---|
| 612 | + buffer = tmp = malloc(blkcnt * blksz); |
|---|
| 496 | 613 | typesz = sizeof(hdr->dtb_size); |
|---|
| 497 | 614 | break; |
|---|
| 498 | 615 | case IMG_RK_DTB: |
|---|
| .. | .. |
|---|
| 540 | 657 | if (hdr->header_version < 3) { |
|---|
| 541 | 658 | #ifdef CONFIG_ANDROID_BOOT_IMAGE_HASH |
|---|
| 542 | 659 | #ifdef CONFIG_DM_CRYPTO |
|---|
| 543 | | - crypto_sha_update(crypto, (u32 *)buffer, length); |
|---|
| 544 | | - crypto_sha_update(crypto, (u32 *)&length, typesz); |
|---|
| 660 | + if (crypto) { |
|---|
| 661 | + crypto_sha_update(crypto, (u32 *)buffer, length); |
|---|
| 662 | + crypto_sha_update(crypto, (u32 *)&length, typesz); |
|---|
| 663 | + } |
|---|
| 545 | 664 | #else |
|---|
| 546 | 665 | sha1_update(&sha1_ctx, (void *)buffer, length); |
|---|
| 547 | 666 | sha1_update(&sha1_ctx, (void *)&length, typesz); |
|---|
| 548 | 667 | #endif |
|---|
| 549 | 668 | #endif |
|---|
| 550 | 669 | } |
|---|
| 670 | + |
|---|
| 671 | + if (tmp) |
|---|
| 672 | + free(tmp); |
|---|
| 551 | 673 | |
|---|
| 552 | 674 | return 0; |
|---|
| 553 | 675 | } |
|---|
| .. | .. |
|---|
| 605 | 727 | return -1; |
|---|
| 606 | 728 | |
|---|
| 607 | 729 | #ifdef CONFIG_ANDROID_BOOT_IMAGE_HASH |
|---|
| 608 | | - if (hdr->header_version < 3) { |
|---|
| 730 | + int verify = 1; |
|---|
| 731 | + |
|---|
| 732 | +#ifdef CONFIG_MP_BOOT |
|---|
| 733 | + verify = mpb_post(3); |
|---|
| 734 | +#endif |
|---|
| 735 | + if (hdr->header_version < 3 && verify) { |
|---|
| 609 | 736 | struct udevice *dev = NULL; |
|---|
| 610 | 737 | uchar hash[20]; |
|---|
| 611 | 738 | #ifdef CONFIG_DM_CRYPTO |
|---|
| .. | .. |
|---|
| 936 | 1063 | const disk_partition_t *boot_img) |
|---|
| 937 | 1064 | { |
|---|
| 938 | 1065 | struct boot_img_hdr_v34 *boot_hdr; |
|---|
| 1066 | + disk_partition_t part; |
|---|
| 939 | 1067 | long blk_cnt, blks_read; |
|---|
| 940 | 1068 | |
|---|
| 941 | 1069 | blk_cnt = BLK_CNT(sizeof(struct boot_img_hdr_v34), dev_desc->blksz); |
|---|
| .. | .. |
|---|
| 960 | 1088 | printf("boot header %d, is not >= v3.\n", |
|---|
| 961 | 1089 | boot_hdr->header_version); |
|---|
| 962 | 1090 | return NULL; |
|---|
| 1091 | + } |
|---|
| 1092 | + |
|---|
| 1093 | + /* Start from android-13 GKI, it doesn't assign 'os_version' */ |
|---|
| 1094 | + if (boot_hdr->header_version >= 4 && boot_hdr->os_version == 0) { |
|---|
| 1095 | + if (part_get_info_by_name(dev_desc, |
|---|
| 1096 | + ANDROID_PARTITION_INIT_BOOT, &part) > 0) |
|---|
| 1097 | + boot_hdr->os_version = 13 << 25; |
|---|
| 963 | 1098 | } |
|---|
| 964 | 1099 | |
|---|
| 965 | 1100 | return boot_hdr; |
|---|
| .. | .. |
|---|
| 1003 | 1138 | return vboot_hdr; |
|---|
| 1004 | 1139 | } |
|---|
| 1005 | 1140 | |
|---|
| 1006 | | -static int populate_boot_info(const struct boot_img_hdr_v34 *boot_hdr, |
|---|
| 1007 | | - const struct vendor_boot_img_hdr_v34 *vendor_hdr, |
|---|
| 1008 | | - struct andr_img_hdr *hdr) |
|---|
| 1141 | +int populate_boot_info(const struct boot_img_hdr_v34 *boot_hdr, |
|---|
| 1142 | + const struct vendor_boot_img_hdr_v34 *vendor_boot_hdr, |
|---|
| 1143 | + const struct boot_img_hdr_v34 *init_boot_hdr, |
|---|
| 1144 | + struct andr_img_hdr *hdr, bool save_hdr) |
|---|
| 1009 | 1145 | { |
|---|
| 1010 | 1146 | memset(hdr->magic, 0, ANDR_BOOT_MAGIC_SIZE); |
|---|
| 1011 | 1147 | memcpy(hdr->magic, boot_hdr->magic, ANDR_BOOT_MAGIC_SIZE); |
|---|
| 1012 | 1148 | |
|---|
| 1013 | 1149 | hdr->kernel_size = boot_hdr->kernel_size; |
|---|
| 1014 | | - /* don't use vendor_hdr->kernel_addr, we prefer "hdr + hdr->page_size" */ |
|---|
| 1150 | + /* don't use vendor_boot_hdr->kernel_addr, we prefer "hdr + hdr->page_size" */ |
|---|
| 1015 | 1151 | hdr->kernel_addr = ANDROID_IMAGE_DEFAULT_KERNEL_ADDR; |
|---|
| 1016 | | - /* generic ramdisk: immediately following the vendor ramdisk */ |
|---|
| 1017 | | - hdr->boot_ramdisk_size = boot_hdr->ramdisk_size; |
|---|
| 1018 | | - hdr->ramdisk_size = boot_hdr->ramdisk_size; |
|---|
| 1152 | + |
|---|
| 1153 | + /* |
|---|
| 1154 | + * generic ramdisk: immediately following the vendor ramdisk. |
|---|
| 1155 | + * It can be from init_boot.img or boot.img. |
|---|
| 1156 | + */ |
|---|
| 1157 | + if (init_boot_hdr) |
|---|
| 1158 | + hdr->ramdisk_size = init_boot_hdr->ramdisk_size; |
|---|
| 1159 | + else |
|---|
| 1160 | + hdr->ramdisk_size = boot_hdr->ramdisk_size; |
|---|
| 1019 | 1161 | |
|---|
| 1020 | 1162 | /* actually, useless */ |
|---|
| 1021 | 1163 | hdr->ramdisk_addr = env_get_ulong("ramdisk_addr_r", 16, 0); |
|---|
| .. | .. |
|---|
| 1024 | 1166 | hdr->second_size = 0; |
|---|
| 1025 | 1167 | hdr->second_addr = 0; |
|---|
| 1026 | 1168 | |
|---|
| 1027 | | - hdr->tags_addr = vendor_hdr->tags_addr; |
|---|
| 1169 | + hdr->tags_addr = vendor_boot_hdr->tags_addr; |
|---|
| 1028 | 1170 | |
|---|
| 1029 | 1171 | /* fixed in v3 */ |
|---|
| 1030 | 1172 | hdr->page_size = 4096; |
|---|
| .. | .. |
|---|
| 1032 | 1174 | hdr->os_version = boot_hdr->os_version; |
|---|
| 1033 | 1175 | |
|---|
| 1034 | 1176 | memset(hdr->name, 0, ANDR_BOOT_NAME_SIZE); |
|---|
| 1035 | | - strncpy(hdr->name, (const char *)vendor_hdr->name, ANDR_BOOT_NAME_SIZE); |
|---|
| 1177 | + strncpy(hdr->name, (const char *)vendor_boot_hdr->name, ANDR_BOOT_NAME_SIZE); |
|---|
| 1036 | 1178 | |
|---|
| 1037 | 1179 | /* removed in v3 */ |
|---|
| 1038 | 1180 | memset(hdr->cmdline, 0, ANDR_BOOT_ARGS_SIZE); |
|---|
| .. | .. |
|---|
| 1042 | 1184 | hdr->recovery_dtbo_offset = 0; |
|---|
| 1043 | 1185 | |
|---|
| 1044 | 1186 | hdr->header_size = boot_hdr->header_size; |
|---|
| 1045 | | - hdr->dtb_size = vendor_hdr->dtb_size; |
|---|
| 1046 | | - hdr->dtb_addr = vendor_hdr->dtb_addr; |
|---|
| 1187 | + hdr->dtb_size = vendor_boot_hdr->dtb_size; |
|---|
| 1188 | + hdr->dtb_addr = vendor_boot_hdr->dtb_addr; |
|---|
| 1047 | 1189 | |
|---|
| 1048 | 1190 | /* boot_img_hdr_v34 fields */ |
|---|
| 1049 | | - hdr->vendor_ramdisk_size = vendor_hdr->vendor_ramdisk_size; |
|---|
| 1050 | | - hdr->vendor_page_size = vendor_hdr->page_size; |
|---|
| 1051 | | - hdr->vendor_header_version = vendor_hdr->header_version; |
|---|
| 1052 | | - hdr->vendor_header_size = vendor_hdr->header_size; |
|---|
| 1191 | + hdr->vendor_ramdisk_size = vendor_boot_hdr->vendor_ramdisk_size; |
|---|
| 1192 | + hdr->vendor_page_size = vendor_boot_hdr->page_size; |
|---|
| 1193 | + hdr->vendor_header_version = vendor_boot_hdr->header_version; |
|---|
| 1194 | + hdr->vendor_header_size = vendor_boot_hdr->header_size; |
|---|
| 1053 | 1195 | |
|---|
| 1054 | 1196 | hdr->total_cmdline = calloc(1, TOTAL_BOOT_ARGS_SIZE); |
|---|
| 1055 | 1197 | if (!hdr->total_cmdline) |
|---|
| .. | .. |
|---|
| 1057 | 1199 | strncpy(hdr->total_cmdline, (const char *)boot_hdr->cmdline, |
|---|
| 1058 | 1200 | sizeof(boot_hdr->cmdline)); |
|---|
| 1059 | 1201 | strncat(hdr->total_cmdline, " ", 1); |
|---|
| 1060 | | - strncat(hdr->total_cmdline, (const char *)vendor_hdr->cmdline, |
|---|
| 1061 | | - sizeof(vendor_hdr->cmdline)); |
|---|
| 1202 | + strncat(hdr->total_cmdline, (const char *)vendor_boot_hdr->cmdline, |
|---|
| 1203 | + sizeof(vendor_boot_hdr->cmdline)); |
|---|
| 1062 | 1204 | |
|---|
| 1063 | 1205 | /* new for header v4 */ |
|---|
| 1064 | | - if (vendor_hdr->header_version > 3) { |
|---|
| 1206 | + if (vendor_boot_hdr->header_version >= 4) { |
|---|
| 1065 | 1207 | hdr->vendor_ramdisk_table_size = |
|---|
| 1066 | | - vendor_hdr->vendor_ramdisk_table_size; |
|---|
| 1208 | + vendor_boot_hdr->vendor_ramdisk_table_size; |
|---|
| 1067 | 1209 | hdr->vendor_ramdisk_table_entry_num = |
|---|
| 1068 | | - vendor_hdr->vendor_ramdisk_table_entry_num; |
|---|
| 1210 | + vendor_boot_hdr->vendor_ramdisk_table_entry_num; |
|---|
| 1069 | 1211 | hdr->vendor_ramdisk_table_entry_size = |
|---|
| 1070 | | - vendor_hdr->vendor_ramdisk_table_entry_size; |
|---|
| 1212 | + vendor_boot_hdr->vendor_ramdisk_table_entry_size; |
|---|
| 1071 | 1213 | /* |
|---|
| 1072 | 1214 | * If we place additional "androidboot.xxx" parameters after |
|---|
| 1073 | 1215 | * bootconfig, this field value should be increased, |
|---|
| 1074 | 1216 | * but not over than ANDROID_ADDITION_BOOTCONFIG_PARAMS_MAX_SIZE. |
|---|
| 1075 | 1217 | */ |
|---|
| 1076 | 1218 | hdr->vendor_bootconfig_size = |
|---|
| 1077 | | - vendor_hdr->vendor_bootconfig_size; |
|---|
| 1219 | + vendor_boot_hdr->vendor_bootconfig_size; |
|---|
| 1078 | 1220 | } else { |
|---|
| 1079 | 1221 | hdr->vendor_ramdisk_table_size = 0; |
|---|
| 1080 | 1222 | hdr->vendor_ramdisk_table_entry_num = 0; |
|---|
| 1081 | 1223 | hdr->vendor_ramdisk_table_entry_size = 0; |
|---|
| 1082 | 1224 | hdr->vendor_bootconfig_size = 0; |
|---|
| 1083 | 1225 | } |
|---|
| 1226 | + |
|---|
| 1227 | + hdr->init_boot_buf = save_hdr ? (void *)init_boot_hdr : 0; |
|---|
| 1228 | + hdr->vendor_boot_buf = save_hdr ? (void *)vendor_boot_hdr : 0; |
|---|
| 1084 | 1229 | |
|---|
| 1085 | 1230 | if (hdr->page_size < sizeof(*hdr)) { |
|---|
| 1086 | 1231 | printf("android hdr is over size\n"); |
|---|
| .. | .. |
|---|
| 1110 | 1255 | disk_partition_t *part_boot) |
|---|
| 1111 | 1256 | { |
|---|
| 1112 | 1257 | disk_partition_t part_vendor_boot; |
|---|
| 1113 | | - struct vendor_boot_img_hdr_v34 *vboot_hdr; |
|---|
| 1114 | | - struct boot_img_hdr_v34 *boot_hdr; |
|---|
| 1115 | | - struct andr_img_hdr *andr_hdr; |
|---|
| 1258 | + disk_partition_t part_init_boot; |
|---|
| 1259 | + struct vendor_boot_img_hdr_v34 *vboot_hdr = NULL; |
|---|
| 1260 | + struct boot_img_hdr_v34 *iboot_hdr = NULL; |
|---|
| 1261 | + struct boot_img_hdr_v34 *boot_hdr = NULL; |
|---|
| 1262 | + struct andr_img_hdr *andr_hdr = NULL; |
|---|
| 1116 | 1263 | int header_version; |
|---|
| 1264 | + int andr_version; |
|---|
| 1117 | 1265 | |
|---|
| 1118 | 1266 | if (!dev_desc || !part_boot) |
|---|
| 1119 | 1267 | return NULL; |
|---|
| .. | .. |
|---|
| 1134 | 1282 | |
|---|
| 1135 | 1283 | header_version = andr_hdr->header_version; |
|---|
| 1136 | 1284 | free(andr_hdr); |
|---|
| 1285 | + andr_hdr = NULL; |
|---|
| 1137 | 1286 | |
|---|
| 1138 | 1287 | if (header_version < 3) { |
|---|
| 1139 | 1288 | return extract_boot_image_v012_header(dev_desc, part_boot); |
|---|
| .. | .. |
|---|
| 1150 | 1299 | if (!boot_hdr || !vboot_hdr) |
|---|
| 1151 | 1300 | goto image_load_exit; |
|---|
| 1152 | 1301 | |
|---|
| 1302 | + andr_version = (boot_hdr->os_version >> 25) & 0x7f; |
|---|
| 1303 | + if (header_version >= 4 && andr_version >= 13) { |
|---|
| 1304 | + if (part_get_info_by_name(dev_desc, |
|---|
| 1305 | + ANDROID_PARTITION_INIT_BOOT, |
|---|
| 1306 | + &part_init_boot) < 0) { |
|---|
| 1307 | + printf("No init boot partition\n"); |
|---|
| 1308 | + return NULL; |
|---|
| 1309 | + } |
|---|
| 1310 | + iboot_hdr = extract_boot_image_v34_header(dev_desc, &part_init_boot); |
|---|
| 1311 | + if (!iboot_hdr) |
|---|
| 1312 | + goto image_load_exit; |
|---|
| 1313 | + if (!iboot_hdr->ramdisk_size) { |
|---|
| 1314 | + printf("No ramdisk in init boot partition\n"); |
|---|
| 1315 | + goto image_load_exit; |
|---|
| 1316 | + } |
|---|
| 1317 | + } |
|---|
| 1318 | + |
|---|
| 1153 | 1319 | andr_hdr = (struct andr_img_hdr *) |
|---|
| 1154 | 1320 | malloc(sizeof(struct andr_img_hdr)); |
|---|
| 1155 | 1321 | if (!andr_hdr) { |
|---|
| .. | .. |
|---|
| 1157 | 1323 | goto image_load_exit; |
|---|
| 1158 | 1324 | } |
|---|
| 1159 | 1325 | |
|---|
| 1160 | | - if (populate_boot_info(boot_hdr, vboot_hdr, andr_hdr)) { |
|---|
| 1326 | + if (populate_boot_info(boot_hdr, vboot_hdr, |
|---|
| 1327 | + iboot_hdr, andr_hdr, false)) { |
|---|
| 1161 | 1328 | printf("populate boot info failed\n"); |
|---|
| 1162 | 1329 | goto image_load_exit; |
|---|
| 1163 | 1330 | } |
|---|
| 1164 | 1331 | |
|---|
| 1165 | | - free(boot_hdr); |
|---|
| 1166 | | - free(vboot_hdr); |
|---|
| 1332 | +image_load_exit: |
|---|
| 1333 | + if (boot_hdr) |
|---|
| 1334 | + free(boot_hdr); |
|---|
| 1335 | + if (iboot_hdr) |
|---|
| 1336 | + free(iboot_hdr); |
|---|
| 1337 | + if (vboot_hdr) |
|---|
| 1338 | + free(vboot_hdr); |
|---|
| 1167 | 1339 | |
|---|
| 1168 | 1340 | return andr_hdr; |
|---|
| 1169 | | - |
|---|
| 1170 | | -image_load_exit: |
|---|
| 1171 | | - free(boot_hdr); |
|---|
| 1172 | | - free(vboot_hdr); |
|---|
| 1173 | | - |
|---|
| 1174 | | - return NULL; |
|---|
| 1175 | 1341 | } |
|---|
| 1176 | 1342 | |
|---|
| 1177 | 1343 | return NULL; |
|---|