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