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 <malloc.h> 11 #include <mapmem.h> 12 #include <errno.h> 13 #ifdef CONFIG_RKIMG_BOOTLOADER 14 #include <asm/arch/resource_img.h> 15 #endif 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000 20 #define ANDROID_ARG_FDT_FILENAME "rk-kernel.dtb" 21 22 static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; 23 static u32 android_kernel_comp_type = IH_COMP_NONE; 24 25 static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr) 26 { 27 /* 28 * All the Android tools that generate a boot.img use this 29 * address as the default. 30 * 31 * Even though it doesn't really make a lot of sense, and it 32 * might be valid on some platforms, we treat that adress as 33 * the default value for this field, and try to execute the 34 * kernel in place in such a case. 35 * 36 * Otherwise, we will return the actual value set by the user. 37 */ 38 if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR) 39 return (ulong)hdr + hdr->page_size; 40 41 #ifdef CONFIG_ARCH_ROCKCHIP 42 /* 43 * If kernel is compressed, kernel_addr is set as decompressed address 44 * after compressed being loaded to ram, so let's use it. 45 */ 46 if (android_kernel_comp_type != IH_COMP_NONE && 47 android_kernel_comp_type != IH_COMP_ZIMAGE) 48 return hdr->kernel_addr; 49 50 /* 51 * Compatble with rockchip legacy packing with kernel/ramdisk/second 52 * address base from 0x60000000(SDK versiont < 8.1), these are invalid 53 * address, so we calc it by real size. 54 */ 55 return (ulong)hdr + hdr->page_size; 56 #else 57 return hdr->kernel_addr; 58 #endif 59 60 } 61 62 void android_image_set_comp(struct andr_img_hdr *hdr, u32 comp) 63 { 64 android_kernel_comp_type = comp; 65 } 66 67 u32 android_image_get_comp(const struct andr_img_hdr *hdr) 68 { 69 return android_kernel_comp_type; 70 } 71 72 int android_image_parse_kernel_comp(const struct andr_img_hdr *hdr) 73 { 74 ulong kaddr = android_image_get_kernel_addr(hdr); 75 return bootm_parse_comp((const unsigned char *)kaddr); 76 } 77 78 /** 79 * android_image_get_kernel() - processes kernel part of Android boot images 80 * @hdr: Pointer to image header, which is at the start 81 * of the image. 82 * @verify: Checksum verification flag. Currently unimplemented. 83 * @os_data: Pointer to a ulong variable, will hold os data start 84 * address. 85 * @os_len: Pointer to a ulong variable, will hold os data length. 86 * 87 * This function returns the os image's start address and length. Also, 88 * it appends the kernel command line to the bootargs env variable. 89 * 90 * Return: Zero, os start address and length on success, 91 * otherwise on failure. 92 */ 93 int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, 94 ulong *os_data, ulong *os_len) 95 { 96 u32 kernel_addr = android_image_get_kernel_addr(hdr); 97 98 /* 99 * Not all Android tools use the id field for signing the image with 100 * sha1 (or anything) so we don't check it. It is not obvious that the 101 * string is null terminated so we take care of this. 102 */ 103 strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE); 104 andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0'; 105 if (strlen(andr_tmp_str)) 106 printf("Android's image name: %s\n", andr_tmp_str); 107 108 printf("Kernel load addr 0x%08x size %u KiB\n", 109 kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024)); 110 111 int len = 0; 112 if (*hdr->cmdline) { 113 debug("Kernel command line: %s\n", hdr->cmdline); 114 len += strlen(hdr->cmdline); 115 } 116 117 char *bootargs = env_get("bootargs"); 118 if (bootargs) 119 len += strlen(bootargs); 120 121 char *newbootargs = malloc(len + 2); 122 if (!newbootargs) { 123 puts("Error: malloc in android_image_get_kernel failed!\n"); 124 return -ENOMEM; 125 } 126 *newbootargs = '\0'; 127 128 if (bootargs) { 129 strcpy(newbootargs, bootargs); 130 strcat(newbootargs, " "); 131 } 132 if (*hdr->cmdline) 133 strcat(newbootargs, hdr->cmdline); 134 135 env_set("bootargs", newbootargs); 136 137 if (os_data) { 138 *os_data = (ulong)hdr; 139 *os_data += hdr->page_size; 140 } 141 if (os_len) 142 *os_len = hdr->kernel_size; 143 return 0; 144 } 145 146 int android_image_check_header(const struct andr_img_hdr *hdr) 147 { 148 return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE); 149 } 150 151 ulong android_image_get_end(const struct andr_img_hdr *hdr) 152 { 153 ulong end; 154 /* 155 * The header takes a full page, the remaining components are aligned 156 * on page boundary 157 */ 158 end = (ulong)hdr; 159 end += hdr->page_size; 160 end += ALIGN(hdr->kernel_size, hdr->page_size); 161 end += ALIGN(hdr->ramdisk_size, hdr->page_size); 162 end += ALIGN(hdr->second_size, hdr->page_size); 163 164 if (hdr->header_version >= 1) 165 end += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); 166 167 return end; 168 } 169 170 u32 android_image_get_ksize(const struct andr_img_hdr *hdr) 171 { 172 return hdr->kernel_size; 173 } 174 175 void android_image_set_kload(struct andr_img_hdr *hdr, u32 load_address) 176 { 177 hdr->kernel_addr = load_address; 178 } 179 180 ulong android_image_get_kload(const struct andr_img_hdr *hdr) 181 { 182 return android_image_get_kernel_addr(hdr); 183 } 184 185 int android_image_get_ramdisk(const struct andr_img_hdr *hdr, 186 ulong *rd_data, ulong *rd_len) 187 { 188 if (!hdr->ramdisk_size) { 189 *rd_data = *rd_len = 0; 190 return -1; 191 } 192 193 *rd_data = (unsigned long)hdr; 194 *rd_data += hdr->page_size; 195 *rd_data += ALIGN(hdr->kernel_size, hdr->page_size); 196 *rd_len = hdr->ramdisk_size; 197 198 printf("RAM disk load addr 0x%08lx size %u KiB\n", 199 *rd_data, DIV_ROUND_UP(hdr->ramdisk_size, 1024)); 200 201 return 0; 202 } 203 204 int android_image_get_fdt(const struct andr_img_hdr *hdr, 205 ulong *rd_data) 206 { 207 if (!hdr->second_size) { 208 *rd_data = 0; 209 return -1; 210 } 211 /* 212 * If kernel dtb is enabled, we have read kernel dtb in 213 * init_kernel_dtb() -> rockchip_read_dtb_file() and may have been 214 * done(optional) selection: 215 * 216 * 1. apply fdt overlay; 217 * 2. select fdt by adc or gpio; 218 * 219 * After that, we didn't update dtb at all untill run here, it's fine to 220 * pass current fdt to kernel. 221 */ 222 #if defined(CONFIG_USING_KERNEL_DTB) 223 *rd_data = (ulong)gd->fdt_blob; 224 225 /* 226 * If kernel dtb is disabled and support rockchip image, we need to call 227 * rockchip_read_dtb_file() to get dtb with some optional selection. 228 */ 229 #elif defined(CONFIG_RKIMG_BOOTLOADER) 230 ulong fdt_addr = 0; 231 int ret; 232 233 /* Get resource addr and fdt addr */ 234 fdt_addr = env_get_ulong("fdt_addr_r", 16, 0); 235 if (!fdt_addr) { 236 printf("No Found FDT Load Address.\n"); 237 return -1; 238 } 239 240 ret = rockchip_read_dtb_file((void *)fdt_addr); 241 if (ret < 0) { 242 printf("%s: failed to read dtb file, ret=%d\n", __func__, ret); 243 return ret; 244 } 245 246 *rd_data = fdt_addr; 247 248 /* 249 * If kernel dtb is disabled and not support rockchip image, 250 * get dtb from second position. 251 */ 252 #else 253 *rd_data = (unsigned long)hdr; 254 *rd_data += hdr->page_size; 255 *rd_data += ALIGN(hdr->kernel_size, hdr->page_size); 256 *rd_data += ALIGN(hdr->ramdisk_size, hdr->page_size); 257 258 printf("FDT load addr 0x%08x size %u KiB\n", 259 hdr->second_addr, DIV_ROUND_UP(hdr->second_size, 1024)); 260 #endif 261 262 return 0; 263 } 264 265 long android_image_load(struct blk_desc *dev_desc, 266 const disk_partition_t *part_info, 267 unsigned long load_address, 268 unsigned long max_size) { 269 void *buf; 270 long blk_cnt = 0; 271 long blk_read = 0; 272 u32 comp; 273 u32 kload_addr; 274 u32 blkcnt; 275 struct andr_img_hdr *hdr; 276 277 if (max_size < part_info->blksz) 278 return -1; 279 280 /* 281 * Read the Android boot.img header and a few parts of 282 * the head of kernel image(2 blocks maybe enough). 283 */ 284 blkcnt = DIV_ROUND_UP(sizeof(*hdr), 512) + 2; 285 hdr = memalign(ARCH_DMA_MINALIGN, blkcnt * 512); 286 if (!hdr) { 287 printf("%s: no memory\n", __func__); 288 return -1; 289 } 290 291 if (blk_dread(dev_desc, part_info->start, blkcnt, hdr) != blkcnt) 292 blk_read = -1; 293 294 if (!blk_read && android_image_check_header(hdr) != 0) { 295 printf("** Invalid Android Image header **\n"); 296 blk_read = -1; 297 } 298 299 /* page_size for image header */ 300 load_address -= hdr->page_size; 301 302 /* We don't know the size of the Android image before reading the header 303 * so we don't limit the size of the mapped memory. 304 */ 305 buf = map_sysmem(load_address, 0 /* size */); 306 if (!blk_read) { 307 blk_cnt = (android_image_get_end(hdr) - (ulong)hdr + 308 part_info->blksz - 1) / part_info->blksz; 309 comp = android_image_parse_kernel_comp(hdr); 310 /* 311 * We should load a compressed kernel Image 312 * to high memory 313 */ 314 if (comp != IH_COMP_NONE) { 315 load_address += android_image_get_ksize(hdr) * 3; 316 load_address = env_get_ulong("kernel_addr_c", 16, load_address); 317 unmap_sysmem(buf); 318 buf = map_sysmem(load_address, 0 /* size */); 319 } 320 321 if (blk_cnt * part_info->blksz > max_size) { 322 debug("Android Image too big (%lu bytes, max %lu)\n", 323 android_image_get_end(hdr) - (ulong)hdr, 324 max_size); 325 blk_read = -1; 326 } else { 327 debug("Loading Android Image (%lu blocks) to 0x%lx... ", 328 blk_cnt, load_address); 329 blk_read = blk_dread(dev_desc, part_info->start, 330 blk_cnt, buf); 331 } 332 333 /* 334 * zImage is not need to decompress 335 * kernel will handle decompress itself 336 */ 337 if (comp != IH_COMP_NONE && comp != IH_COMP_ZIMAGE) { 338 kload_addr = env_get_ulong("kernel_addr_r", 16, 0x02080000); 339 android_image_set_kload(buf, kload_addr); 340 android_image_set_comp(buf, comp); 341 } else { 342 android_image_set_comp(buf, IH_COMP_NONE); 343 } 344 345 } 346 347 free(hdr); 348 unmap_sysmem(buf); 349 350 debug("%lu blocks read: %s\n", 351 blk_read, (blk_read == blk_cnt) ? "OK" : "ERROR"); 352 if (blk_read != blk_cnt) 353 return -1; 354 355 return load_address; 356 } 357 358 #if !defined(CONFIG_SPL_BUILD) 359 /** 360 * android_print_contents - prints out the contents of the Android format image 361 * @hdr: pointer to the Android format image header 362 * 363 * android_print_contents() formats a multi line Android image contents 364 * description. 365 * The routine prints out Android image properties 366 * 367 * returns: 368 * no returned results 369 */ 370 void android_print_contents(const struct andr_img_hdr *hdr) 371 { 372 const char * const p = IMAGE_INDENT_STRING; 373 /* os_version = ver << 11 | lvl */ 374 u32 os_ver = hdr->os_version >> 11; 375 u32 os_lvl = hdr->os_version & ((1U << 11) - 1); 376 u32 header_version = hdr->header_version; 377 378 printf("%skernel size: %x\n", p, hdr->kernel_size); 379 printf("%skernel address: %x\n", p, hdr->kernel_addr); 380 printf("%sramdisk size: %x\n", p, hdr->ramdisk_size); 381 printf("%sramdisk addrress: %x\n", p, hdr->ramdisk_addr); 382 printf("%ssecond size: %x\n", p, hdr->second_size); 383 printf("%ssecond address: %x\n", p, hdr->second_addr); 384 printf("%stags address: %x\n", p, hdr->tags_addr); 385 printf("%spage size: %x\n", p, hdr->page_size); 386 printf("%sheader_version: %x\n", p, header_version); 387 /* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C) 388 * lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M) */ 389 printf("%sos_version: %x (ver: %u.%u.%u, level: %u.%u)\n", 390 p, hdr->os_version, 391 (os_ver >> 7) & 0x7F, (os_ver >> 14) & 0x7F, os_ver & 0x7F, 392 (os_lvl >> 4) + 2000, os_lvl & 0x0F); 393 printf("%sname: %s\n", p, hdr->name); 394 printf("%scmdline: %s\n", p, hdr->cmdline); 395 396 if (header_version >= 1) { 397 printf("%srecovery dtbo size: %x\n", p, hdr->recovery_dtbo_size); 398 printf("%srecovery dtbo offset: %llx\n", p, hdr->recovery_dtbo_offset); 399 printf("%sheader size: %x\n", p, hdr->header_size); 400 } 401 } 402 #endif 403