1 /* 2 * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <image.h> 9 #include <android_image.h> 10 #include <android_bootloader.h> 11 #include <malloc.h> 12 #include <mapmem.h> 13 #include <errno.h> 14 #include <boot_rkimg.h> 15 #include <sysmem.h> 16 #ifdef CONFIG_RKIMG_BOOTLOADER 17 #include <asm/arch/resource_img.h> 18 #endif 19 #ifdef CONFIG_RK_AVB_LIBAVB_USER 20 #include <android_avb/avb_slot_verify.h> 21 #include <android_avb/avb_ops_user.h> 22 #include <android_avb/rk_avb_ops_user.h> 23 #endif 24 #include <optee_include/OpteeClientInterface.h> 25 26 DECLARE_GLOBAL_DATA_PTR; 27 28 #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000 29 #define ANDROID_ARG_FDT_FILENAME "rk-kernel.dtb" 30 31 static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; 32 static u32 android_kernel_comp_type = IH_COMP_NONE; 33 34 static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr) 35 { 36 /* 37 * All the Android tools that generate a boot.img use this 38 * address as the default. 39 * 40 * Even though it doesn't really make a lot of sense, and it 41 * might be valid on some platforms, we treat that address as 42 * the default value for this field, and try to execute the 43 * kernel in place in such a case. 44 * 45 * Otherwise, we will return the actual value set by the user. 46 */ 47 if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR) 48 return (ulong)hdr + hdr->page_size; 49 50 #ifdef CONFIG_ARCH_ROCKCHIP 51 /* 52 * If kernel is compressed, kernel_addr is set as decompressed address 53 * after compressed being loaded to ram, so let's use it. 54 */ 55 if (android_kernel_comp_type != IH_COMP_NONE && 56 android_kernel_comp_type != IH_COMP_ZIMAGE) 57 return hdr->kernel_addr; 58 59 /* 60 * Compatble with rockchip legacy packing with kernel/ramdisk/second 61 * address base from 0x60000000(SDK versiont < 8.1), these are invalid 62 * address, so we calc it by real size. 63 */ 64 return (ulong)hdr + hdr->page_size; 65 #else 66 return hdr->kernel_addr; 67 #endif 68 69 } 70 71 void android_image_set_comp(struct andr_img_hdr *hdr, u32 comp) 72 { 73 android_kernel_comp_type = comp; 74 } 75 76 u32 android_image_get_comp(const struct andr_img_hdr *hdr) 77 { 78 return android_kernel_comp_type; 79 } 80 81 int android_image_parse_kernel_comp(const struct andr_img_hdr *hdr) 82 { 83 ulong kaddr = android_image_get_kernel_addr(hdr); 84 return bootm_parse_comp((const unsigned char *)kaddr); 85 } 86 87 /** 88 * android_image_get_kernel() - processes kernel part of Android boot images 89 * @hdr: Pointer to image header, which is at the start 90 * of the image. 91 * @verify: Checksum verification flag. Currently unimplemented. 92 * @os_data: Pointer to a ulong variable, will hold os data start 93 * address. 94 * @os_len: Pointer to a ulong variable, will hold os data length. 95 * 96 * This function returns the os image's start address and length. Also, 97 * it appends the kernel command line to the bootargs env variable. 98 * 99 * Return: Zero, os start address and length on success, 100 * otherwise on failure. 101 */ 102 int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, 103 ulong *os_data, ulong *os_len) 104 { 105 u32 kernel_addr = android_image_get_kernel_addr(hdr); 106 107 /* 108 * Not all Android tools use the id field for signing the image with 109 * sha1 (or anything) so we don't check it. It is not obvious that the 110 * string is null terminated so we take care of this. 111 */ 112 strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE); 113 andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0'; 114 if (strlen(andr_tmp_str)) 115 printf("Android's image name: %s\n", andr_tmp_str); 116 117 printf("Kernel load addr 0x%08x size %u KiB\n", 118 kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024)); 119 120 int len = 0; 121 if (*hdr->cmdline) { 122 debug("Kernel command line: %s\n", hdr->cmdline); 123 len += strlen(hdr->cmdline); 124 } 125 126 char *bootargs = env_get("bootargs"); 127 if (bootargs) 128 len += strlen(bootargs); 129 130 char *newbootargs = malloc(len + 2); 131 if (!newbootargs) { 132 puts("Error: malloc in android_image_get_kernel failed!\n"); 133 return -ENOMEM; 134 } 135 *newbootargs = '\0'; 136 137 if (bootargs) { 138 strcpy(newbootargs, bootargs); 139 strcat(newbootargs, " "); 140 } 141 if (*hdr->cmdline) 142 strcat(newbootargs, hdr->cmdline); 143 144 env_set("bootargs", newbootargs); 145 146 if (os_data) { 147 *os_data = (ulong)hdr; 148 *os_data += hdr->page_size; 149 } 150 if (os_len) 151 *os_len = hdr->kernel_size; 152 return 0; 153 } 154 155 int android_image_check_header(const struct andr_img_hdr *hdr) 156 { 157 return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE); 158 } 159 160 ulong android_image_get_end(const struct andr_img_hdr *hdr) 161 { 162 ulong end; 163 /* 164 * The header takes a full page, the remaining components are aligned 165 * on page boundary 166 */ 167 end = (ulong)hdr; 168 end += hdr->page_size; 169 end += ALIGN(hdr->kernel_size, hdr->page_size); 170 end += ALIGN(hdr->ramdisk_size, hdr->page_size); 171 end += ALIGN(hdr->second_size, hdr->page_size); 172 173 if (hdr->header_version >= 1) 174 end += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); 175 176 return end; 177 } 178 179 u32 android_image_get_ksize(const struct andr_img_hdr *hdr) 180 { 181 return hdr->kernel_size; 182 } 183 184 void android_image_set_kload(struct andr_img_hdr *hdr, u32 load_address) 185 { 186 hdr->kernel_addr = load_address; 187 } 188 189 ulong android_image_get_kload(const struct andr_img_hdr *hdr) 190 { 191 return android_image_get_kernel_addr(hdr); 192 } 193 194 int android_image_get_ramdisk(const struct andr_img_hdr *hdr, 195 ulong *rd_data, ulong *rd_len) 196 { 197 if (!hdr->ramdisk_size) { 198 *rd_data = *rd_len = 0; 199 return -1; 200 } 201 202 /* We have load ramdisk at "ramdisk_addr_r" */ 203 #ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE 204 ulong ramdisk_addr_r; 205 206 ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0); 207 if (!ramdisk_addr_r) { 208 printf("No Found Ramdisk Load Address.\n"); 209 return -1; 210 } 211 212 *rd_data = ramdisk_addr_r; 213 #else 214 *rd_data = (unsigned long)hdr; 215 *rd_data += hdr->page_size; 216 *rd_data += ALIGN(hdr->kernel_size, hdr->page_size); 217 #endif 218 219 *rd_len = hdr->ramdisk_size; 220 221 printf("RAM disk load addr 0x%08lx size %u KiB\n", 222 *rd_data, DIV_ROUND_UP(hdr->ramdisk_size, 1024)); 223 224 return 0; 225 } 226 227 int android_image_get_fdt(const struct andr_img_hdr *hdr, 228 ulong *rd_data) 229 { 230 if (!hdr->second_size) { 231 *rd_data = 0; 232 return -1; 233 } 234 235 /* We have load fdt at "fdt_addr_r" */ 236 #if defined(CONFIG_USING_KERNEL_DTB) || \ 237 defined(CONFIG_ANDROID_BOOT_IMAGE_SEPARATE) 238 ulong fdt_addr_r; 239 240 fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0); 241 if (!fdt_addr_r) { 242 printf("No Found FDT Load Address.\n"); 243 return -1; 244 } 245 246 *rd_data = fdt_addr_r; 247 #else 248 *rd_data = (unsigned long)hdr; 249 *rd_data += hdr->page_size; 250 *rd_data += ALIGN(hdr->kernel_size, hdr->page_size); 251 *rd_data += ALIGN(hdr->ramdisk_size, hdr->page_size); 252 #endif 253 254 debug("FDT load addr 0x%08x size %u KiB\n", 255 hdr->second_addr, DIV_ROUND_UP(hdr->second_size, 1024)); 256 257 return 0; 258 } 259 260 #ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE 261 int android_image_load_separate(struct andr_img_hdr *hdr, 262 const disk_partition_t *part, 263 void *load_address, void *ram_src) 264 { 265 struct blk_desc *dev_desc = rockchip_get_bootdev(); 266 ulong fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0); 267 char *fdt_high = env_get("fdt_high"); 268 char *ramdisk_high = env_get("initrd_high"); 269 ulong blk_start, blk_cnt, size; 270 int ret, blk_read = 0; 271 ulong start; 272 273 if (android_image_check_header(hdr)) { 274 printf("Bad android image header\n"); 275 return -EINVAL; 276 } 277 278 if (hdr->kernel_size) { 279 size = hdr->kernel_size + hdr->page_size; 280 blk_cnt = DIV_ROUND_UP(size, dev_desc->blksz); 281 if (!sysmem_alloc_base(MEMBLK_ID_KERNEL, 282 (phys_addr_t)load_address, 283 blk_cnt * dev_desc->blksz)) 284 return -ENXIO; 285 286 if (ram_src) { 287 start = (ulong)ram_src; 288 memcpy((char *)load_address, (char *)start, size); 289 } else { 290 blk_start = part->start; 291 ret = blk_dread(dev_desc, blk_start, 292 blk_cnt, load_address); 293 if (ret != blk_cnt) { 294 printf("%s: read kernel failed, ret=%d\n", 295 __func__, ret); 296 return -1; 297 } 298 blk_read += ret; 299 } 300 } 301 302 if (hdr->ramdisk_size) { 303 ulong ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0); 304 305 size = hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size); 306 blk_cnt = DIV_ROUND_UP(hdr->ramdisk_size, dev_desc->blksz); 307 if (!sysmem_alloc_base(MEMBLK_ID_RAMDISK, 308 ramdisk_addr_r, 309 blk_cnt * dev_desc->blksz)) 310 return -ENXIO; 311 if (ram_src) { 312 start = (unsigned long)ram_src; 313 start += hdr->page_size; 314 start += ALIGN(hdr->kernel_size, hdr->page_size); 315 memcpy((char *)ramdisk_addr_r, 316 (char *)start, hdr->ramdisk_size); 317 } else { 318 blk_start = part->start + 319 DIV_ROUND_UP(size, dev_desc->blksz); 320 ret = blk_dread(dev_desc, blk_start, 321 blk_cnt, (void *)ramdisk_addr_r); 322 if (ret != blk_cnt) { 323 printf("%s: read ramdisk failed, ret=%d\n", 324 __func__, ret); 325 return -1; 326 } 327 blk_read += ret; 328 } 329 } 330 331 if ((gd->fdt_blob != (void *)fdt_addr_r) && hdr->second_size) { 332 #ifdef CONFIG_RKIMG_BOOTLOADER 333 /* Rockchip AOSP, resource.img is in second position */ 334 ulong fdt_size; 335 336 fdt_size = rockchip_read_dtb_file((void *)fdt_addr_r); 337 if (fdt_size < 0) { 338 printf("%s: read fdt failed\n", __func__); 339 return ret; 340 } 341 342 blk_read += DIV_ROUND_UP(fdt_size, dev_desc->blksz); 343 #else 344 /* Standard AOSP, dtb is in second position */ 345 ulong blk_start, blk_cnt; 346 347 size = hdr->page_size + 348 ALIGN(hdr->kernel_size, hdr->page_size) + 349 ALIGN(hdr->ramdisk_size, hdr->page_size); 350 blk_cnt = DIV_ROUND_UP(hdr->second_size, dev_desc->blksz); 351 if (!sysmem_alloc_base(MEMBLK_ID_FDT_AOSP, 352 fdt_addr_r, 353 blk_cnt * dev_desc->blksz + 354 CONFIG_SYS_FDT_PAD)) 355 return -ENXIO; 356 357 if (ram_src) { 358 start = (unsigned long)ram_src; 359 start += hdr->page_size; 360 start += ALIGN(hdr->kernel_size, hdr->page_size); 361 start += ALIGN(hdr->ramdisk_size, hdr->page_size); 362 memcpy((char *)fdt_addr_r, 363 (char *)start, hdr->second_size); 364 } else { 365 blk_start = part->start + 366 DIV_ROUND_UP(size, dev_desc->blksz); 367 ret = blk_dread(dev_desc, blk_start, blk_cnt, 368 (void *)fdt_addr_r); 369 if (ret != blk_cnt) { 370 printf("%s: read dtb failed, ret=%d\n", 371 __func__, ret); 372 return -1; 373 } 374 375 blk_read += blk_cnt; 376 } 377 #endif /* CONFIG_RKIMG_BOOTLOADER */ 378 } 379 380 if (blk_read > 0 || ram_src) { 381 if (!fdt_high) { 382 env_set_hex("fdt_high", -1UL); 383 printf("Fdt "); 384 } 385 if (!ramdisk_high) { 386 env_set_hex("initrd_high", -1UL); 387 printf("Ramdisk "); 388 } 389 if (!fdt_high || !ramdisk_high) 390 printf("skip relocation\n"); 391 } 392 393 return blk_read; 394 } 395 #endif /* CONFIG_ANDROID_BOOT_IMAGE_SEPARATE */ 396 397 long android_image_load(struct blk_desc *dev_desc, 398 const disk_partition_t *part_info, 399 unsigned long load_address, 400 unsigned long max_size) { 401 void *buf; 402 long blk_cnt = 0; 403 long blk_read = 0; 404 u32 comp; 405 u32 kload_addr; 406 u32 blkcnt; 407 struct andr_img_hdr *hdr; 408 409 if (max_size < part_info->blksz) 410 return -1; 411 412 /* 413 * Read the Android boot.img header and a few parts of 414 * the head of kernel image(2 blocks maybe enough). 415 */ 416 blkcnt = DIV_ROUND_UP(sizeof(*hdr), 512) + 2; 417 hdr = memalign(ARCH_DMA_MINALIGN, blkcnt * 512); 418 if (!hdr) { 419 printf("%s: no memory\n", __func__); 420 return -1; 421 } 422 423 if (blk_dread(dev_desc, part_info->start, blkcnt, hdr) != blkcnt) 424 blk_read = -1; 425 426 if (!blk_read && android_image_check_header(hdr) != 0) { 427 printf("** Invalid Android Image header **\n"); 428 blk_read = -1; 429 } 430 431 /* page_size for image header */ 432 load_address -= hdr->page_size; 433 434 /* We don't know the size of the Android image before reading the header 435 * so we don't limit the size of the mapped memory. 436 */ 437 buf = map_sysmem(load_address, 0 /* size */); 438 if (!blk_read) { 439 blk_cnt = (android_image_get_end(hdr) - (ulong)hdr + 440 part_info->blksz - 1) / part_info->blksz; 441 comp = android_image_parse_kernel_comp(hdr); 442 /* 443 * We should load compressed kernel Image to high memory at 444 * address "kernel_addr_c". 445 */ 446 if (comp != IH_COMP_NONE) { 447 ulong kernel_addr_c; 448 449 env_set_ulong("os_comp", comp); 450 kernel_addr_c = env_get_ulong("kernel_addr_c", 16, 0); 451 if (kernel_addr_c) { 452 load_address = kernel_addr_c - hdr->page_size; 453 unmap_sysmem(buf); 454 buf = map_sysmem(load_address, 0 /* size */); 455 } 456 #ifdef CONFIG_ARM64 457 else { 458 printf("Warn: \"kernel_addr_c\" is not defined " 459 "for compressed kernel Image!\n"); 460 load_address += android_image_get_ksize(hdr) * 3; 461 load_address = ALIGN(load_address, ARCH_DMA_MINALIGN); 462 env_set_ulong("kernel_addr_c", load_address); 463 464 load_address -= hdr->page_size; 465 unmap_sysmem(buf); 466 buf = map_sysmem(load_address, 0 /* size */); 467 } 468 #endif 469 } 470 471 if (blk_cnt * part_info->blksz > max_size) { 472 debug("Android Image too big (%lu bytes, max %lu)\n", 473 android_image_get_end(hdr) - (ulong)hdr, 474 max_size); 475 blk_read = -1; 476 } else { 477 debug("Loading Android Image (%lu blocks) to 0x%lx... ", 478 blk_cnt, load_address); 479 480 #ifdef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE 481 blk_read = 482 android_image_load_separate(hdr, part_info, buf, NULL); 483 #else 484 if (!sysmem_alloc_base(MEMBLK_ID_ANDROID, 485 (phys_addr_t)buf, 486 blk_cnt * part_info->blksz)) 487 return -ENXIO; 488 489 blk_read = blk_dread(dev_desc, part_info->start, 490 blk_cnt, buf); 491 #endif 492 } 493 494 /* 495 * zImage is not need to decompress 496 * kernel will handle decompress itself 497 */ 498 if (comp != IH_COMP_NONE && comp != IH_COMP_ZIMAGE) { 499 kload_addr = env_get_ulong("kernel_addr_r", 16, 0x02080000); 500 android_image_set_kload(buf, kload_addr); 501 android_image_set_comp(buf, comp); 502 } else { 503 android_image_set_comp(buf, IH_COMP_NONE); 504 } 505 506 } 507 508 free(hdr); 509 unmap_sysmem(buf); 510 511 #ifndef CONFIG_ANDROID_BOOT_IMAGE_SEPARATE 512 debug("%lu blocks read: %s\n", 513 blk_read, (blk_read == blk_cnt) ? "OK" : "ERROR"); 514 if (blk_read != blk_cnt) 515 return -1; 516 #else 517 debug("%lu blocks read\n", blk_read); 518 if (blk_read < 0) 519 return blk_read; 520 #endif 521 522 return load_address; 523 } 524 525 #if !defined(CONFIG_SPL_BUILD) 526 /** 527 * android_print_contents - prints out the contents of the Android format image 528 * @hdr: pointer to the Android format image header 529 * 530 * android_print_contents() formats a multi line Android image contents 531 * description. 532 * The routine prints out Android image properties 533 * 534 * returns: 535 * no returned results 536 */ 537 void android_print_contents(const struct andr_img_hdr *hdr) 538 { 539 const char * const p = IMAGE_INDENT_STRING; 540 /* os_version = ver << 11 | lvl */ 541 u32 os_ver = hdr->os_version >> 11; 542 u32 os_lvl = hdr->os_version & ((1U << 11) - 1); 543 u32 header_version = hdr->header_version; 544 545 printf("%skernel size: %x\n", p, hdr->kernel_size); 546 printf("%skernel address: %x\n", p, hdr->kernel_addr); 547 printf("%sramdisk size: %x\n", p, hdr->ramdisk_size); 548 printf("%sramdisk addrress: %x\n", p, hdr->ramdisk_addr); 549 printf("%ssecond size: %x\n", p, hdr->second_size); 550 printf("%ssecond address: %x\n", p, hdr->second_addr); 551 printf("%stags address: %x\n", p, hdr->tags_addr); 552 printf("%spage size: %x\n", p, hdr->page_size); 553 printf("%sheader_version: %x\n", p, header_version); 554 /* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C) 555 * lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M) */ 556 printf("%sos_version: %x (ver: %u.%u.%u, level: %u.%u)\n", 557 p, hdr->os_version, 558 (os_ver >> 7) & 0x7F, (os_ver >> 14) & 0x7F, os_ver & 0x7F, 559 (os_lvl >> 4) + 2000, os_lvl & 0x0F); 560 printf("%sname: %s\n", p, hdr->name); 561 printf("%scmdline: %s\n", p, hdr->cmdline); 562 563 if (header_version >= 1) { 564 printf("%srecovery dtbo size: %x\n", p, hdr->recovery_dtbo_size); 565 printf("%srecovery dtbo offset: %llx\n", p, hdr->recovery_dtbo_offset); 566 printf("%sheader size: %x\n", p, hdr->header_size); 567 } 568 } 569 #endif 570