xref: /rk3399_rockchip-uboot/common/image-android.c (revision 11f9ae3a9f57d1ecc3b8cc16cfbf5e4e599e5330)
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_ab.h>
10 #include <android_bootloader.h>
11 #include <android_image.h>
12 #include <malloc.h>
13 #include <mapmem.h>
14 #include <errno.h>
15 #include <boot_rkimg.h>
16 #include <crypto.h>
17 #include <sysmem.h>
18 #include <u-boot/sha1.h>
19 #ifdef CONFIG_RKIMG_BOOTLOADER
20 #include <asm/arch/resource_img.h>
21 #endif
22 #ifdef CONFIG_RK_AVB_LIBAVB_USER
23 #include <android_avb/avb_slot_verify.h>
24 #include <android_avb/avb_ops_user.h>
25 #include <android_avb/rk_avb_ops_user.h>
26 #endif
27 #include <optee_include/OpteeClientInterface.h>
28 
29 DECLARE_GLOBAL_DATA_PTR;
30 
31 #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR	0x10008000
32 #define ANDROID_PARTITION_VENDOR_BOOT		"vendor_boot"
33 #define ANDROID_PARTITION_INIT_BOOT		"init_boot"
34 
35 #define BLK_CNT(_num_bytes, _block_size)	\
36 		((_num_bytes + _block_size - 1) / _block_size)
37 
38 static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
39 static u32 android_kernel_comp_type = IH_COMP_NONE;
40 
41 static int android_version_init(void)
42 {
43 	struct andr_img_hdr *hdr = NULL;
44 	struct blk_desc *desc;
45 	const char *part_name = PART_BOOT;
46 	disk_partition_t part;
47 	int os_version;
48 
49 	desc = rockchip_get_bootdev();
50 	if (!desc) {
51 		printf("No bootdev\n");
52 		return -1;
53 	}
54 
55 #ifdef CONFIG_ANDROID_AB
56 	part_name = ab_can_find_recovery_part() ? PART_RECOVERY : PART_BOOT;
57 #endif
58 	if (part_get_info_by_name(desc, part_name, &part) < 0)
59 		return -1;
60 
61 	hdr = populate_andr_img_hdr(desc, &part);
62 	if (!hdr)
63 		return -1;
64 
65 	os_version = hdr->os_version;
66 	if (os_version)
67 		printf("Android %u.%u, Build %u.%u, v%d\n",
68 		       (os_version >> 25) & 0x7f, (os_version >> 18) & 0x7F,
69 		       ((os_version >> 4) & 0x7f) + 2000, os_version & 0x0F,
70 		       hdr->header_version);
71 	free(hdr);
72 
73 	return (os_version >> 25) & 0x7f;
74 }
75 
76 u32 android_bcb_msg_sector_offset(void)
77 {
78 	static int android_version = -1;	/* static */
79 
80 	/*
81 	 * get android os version:
82 	 *
83 	 * There are two types of misc.img:
84 	 *	Rockchip platforms defines BCB message at the 16KB offset of
85 	 *	misc.img except for the Android version >= 10. Because Google
86 	 *	defines it at 0x00 offset, and from Android-10 it becoms mandary
87 	 *	on Google VTS.
88 	 *
89 	 * So we must get android 'os_version' to identify which type we
90 	 * are using, then we could able to use rockchip_get_boot_mode()
91 	 * which reads BCB from misc.img.
92 	 */
93 #ifdef CONFIG_RKIMG_BOOTLOADER
94 	if (android_version < 0)
95 		android_version = android_version_init();
96 
97 	return (android_version >= 10) ? 0x00 : 0x20;
98 #else
99 	return 0x00;
100 #endif
101 }
102 
103 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
104 int android_image_init_resource(struct blk_desc *desc,
105 				disk_partition_t *out_part,
106 				ulong *out_blk_offset)
107 {
108 	struct andr_img_hdr *hdr = NULL;
109 	const char *part_name = ANDROID_PARTITION_BOOT;
110 	disk_partition_t part;
111 	ulong offset;
112 	int ret = 0;
113 
114 	if (!desc)
115 		return -ENODEV;
116 
117 #ifndef CONFIG_ANDROID_AB
118 	if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY)
119 		part_name = ANDROID_PARTITION_RECOVERY;
120 #endif
121 	if (part_get_info_by_name(desc, part_name, &part) < 0)
122 		return -ENOENT;
123 
124 	hdr = populate_andr_img_hdr(desc, &part);
125 	if (!hdr)
126 		return -EINVAL;
127 
128 	if (hdr->header_version >= 2 && hdr->dtb_size)
129 		env_update("bootargs", "androidboot.dtb_idx=0");
130 
131 	if (hdr->header_version <= 2) {
132 		offset = hdr->page_size +
133 			ALIGN(hdr->kernel_size, hdr->page_size) +
134 			ALIGN(hdr->ramdisk_size, hdr->page_size);
135 		*out_part = part;
136 		*out_blk_offset = DIV_ROUND_UP(offset, desc->blksz);
137 	} else {
138 		ret = -EINVAL;
139 	}
140 	free(hdr);
141 
142 	return ret;
143 }
144 #endif
145 
146 static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr)
147 {
148 	/*
149 	 * All the Android tools that generate a boot.img use this
150 	 * address as the default.
151 	 *
152 	 * Even though it doesn't really make a lot of sense, and it
153 	 * might be valid on some platforms, we treat that address as
154 	 * the default value for this field, and try to execute the
155 	 * kernel in place in such a case.
156 	 *
157 	 * Otherwise, we will return the actual value set by the user.
158 	 */
159 	if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR)
160 		return (ulong)hdr + hdr->page_size;
161 
162 #ifdef CONFIG_ARCH_ROCKCHIP
163 	/*
164 	 * If kernel is compressed, kernel_addr is set as decompressed address
165 	 * after compressed being loaded to ram, so let's use it.
166 	 */
167 	if (android_kernel_comp_type != IH_COMP_NONE &&
168 	    android_kernel_comp_type != IH_COMP_ZIMAGE)
169 		return hdr->kernel_addr;
170 
171 	/*
172 	 * Compatble with rockchip legacy packing with kernel/ramdisk/second
173 	 * address base from 0x60000000(SDK versiont < 8.1), these are invalid
174 	 * address, so we calc it by real size.
175 	 */
176 	return (ulong)hdr + hdr->page_size;
177 #else
178 	return hdr->kernel_addr;
179 #endif
180 
181 }
182 
183 void android_image_set_comp(struct andr_img_hdr *hdr, u32 comp)
184 {
185 	android_kernel_comp_type = comp;
186 }
187 
188 u32 android_image_get_comp(const struct andr_img_hdr *hdr)
189 {
190 	return android_kernel_comp_type;
191 }
192 
193 int android_image_parse_kernel_comp(const struct andr_img_hdr *hdr)
194 {
195 	ulong kaddr = android_image_get_kernel_addr(hdr);
196 	return bootm_parse_comp((const unsigned char *)kaddr);
197 }
198 
199 /**
200  * android_image_get_kernel() - processes kernel part of Android boot images
201  * @hdr:	Pointer to image header, which is at the start
202  *			of the image.
203  * @verify:	Checksum verification flag. Currently unimplemented.
204  * @os_data:	Pointer to a ulong variable, will hold os data start
205  *			address.
206  * @os_len:	Pointer to a ulong variable, will hold os data length.
207  *
208  * This function returns the os image's start address and length. Also,
209  * it appends the kernel command line to the bootargs env variable.
210  *
211  * Return: Zero, os start address and length on success,
212  *		otherwise on failure.
213  */
214 int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
215 			     ulong *os_data, ulong *os_len)
216 {
217 	u32 kernel_addr = android_image_get_kernel_addr(hdr);
218 	const char *cmdline = hdr->header_version < 3 ?
219 			      hdr->cmdline : hdr->total_cmdline;
220 	/*
221 	 * Not all Android tools use the id field for signing the image with
222 	 * sha1 (or anything) so we don't check it. It is not obvious that the
223 	 * string is null terminated so we take care of this.
224 	 */
225 	strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE);
226 	andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0';
227 	if (strlen(andr_tmp_str))
228 		printf("Android's image name: %s\n", andr_tmp_str);
229 
230 	printf("Kernel: 0x%08x - 0x%08x (%u KiB)\n",
231 	       kernel_addr, kernel_addr + hdr->kernel_size,
232 	       DIV_ROUND_UP(hdr->kernel_size, 1024));
233 
234 	int len = 0;
235 	if (cmdline) {
236 		debug("Kernel command line: %s\n", cmdline);
237 		len += strlen(cmdline);
238 	}
239 
240 	char *bootargs = env_get("bootargs");
241 	if (bootargs)
242 		len += strlen(bootargs);
243 
244 	char *newbootargs = malloc(len + 2);
245 	if (!newbootargs) {
246 		puts("Error: malloc in android_image_get_kernel failed!\n");
247 		return -ENOMEM;
248 	}
249 	*newbootargs = '\0';
250 
251 	if (bootargs) {
252 		strcpy(newbootargs, bootargs);
253 		strcat(newbootargs, " ");
254 	}
255 	if (cmdline)
256 		strcat(newbootargs, cmdline);
257 
258 	env_set("bootargs", newbootargs);
259 
260 	if (os_data) {
261 		*os_data = (ulong)hdr;
262 		*os_data += hdr->page_size;
263 	}
264 	if (os_len)
265 		*os_len = hdr->kernel_size;
266 	return 0;
267 }
268 
269 int android_image_check_header(const struct andr_img_hdr *hdr)
270 {
271 	return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE);
272 }
273 
274 ulong android_image_get_end(const struct andr_img_hdr *hdr)
275 {
276 	ulong end;
277 	/*
278 	 * The header takes a full page, the remaining components are aligned
279 	 * on page boundary
280 	 */
281 	end = (ulong)hdr;
282 	if (hdr->header_version < 3) {
283 		end += hdr->page_size;
284 		end += ALIGN(hdr->kernel_size, hdr->page_size);
285 		end += ALIGN(hdr->ramdisk_size, hdr->page_size);
286 		end += ALIGN(hdr->second_size, hdr->page_size);
287 		if (hdr->header_version == 1) {
288 			end += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
289 		} else if (hdr->header_version == 2) {
290 			end += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
291 			end += ALIGN(hdr->dtb_size, hdr->page_size);
292 		}
293 	} else {
294 		/* boot_img_hdr_v34 */
295 		end += hdr->page_size;
296 		end += ALIGN(hdr->kernel_size, hdr->page_size);
297 		end += ALIGN(hdr->ramdisk_size, hdr->page_size);
298 	}
299 
300 	return end;
301 }
302 
303 u32 android_image_get_ksize(const struct andr_img_hdr *hdr)
304 {
305 	return hdr->kernel_size;
306 }
307 
308 void android_image_set_kload(struct andr_img_hdr *hdr, u32 load_address)
309 {
310 	hdr->kernel_addr = load_address;
311 }
312 
313 ulong android_image_get_kload(const struct andr_img_hdr *hdr)
314 {
315 	return android_image_get_kernel_addr(hdr);
316 }
317 
318 int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
319 			      ulong *rd_data, ulong *rd_len)
320 {
321 	ulong ramdisk_addr_r;
322 	ulong start, end;
323 
324 	if (!hdr->ramdisk_size) {
325 		*rd_data = *rd_len = 0;
326 		return -1;
327 	}
328 
329 	/* Have been loaded by android_image_load_separate() on ramdisk_addr_r */
330 	ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
331 	if (!ramdisk_addr_r) {
332 		printf("No Found Ramdisk Load Address.\n");
333 		return -1;
334 	}
335 
336 	*rd_data = ramdisk_addr_r;
337 	*rd_len = hdr->ramdisk_size;
338 	if (hdr->header_version >= 3)
339 		*rd_len += hdr->vendor_ramdisk_size;
340 	if (hdr->header_version >= 4) {
341 		 *rd_len += hdr->vendor_bootconfig_size +
342 		  ANDROID_ADDITION_BOOTCONFIG_PARAMS_MAX_SIZE;
343 	}
344 
345 	/* just for print msg */
346 	start = ramdisk_addr_r;
347 	if (hdr->header_version >= 3) {
348 		end = start + (ulong)hdr->vendor_ramdisk_size;
349 		printf("v-ramdisk:  0x%08lx - 0x%08lx (%u KiB)\n",
350 		       start, end, DIV_ROUND_UP(hdr->vendor_ramdisk_size, 1024));
351 		start = end;
352 	}
353 	{
354 		end = start + (ulong)hdr->ramdisk_size;
355 		printf("ramdisk:    0x%08lx - 0x%08lx (%u KiB)\n",
356 		       start, end, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
357 		start = end;
358 	}
359 	if (hdr->header_version >= 4) {
360 		end = start + (ulong)hdr->vendor_bootconfig_size;
361 		printf("bootconfig: 0x%08lx - 0x%08lx (%u KiB)\n",
362 		       start, end, DIV_ROUND_UP(hdr->vendor_bootconfig_size, 1024));
363 		start = end;
364 		end = start + ANDROID_ADDITION_BOOTCONFIG_PARAMS_MAX_SIZE;
365 		printf("bootparams: 0x%08lx - 0x%08lx\n", start, end);
366 	}
367 
368 	return 0;
369 }
370 
371 int android_image_get_fdt(const struct andr_img_hdr *hdr,
372 			      ulong *rd_data)
373 {
374 	ulong fdt_addr_r;
375 
376 	if (!hdr->second_size) {
377 		*rd_data = 0;
378 		return -1;
379 	}
380 
381 	/* Have been loaded by android_image_load_separate() on fdt_addr_r */
382 	fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0);
383 	if (!fdt_addr_r) {
384 		printf("No Found FDT Load Address.\n");
385 		return -1;
386 	}
387 
388 	*rd_data = fdt_addr_r;
389 
390 	debug("FDT load addr 0x%08x size %u KiB\n",
391 	      hdr->second_addr, DIV_ROUND_UP(hdr->second_size, 1024));
392 
393 	return 0;
394 }
395 
396 #ifdef CONFIG_ANDROID_BOOT_IMAGE_HASH
397 static void print_hash(const char *label, u8 *hash, int len)
398 {
399 	int i;
400 
401 	printf("%s:\n    0x", label ? : "Hash");
402 	for (i = 0; i < len; i++)
403 		printf("%02x", hash[i]);
404 	printf("\n");
405 }
406 #endif
407 
408 typedef enum {
409 	IMG_KERNEL,
410 	IMG_RAMDISK,	/* within boot.img or init_boot.img(Android-13 or later) */
411 	IMG_SECOND,
412 	IMG_RECOVERY_DTBO,
413 	IMG_RK_DTB,	/* within resource.img in second position */
414 	IMG_DTB,
415 	IMG_VENDOR_RAMDISK,
416 	IMG_BOOTCONFIG,
417 	IMG_MAX,
418 } img_t;
419 
420 #if defined(CONFIG_ANDROID_BOOT_IMAGE_HASH) && !defined(CONFIG_DM_CRYPTO)
421 static sha1_context sha1_ctx;
422 #endif
423 
424 static int image_load(img_t img, struct andr_img_hdr *hdr,
425 		      ulong blkstart, void *ram_base,
426 		      struct udevice *crypto)
427 {
428 	struct blk_desc *desc = rockchip_get_bootdev();
429 	disk_partition_t part_vendor_boot;
430 	disk_partition_t part_init_boot;
431 	__maybe_unused u32 typesz;
432 	u32 andr_version = (hdr->os_version >> 25) & 0x7f;
433 	ulong pgsz = hdr->page_size;
434 	ulong blksz = desc->blksz;
435 	ulong blkcnt, blkoff;
436 	ulong memmove_dst = 0;
437 	ulong bsoffs = 0;
438 	ulong extra = 0;
439 	ulong length;
440 	void *buffer;
441 	void *tmp = NULL;
442 	int ret = 0;
443 
444 	switch (img) {
445 	case IMG_KERNEL:
446 		bsoffs = 0; /* include a page_size(image header) */
447 		length = hdr->kernel_size + pgsz;
448 		buffer = (void *)env_get_ulong("android_addr_r", 16, 0);
449 		blkcnt = DIV_ROUND_UP(hdr->kernel_size + pgsz, blksz);
450 		typesz = sizeof(hdr->kernel_size);
451 		if (!sysmem_alloc_base(MEM_KERNEL,
452 			(phys_addr_t)buffer, blkcnt * blksz))
453 			return -ENOMEM;
454 		break;
455 	case IMG_VENDOR_RAMDISK:
456 		if (hdr->vendor_boot_buf) {
457 			ram_base = hdr->vendor_boot_buf;
458 		} else {
459 			if (part_get_info_by_name(desc,
460 						  ANDROID_PARTITION_VENDOR_BOOT,
461 						  &part_vendor_boot) < 0) {
462 				printf("No vendor boot partition\n");
463 				return -ENOENT;
464 			}
465 			ram_base = 0;
466 		}
467 
468 		blkstart = part_vendor_boot.start;
469 		pgsz = hdr->vendor_page_size;
470 		bsoffs = ALIGN(VENDOR_BOOT_HDRv3_SIZE, pgsz);
471 		length = hdr->vendor_ramdisk_size;
472 		buffer = (void *)env_get_ulong("ramdisk_addr_r", 16, 0);
473 		blkcnt = DIV_ROUND_UP(hdr->vendor_ramdisk_size, blksz);
474 		typesz = sizeof(hdr->vendor_ramdisk_size);
475 		/*
476 		 * Add extra memory for generic ramdisk space.
477 		 *
478 		 * In case of unaligned vendor ramdisk size, reserve
479 		 * 1 more blksz.
480 		 *
481 		 * Reserve 8KB for bootloader cmdline.
482 		 */
483 		if (hdr->header_version >= 3)
484 			extra += ALIGN(hdr->ramdisk_size, blksz) + blksz;
485 		if (hdr->header_version >= 4)
486 			extra += ALIGN(hdr->vendor_bootconfig_size, blksz) +
487 				 ANDROID_ADDITION_BOOTCONFIG_PARAMS_MAX_SIZE;
488 		if (length && !sysmem_alloc_base(MEM_RAMDISK,
489 			(phys_addr_t)buffer, blkcnt * blksz + extra))
490 			return -ENOMEM;
491 		break;
492 	case IMG_RAMDISK:
493 		/* get ramdisk from init_boot.img ? */
494 		if (hdr->header_version >= 4 && andr_version >= 13) {
495 			if (hdr->init_boot_buf) {
496 				ram_base = hdr->init_boot_buf;
497 			} else {
498 				if (part_get_info_by_name(desc,
499 				    ANDROID_PARTITION_INIT_BOOT, &part_init_boot) < 0) {
500 					printf("No init boot partition\n");
501 					return -ENOENT;
502 				}
503 				blkstart = part_init_boot.start;
504 				ram_base = 0;
505 			}
506 			bsoffs = pgsz;
507 		} else {
508 			/* get ramdisk from generic boot.img */
509 			bsoffs = pgsz + ALIGN(hdr->kernel_size, pgsz);
510 		}
511 
512 		length = hdr->ramdisk_size;
513 		buffer = (void *)env_get_ulong("ramdisk_addr_r", 16, 0);
514 		blkcnt = DIV_ROUND_UP(hdr->ramdisk_size, blksz);
515 		typesz = sizeof(hdr->ramdisk_size);
516 
517 		/*
518 		 * ramdisk_addr_r v012:
519 		 *	|----------------|
520 		 *	|    ramdisk     |
521 		 *	|----------------|
522 		 *
523 		 * ramdisk_addr_r v3 (Android-11 and later):
524 		 *	|----------------|---------|
525 		 *	| vendor-ramdisk | ramdisk |
526 		 *	|----------------|---------|
527 		 *
528 		 * ramdisk_addr_r v4 (Android-12 and later):
529 		 *	|----------------|---------|------------|------------|
530 		 *	| vendor-ramdisk | ramdisk | bootconfig | bootparams |
531 		 *	|----------------|---------|------------|------------|
532 		 *
533 		 * ramdisk_addr_r v4 + init_boot(Android-13 and later):
534 		 *	|----------------|----------------|------------|------------|
535 		 *	| vendor-ramdisk | (init_)ramdisk | bootconfig | bootparams |
536 		 *	|----------------|----------------|------------|------------|
537 		 */
538 		if (hdr->header_version >= 3) {
539 			buffer += hdr->vendor_ramdisk_size;
540 			if (!IS_ALIGNED((ulong)buffer, blksz)) {
541 				memmove_dst = (ulong)buffer;
542 				buffer = (void *)ALIGN(memmove_dst, blksz);
543 			}
544 		}
545 		/* sysmem has been alloced by vendor ramdisk */
546 		if (hdr->header_version < 3) {
547 			if (length && !sysmem_alloc_base(MEM_RAMDISK,
548 				(phys_addr_t)buffer, blkcnt * blksz))
549 				return -ENOMEM;
550 		}
551 		break;
552 	case IMG_BOOTCONFIG:
553 		if (hdr->header_version < 4)
554 			return 0;
555 
556 		if (hdr->vendor_boot_buf) {
557 			ram_base = hdr->vendor_boot_buf;
558 		} else {
559 			if (part_get_info_by_name(desc,
560 						  ANDROID_PARTITION_VENDOR_BOOT,
561 						  &part_vendor_boot) < 0) {
562 				printf("No vendor boot partition\n");
563 				return -ENOENT;
564 			}
565 			ram_base = 0;
566 		}
567 		blkstart = part_vendor_boot.start;
568 		pgsz = hdr->vendor_page_size;
569 		bsoffs = ALIGN(VENDOR_BOOT_HDRv4_SIZE, pgsz) +
570 			 ALIGN(hdr->vendor_ramdisk_size, pgsz) +
571 			 ALIGN(hdr->dtb_size, pgsz) +
572 			 ALIGN(hdr->vendor_ramdisk_table_size, pgsz);
573 		length = hdr->vendor_bootconfig_size;
574 		buffer = (void *)env_get_ulong("ramdisk_addr_r", 16, 0);
575 		blkcnt = DIV_ROUND_UP(hdr->vendor_bootconfig_size, blksz);
576 		typesz = sizeof(hdr->vendor_bootconfig_size);
577 
578 		buffer += hdr->vendor_ramdisk_size + hdr->ramdisk_size;
579 		if (!IS_ALIGNED((ulong)buffer, blksz)) {
580 			memmove_dst = (ulong)buffer;
581 			buffer = (void *)ALIGN(memmove_dst, blksz);
582 		}
583 		break;
584 	case IMG_SECOND:
585 		bsoffs = pgsz +
586 			 ALIGN(hdr->kernel_size, pgsz) +
587 			 ALIGN(hdr->ramdisk_size, pgsz);
588 		length = hdr->second_size;
589 		blkcnt = DIV_ROUND_UP(hdr->second_size, blksz);
590 		buffer = tmp = malloc(blkcnt * blksz);
591 		typesz = sizeof(hdr->second_size);
592 		break;
593 	case IMG_RECOVERY_DTBO:
594 		bsoffs = pgsz +
595 			 ALIGN(hdr->kernel_size, pgsz) +
596 			 ALIGN(hdr->ramdisk_size, pgsz) +
597 			 ALIGN(hdr->second_size, pgsz);
598 		length = hdr->recovery_dtbo_size;
599 		blkcnt = DIV_ROUND_UP(hdr->recovery_dtbo_size, blksz);
600 		buffer = tmp = malloc(blkcnt * blksz);
601 		typesz = sizeof(hdr->recovery_dtbo_size);
602 		break;
603 	case IMG_DTB:
604 		bsoffs = pgsz +
605 			 ALIGN(hdr->kernel_size, pgsz) +
606 			 ALIGN(hdr->ramdisk_size, pgsz) +
607 			 ALIGN(hdr->second_size, pgsz) +
608 			 ALIGN(hdr->recovery_dtbo_size, pgsz);
609 		length = hdr->dtb_size;
610 		blkcnt = DIV_ROUND_UP(hdr->dtb_size, blksz);
611 		buffer = tmp = malloc(blkcnt * blksz);
612 		typesz = sizeof(hdr->dtb_size);
613 		break;
614 	case IMG_RK_DTB:
615 #ifdef CONFIG_RKIMG_BOOTLOADER
616 		/* No going further, it handles DTBO, HW-ID, etc */
617 		buffer = (void *)env_get_ulong("fdt_addr_r", 16, 0);
618 		if (gd->fdt_blob != (void *)buffer)
619 			ret = rockchip_read_dtb_file(buffer);
620 #endif
621 		return ret < 0 ? ret : 0;
622 	default:
623 		return -EINVAL;
624 	}
625 
626 	if (!buffer) {
627 		printf("No memory for image(%d)\n", img);
628 		return -ENOMEM;
629 	}
630 
631 	if (!blksz || !length)
632 		goto crypto_calc;
633 
634 	/* load */
635 	if (ram_base) {
636 		memcpy(buffer, (char *)((ulong)ram_base + bsoffs), length);
637 	} else {
638 		blkoff = DIV_ROUND_UP(bsoffs, blksz);
639 		ret = blk_dread(desc, blkstart + blkoff, blkcnt, buffer);
640 		if (ret != blkcnt) {
641 			printf("Failed to read img(%d), ret=%d\n", img, ret);
642 			return -EIO;
643 		}
644 	}
645 
646 	if (memmove_dst)
647 		memmove((char *)memmove_dst, buffer, length);
648 
649 crypto_calc:
650 	if (img == IMG_KERNEL) {
651 		buffer += pgsz;
652 		length -= pgsz;
653 	}
654 
655 	/* sha1 */
656 	if (hdr->header_version < 3) {
657 #ifdef CONFIG_ANDROID_BOOT_IMAGE_HASH
658 #ifdef CONFIG_DM_CRYPTO
659 		crypto_sha_update(crypto, (u32 *)buffer, length);
660 		crypto_sha_update(crypto, (u32 *)&length, typesz);
661 #else
662 		sha1_update(&sha1_ctx, (void *)buffer, length);
663 		sha1_update(&sha1_ctx, (void *)&length, typesz);
664 #endif
665 #endif
666 	}
667 
668 	if (tmp)
669 		free(tmp);
670 
671 	return 0;
672 }
673 
674 static int images_load_verify(struct andr_img_hdr *hdr, ulong part_start,
675 			      void *ram_base, struct udevice *crypto)
676 {
677 	/* load, never change order ! */
678 	if (image_load(IMG_KERNEL, hdr, part_start, ram_base, crypto))
679 		return -1;
680 	if (image_load(IMG_RAMDISK, hdr, part_start, ram_base, crypto))
681 		return -1;
682 	if (image_load(IMG_SECOND, hdr, part_start, ram_base, crypto))
683 		return -1;
684 	if (hdr->header_version > 0) {
685 		if (image_load(IMG_RECOVERY_DTBO, hdr, part_start,
686 			       ram_base, crypto))
687 			return -1;
688 	}
689 	if (hdr->header_version > 1) {
690 		if (image_load(IMG_DTB, hdr, part_start, ram_base, crypto))
691 			return -1;
692 	}
693 
694 	return 0;
695 }
696 
697 /*
698  * @ram_base: !NULL means require memcpy for an exist full android image.
699  */
700 static int android_image_separate(struct andr_img_hdr *hdr,
701 				  const disk_partition_t *part,
702 				  void *load_address,
703 				  void *ram_base)
704 {
705 	ulong bstart;
706 	int ret;
707 
708 	if (android_image_check_header(hdr)) {
709 		printf("Bad android image header\n");
710 		return -EINVAL;
711 	}
712 
713 	/* set for image_load(IMG_KERNEL, ...) */
714 	env_set_hex("android_addr_r", (ulong)load_address);
715 	bstart = part ? part->start : 0;
716 
717 	/*
718 	 * 1. Load images to their individual target ram position
719 	 *    in order to disable fdt/ramdisk relocation.
720 	 */
721 
722 	/* load rk-kernel.dtb alone */
723 	if (image_load(IMG_RK_DTB, hdr, bstart, ram_base, NULL))
724 		return -1;
725 
726 #ifdef CONFIG_ANDROID_BOOT_IMAGE_HASH
727 	if (hdr->header_version < 3) {
728 		struct udevice *dev = NULL;
729 		uchar hash[20];
730 #ifdef CONFIG_DM_CRYPTO
731 		sha_context ctx;
732 
733 		ctx.length = 0;
734 		ctx.algo = CRYPTO_SHA1;
735 		dev = crypto_get_device(ctx.algo);
736 		if (!dev) {
737 			printf("Can't find crypto device for SHA1\n");
738 			return -ENODEV;
739 		}
740 
741 		/* v1 & v2: requires total length before sha init */
742 		ctx.length += hdr->kernel_size + sizeof(hdr->kernel_size) +
743 			      hdr->ramdisk_size + sizeof(hdr->ramdisk_size) +
744 			      hdr->second_size + sizeof(hdr->second_size);
745 		if (hdr->header_version > 0)
746 			ctx.length += hdr->recovery_dtbo_size +
747 						sizeof(hdr->recovery_dtbo_size);
748 		if (hdr->header_version > 1)
749 			ctx.length += hdr->dtb_size + sizeof(hdr->dtb_size);
750 		crypto_sha_init(dev, &ctx);
751 #else
752 		sha1_starts(&sha1_ctx);
753 #endif
754 		ret = images_load_verify(hdr, bstart, ram_base, dev);
755 		if (ret)
756 			return ret;
757 
758 #ifdef CONFIG_DM_CRYPTO
759 		crypto_sha_final(dev, &ctx, hash);
760 #else
761 		sha1_finish(&sha1_ctx, hash);
762 #endif
763 		if (memcmp(hash, hdr->id, 20)) {
764 			print_hash("Hash from header", (u8 *)hdr->id, 20);
765 			print_hash("Hash real", (u8 *)hash, 20);
766 			return -EBADFD;
767 		} else {
768 			printf("ANDROID: Hash OK\n");
769 		}
770 	} else
771 #endif
772 	{
773 		ret = images_load_verify(hdr, bstart, ram_base, NULL);
774 		if (ret)
775 			return ret;
776 	}
777 
778 	/* 2. Disable fdt/ramdisk relocation, it saves boot time */
779 	env_set("bootm-no-reloc", "y");
780 
781 	return 0;
782 }
783 
784 static int android_image_separate_v34(struct andr_img_hdr *hdr,
785 				      const disk_partition_t *part,
786 				      void *load_address, void *ram_base)
787 {
788 	ulong bstart;
789 
790 	if (android_image_check_header(hdr)) {
791 		printf("Bad android image header\n");
792 		return -EINVAL;
793 	}
794 
795 	/* set for image_load(IMG_KERNEL, ...) */
796 	env_set_hex("android_addr_r", (ulong)load_address);
797 	bstart = part ? part->start : 0;
798 
799 	/*
800 	 * 1. Load images to their individual target ram position
801 	 *    in order to disable fdt/ramdisk relocation.
802 	 */
803 	if (image_load(IMG_RK_DTB,  hdr, bstart, ram_base, NULL))
804 		return -1;
805 	if (image_load(IMG_KERNEL,  hdr, bstart, ram_base, NULL))
806 		return -1;
807 	if (image_load(IMG_VENDOR_RAMDISK, hdr, bstart, ram_base, NULL))
808 		return -1;
809 	if (image_load(IMG_RAMDISK, hdr, bstart, ram_base, NULL))
810 		return -1;
811 	if (image_load(IMG_BOOTCONFIG, hdr, bstart, ram_base, NULL))
812 		return -1;
813 	/*
814 	 * Copy the populated hdr to load address after image_load(IMG_KERNEL)
815 	 *
816 	 * The image_load(IMG_KERNEL) only reads boot_img_hdr_v34 while
817 	 * vendor_boot_img_hdr_v34 is not included, so fix it here.
818 	 */
819 	memcpy((char *)load_address, hdr, hdr->page_size);
820 
821 	/* 2. Disable fdt/ramdisk relocation, it saves boot time */
822 	env_set("bootm-no-reloc", "y");
823 
824 	return 0;
825 }
826 
827 static ulong android_image_get_comp_addr(struct andr_img_hdr *hdr, int comp)
828 {
829 	ulong kernel_addr_c;
830 	ulong load_addr = 0;
831 
832 	kernel_addr_c = env_get_ulong("kernel_addr_c", 16, 0);
833 
834 #ifdef CONFIG_ARM64
835 	/*
836 	 * On 64-bit kernel, assuming use IMAGE by default.
837 	 *
838 	 * kernel_addr_c is for LZ4-IMAGE but maybe not defined.
839 	 * kernel_addr_r is for IMAGE.
840 	 */
841 	if (comp != IH_COMP_NONE) {
842 		ulong comp_addr;
843 
844 		if (kernel_addr_c) {
845 			comp_addr = kernel_addr_c;
846 		} else {
847 			printf("Warn: No \"kernel_addr_c\"\n");
848 			comp_addr = CONFIG_SYS_SDRAM_BASE + 0x2000000;/* 32M */
849 			env_set_hex("kernel_addr_c", comp_addr);
850 		}
851 
852 		load_addr = comp_addr - hdr->page_size;
853 	}
854 #else
855 	/*
856 	 * On 32-bit kernel:
857 	 *
858 	 * The input load_addr is from env value: "kernel_addr_r", it has
859 	 * different role depends on whether kernel_addr_c is defined:
860 	 *
861 	 * - kernel_addr_r is for lz4/zImage if kernel_addr_c if [not] defined.
862 	 * - kernel_addr_r is for IMAGE if kernel_addr_c is defined.
863 	 */
864 	if (comp == IH_COMP_NONE) {
865 		if (kernel_addr_c) {
866 			/* input load_addr is for Image, nothing to do */
867 		} else {
868 			/* input load_addr is for lz4/zImage, set default addr for Image */
869 			load_addr = CONFIG_SYS_SDRAM_BASE + 0x8000;
870 			env_set_hex("kernel_addr_r", load_addr);
871 
872 			load_addr -= hdr->page_size;
873 		}
874 	} else {
875 		if (kernel_addr_c) {
876 			/* input load_addr is for Image, so use another for lz4/zImage */
877 			load_addr = kernel_addr_c - hdr->page_size;
878 		} else {
879 			/* input load_addr is for lz4/zImage, nothing to do */
880 		}
881 	}
882 #endif
883 
884 	return load_addr;
885 }
886 
887 void android_image_set_decomp(struct andr_img_hdr *hdr, int comp)
888 {
889 	ulong kernel_addr_r;
890 
891 	env_set_ulong("os_comp", comp);
892 
893 	/* zImage handles decompress itself */
894 	if (comp != IH_COMP_NONE && comp != IH_COMP_ZIMAGE) {
895 		kernel_addr_r = env_get_ulong("kernel_addr_r", 16, 0x02080000);
896 		android_image_set_kload(hdr, kernel_addr_r);
897 		android_image_set_comp(hdr, comp);
898 	} else {
899 		android_image_set_comp(hdr, IH_COMP_NONE);
900 	}
901 }
902 
903 static int android_image_load_separate(struct andr_img_hdr *hdr,
904 				       const disk_partition_t *part,
905 				       void *load_addr)
906 {
907 	if (hdr->header_version < 3)
908 		return android_image_separate(hdr, part, load_addr, NULL);
909 	else
910 		return android_image_separate_v34(hdr, part, load_addr, NULL);
911 }
912 
913 int android_image_memcpy_separate(struct andr_img_hdr *hdr, ulong *load_addr)
914 {
915 	ulong comp_addr;
916 	int comp;
917 
918 	comp = bootm_parse_comp((void *)(ulong)hdr + hdr->page_size);
919 	comp_addr = android_image_get_comp_addr(hdr, comp);
920 
921 	/* non-compressed image: already in-place */
922 	if ((ulong)hdr == *load_addr)
923 		return 0;
924 
925 	/* compressed image */
926 	if (comp_addr) {
927 		*load_addr = comp_addr;
928 		if ((ulong)hdr == comp_addr)	/* already in-place */
929 			return 0;
930 	}
931 
932 	/*
933 	 * The most possible reason to arrive here is:
934 	 *
935 	 * VBoot=1 and AVB load full partition to a temp memory buffer, now we
936 	 * separate(memcpy) subimages from boot.img to where they should be.
937 	 */
938 	if (hdr->header_version < 3) {
939 		if (android_image_separate(hdr, NULL, (void *)(*load_addr), hdr))
940 			return -1;
941 	} else {
942 		if (android_image_separate_v34(hdr, NULL, (void *)(*load_addr), hdr))
943 			return -1;
944 	}
945 
946 	android_image_set_decomp((void *)(*load_addr), comp);
947 
948 	return 0;
949 }
950 
951 long android_image_load(struct blk_desc *dev_desc,
952 			const disk_partition_t *part_info,
953 			unsigned long load_address,
954 			unsigned long max_size) {
955 	struct andr_img_hdr *hdr;
956 	ulong comp_addr;
957 	int comp, ret;
958 	int blk_off;
959 
960 	if (max_size < part_info->blksz)
961 		return -1;
962 
963 	hdr = populate_andr_img_hdr(dev_desc, (disk_partition_t *)part_info);
964 	if (!hdr) {
965 		printf("No valid android hdr\n");
966 		return -1;
967 	}
968 
969 	/*
970 	 * create the layout:
971 	 *
972 	 * |<- page_size ->|1-blk |
973 	 * |-----|---------|------|-----|
974 	 * | hdr |   ...   |   kernel   |
975 	 * |-----|----- ---|------------|
976 	 *
977 	 * Alloc page_size and 1 more blk for reading kernel image to
978 	 * get it's compression type, then fill the android hdr what
979 	 * we have populated before.
980 	 *
981 	 * Why? see: android_image_get_kernel_addr().
982 	 */
983 	blk_off = BLK_CNT(hdr->page_size, dev_desc->blksz);
984 	hdr = (struct andr_img_hdr *)
985 			realloc(hdr, (blk_off + 1) * dev_desc->blksz);
986 	if (!hdr)
987 		return -1;
988 
989 	if (blk_dread(dev_desc, part_info->start + blk_off, 1,
990 		      (char *)hdr + hdr->page_size) != 1) {
991 		free(hdr);
992 		return -1;
993 	}
994 
995 	/* Changed to compressed address ? */
996 	comp = bootm_parse_comp((void *)(ulong)hdr + hdr->page_size);
997 	comp_addr = android_image_get_comp_addr(hdr, comp);
998 	if (comp_addr)
999 		load_address = comp_addr;
1000 	else
1001 		load_address -= hdr->page_size;
1002 
1003 	ret = android_image_load_separate(hdr, part_info, (void *)load_address);
1004 	if (ret) {
1005 		printf("Failed to load android image\n");
1006 		goto fail;
1007 	}
1008 	android_image_set_decomp((void *)load_address, comp);
1009 
1010 	debug("Loading Android Image to 0x%08lx\n", load_address);
1011 
1012 	free(hdr);
1013 	return load_address;
1014 
1015 fail:
1016 	free(hdr);
1017 	return -1;
1018 }
1019 
1020 static struct andr_img_hdr *
1021 extract_boot_image_v012_header(struct blk_desc *dev_desc,
1022 			       const disk_partition_t *boot_img)
1023 {
1024 	struct andr_img_hdr *hdr;
1025 	long blk_cnt, blks_read;
1026 
1027 	blk_cnt = BLK_CNT(sizeof(struct andr_img_hdr), dev_desc->blksz);
1028 	hdr = (struct andr_img_hdr *)malloc(blk_cnt * dev_desc->blksz);
1029 
1030 	if (!blk_cnt || !hdr)
1031 		return NULL;
1032 
1033 	blks_read = blk_dread(dev_desc, boot_img->start, blk_cnt, hdr);
1034 	if (blks_read != blk_cnt) {
1035 		debug("boot img header blk cnt is %ld and blks read is %ld\n",
1036 		      blk_cnt, blks_read);
1037 		return NULL;
1038 	}
1039 
1040 	if (android_image_check_header((void *)hdr)) {
1041 		printf("boot header magic is invalid.\n");
1042 		return NULL;
1043 	}
1044 
1045 	if (hdr->page_size < sizeof(*hdr)) {
1046 		printf("android hdr is over size\n");
1047 		return NULL;
1048 	}
1049 
1050 	return hdr;
1051 }
1052 
1053 static struct boot_img_hdr_v34 *
1054 extract_boot_image_v34_header(struct blk_desc *dev_desc,
1055 			      const disk_partition_t *boot_img)
1056 {
1057 	struct boot_img_hdr_v34 *boot_hdr;
1058 	disk_partition_t part;
1059 	long blk_cnt, blks_read;
1060 
1061 	blk_cnt = BLK_CNT(sizeof(struct boot_img_hdr_v34), dev_desc->blksz);
1062 	boot_hdr = (struct boot_img_hdr_v34 *)malloc(blk_cnt * dev_desc->blksz);
1063 
1064 	if (!blk_cnt || !boot_hdr)
1065 		return NULL;
1066 
1067 	blks_read = blk_dread(dev_desc, boot_img->start, blk_cnt, boot_hdr);
1068 	if (blks_read != blk_cnt) {
1069 		debug("boot img header blk cnt is %ld and blks read is %ld\n",
1070 		      blk_cnt, blks_read);
1071 		return NULL;
1072 	}
1073 
1074 	if (android_image_check_header((void *)boot_hdr)) {
1075 		printf("boot header magic is invalid.\n");
1076 		return NULL;
1077 	}
1078 
1079 	if (boot_hdr->header_version < 3) {
1080 		printf("boot header %d, is not >= v3.\n",
1081 		       boot_hdr->header_version);
1082 		return NULL;
1083 	}
1084 
1085 	/* Start from android-13 GKI, it doesn't assign 'os_version' */
1086 	if (boot_hdr->header_version >= 4 && boot_hdr->os_version == 0) {
1087 		if (part_get_info_by_name(dev_desc,
1088 				ANDROID_PARTITION_INIT_BOOT, &part) > 0)
1089 			boot_hdr->os_version = 13 << 25;
1090 	}
1091 
1092 	return boot_hdr;
1093 }
1094 
1095 static struct vendor_boot_img_hdr_v34 *
1096 extract_vendor_boot_image_v34_header(struct blk_desc *dev_desc,
1097 				     const disk_partition_t *part_vendor_boot)
1098 {
1099 	struct vendor_boot_img_hdr_v34 *vboot_hdr;
1100 	long blk_cnt, blks_read;
1101 
1102 	blk_cnt = BLK_CNT(sizeof(struct vendor_boot_img_hdr_v34),
1103 				part_vendor_boot->blksz);
1104 	vboot_hdr = (struct vendor_boot_img_hdr_v34 *)
1105 				malloc(blk_cnt * part_vendor_boot->blksz);
1106 
1107 	if (!blk_cnt || !vboot_hdr)
1108 		return NULL;
1109 
1110 	blks_read = blk_dread(dev_desc, part_vendor_boot->start,
1111 			      blk_cnt, vboot_hdr);
1112 	if (blks_read != blk_cnt) {
1113 		debug("vboot img header blk cnt is %ld and blks read is %ld\n",
1114 		      blk_cnt, blks_read);
1115 		return NULL;
1116 	}
1117 
1118 	if (strncmp(VENDOR_BOOT_MAGIC, (void *)vboot_hdr->magic,
1119 		    VENDOR_BOOT_MAGIC_SIZE)) {
1120 		printf("vendor boot header is invalid.\n");
1121 		return NULL;
1122 	}
1123 
1124 	if (vboot_hdr->header_version < 3) {
1125 		printf("vendor boot header %d, is not >= v3.\n",
1126 		       vboot_hdr->header_version);
1127 		return NULL;
1128 	}
1129 
1130 	return vboot_hdr;
1131 }
1132 
1133 int populate_boot_info(const struct boot_img_hdr_v34 *boot_hdr,
1134 		       const struct vendor_boot_img_hdr_v34 *vendor_boot_hdr,
1135 		       const struct boot_img_hdr_v34 *init_boot_hdr,
1136 		       struct andr_img_hdr *hdr, bool save_hdr)
1137 {
1138 	memset(hdr->magic, 0, ANDR_BOOT_MAGIC_SIZE);
1139 	memcpy(hdr->magic, boot_hdr->magic, ANDR_BOOT_MAGIC_SIZE);
1140 
1141 	hdr->kernel_size = boot_hdr->kernel_size;
1142 	/* don't use vendor_boot_hdr->kernel_addr, we prefer "hdr + hdr->page_size" */
1143 	hdr->kernel_addr = ANDROID_IMAGE_DEFAULT_KERNEL_ADDR;
1144 
1145 	/*
1146 	 * generic ramdisk: immediately following the vendor ramdisk.
1147 	 * It can be from init_boot.img or boot.img.
1148 	 */
1149 	if (init_boot_hdr)
1150 		hdr->ramdisk_size = init_boot_hdr->ramdisk_size;
1151 	else
1152 		hdr->ramdisk_size = boot_hdr->ramdisk_size;
1153 
1154 	/* actually, useless */
1155 	hdr->ramdisk_addr = env_get_ulong("ramdisk_addr_r", 16, 0);
1156 
1157 	/* removed in v3 */
1158 	hdr->second_size = 0;
1159 	hdr->second_addr = 0;
1160 
1161 	hdr->tags_addr = vendor_boot_hdr->tags_addr;
1162 
1163 	/* fixed in v3 */
1164 	hdr->page_size = 4096;
1165 	hdr->header_version = boot_hdr->header_version;
1166 	hdr->os_version = boot_hdr->os_version;
1167 
1168 	memset(hdr->name, 0, ANDR_BOOT_NAME_SIZE);
1169 	strncpy(hdr->name, (const char *)vendor_boot_hdr->name, ANDR_BOOT_NAME_SIZE);
1170 
1171 	/* removed in v3 */
1172 	memset(hdr->cmdline, 0, ANDR_BOOT_ARGS_SIZE);
1173 	memset(hdr->id, 0, 32);
1174 	memset(hdr->extra_cmdline, 0, ANDR_BOOT_EXTRA_ARGS_SIZE);
1175 	hdr->recovery_dtbo_size = 0;
1176 	hdr->recovery_dtbo_offset = 0;
1177 
1178 	hdr->header_size = boot_hdr->header_size;
1179 	hdr->dtb_size = vendor_boot_hdr->dtb_size;
1180 	hdr->dtb_addr = vendor_boot_hdr->dtb_addr;
1181 
1182 	/* boot_img_hdr_v34 fields */
1183 	hdr->vendor_ramdisk_size = vendor_boot_hdr->vendor_ramdisk_size;
1184 	hdr->vendor_page_size = vendor_boot_hdr->page_size;
1185 	hdr->vendor_header_version = vendor_boot_hdr->header_version;
1186 	hdr->vendor_header_size = vendor_boot_hdr->header_size;
1187 
1188 	hdr->total_cmdline = calloc(1, TOTAL_BOOT_ARGS_SIZE);
1189 	if (!hdr->total_cmdline)
1190 		return -ENOMEM;
1191 	strncpy(hdr->total_cmdline, (const char *)boot_hdr->cmdline,
1192 		sizeof(boot_hdr->cmdline));
1193 	strncat(hdr->total_cmdline, " ", 1);
1194 	strncat(hdr->total_cmdline, (const char *)vendor_boot_hdr->cmdline,
1195 		sizeof(vendor_boot_hdr->cmdline));
1196 
1197 	/* new for header v4 */
1198 	if (vendor_boot_hdr->header_version >= 4) {
1199 		hdr->vendor_ramdisk_table_size =
1200 				vendor_boot_hdr->vendor_ramdisk_table_size;
1201 		hdr->vendor_ramdisk_table_entry_num =
1202 				vendor_boot_hdr->vendor_ramdisk_table_entry_num;
1203 		hdr->vendor_ramdisk_table_entry_size =
1204 				vendor_boot_hdr->vendor_ramdisk_table_entry_size;
1205 		/*
1206 		 * If we place additional "androidboot.xxx" parameters after
1207 		 * bootconfig, this field value should be increased,
1208 		 * but not over than ANDROID_ADDITION_BOOTCONFIG_PARAMS_MAX_SIZE.
1209 		 */
1210 		hdr->vendor_bootconfig_size =
1211 				vendor_boot_hdr->vendor_bootconfig_size;
1212 	} else {
1213 		hdr->vendor_ramdisk_table_size = 0;
1214 		hdr->vendor_ramdisk_table_entry_num = 0;
1215 		hdr->vendor_ramdisk_table_entry_size = 0;
1216 		hdr->vendor_bootconfig_size = 0;
1217 	}
1218 
1219 	hdr->init_boot_buf = save_hdr ? (void *)init_boot_hdr : 0;
1220 	hdr->vendor_boot_buf = save_hdr ? (void *)vendor_boot_hdr : 0;
1221 
1222 	if (hdr->page_size < sizeof(*hdr)) {
1223 		printf("android hdr is over size\n");
1224 		return -EINVAL;
1225 	}
1226 
1227 	return 0;
1228 }
1229 
1230 /*
1231  * The possible cases of boot.img + recovery.img:
1232  *
1233  * [N]: 0, 1, 2
1234  * [M]: 0, 1, 2, 3, 4
1235  *
1236  * |--------------------|---------------------|
1237  * |   boot.img         |    recovery.img     |
1238  * |--------------------|---------------------|
1239  * | boot_img_hdr_v[N]  |  boot_img_hdr_v[N]  | <= if A/B is not required
1240  * |--------------------|---------------------|
1241  * | boot_img_hdr_v34   |  boot_img_hdr_v2    | <= if A/B is not required
1242  * |------------------------------------------|
1243  * | boot_img_hdr_v[M], no recovery.img       | <= if A/B is required
1244  * |------------------------------------------|
1245  */
1246 struct andr_img_hdr *populate_andr_img_hdr(struct blk_desc *dev_desc,
1247 					   disk_partition_t *part_boot)
1248 {
1249 	disk_partition_t part_vendor_boot;
1250 	disk_partition_t part_init_boot;
1251 	struct vendor_boot_img_hdr_v34 *vboot_hdr = NULL;
1252 	struct boot_img_hdr_v34 *iboot_hdr = NULL;
1253 	struct boot_img_hdr_v34 *boot_hdr = NULL;
1254 	struct andr_img_hdr *andr_hdr = NULL;
1255 	int header_version;
1256 	int andr_version;
1257 
1258 	if (!dev_desc || !part_boot)
1259 		return NULL;
1260 
1261 	andr_hdr = (struct andr_img_hdr *)malloc(1 * dev_desc->blksz);
1262 	if (!andr_hdr)
1263 		return NULL;
1264 
1265 	if (blk_dread(dev_desc, part_boot->start, 1, andr_hdr) != 1) {
1266 		free(andr_hdr);
1267 		return NULL;
1268 	}
1269 
1270 	if (android_image_check_header(andr_hdr)) {
1271 		free(andr_hdr);
1272 		return NULL;
1273 	}
1274 
1275 	header_version = andr_hdr->header_version;
1276 	free(andr_hdr);
1277 	andr_hdr = NULL;
1278 
1279 	if (header_version < 3) {
1280 		return extract_boot_image_v012_header(dev_desc, part_boot);
1281 	} else {
1282 		if (part_get_info_by_name(dev_desc,
1283 					  ANDROID_PARTITION_VENDOR_BOOT,
1284 					  &part_vendor_boot) < 0) {
1285 			printf("No vendor boot partition\n");
1286 			return NULL;
1287 		}
1288 		boot_hdr = extract_boot_image_v34_header(dev_desc, part_boot);
1289 		vboot_hdr = extract_vendor_boot_image_v34_header(dev_desc,
1290 							&part_vendor_boot);
1291 		if (!boot_hdr || !vboot_hdr)
1292 			goto image_load_exit;
1293 
1294 		andr_version = (boot_hdr->os_version >> 25) & 0x7f;
1295 		if (header_version >= 4 && andr_version >= 13) {
1296 			if (part_get_info_by_name(dev_desc,
1297 						  ANDROID_PARTITION_INIT_BOOT,
1298 						  &part_init_boot) < 0) {
1299 				printf("No init boot partition\n");
1300 				return NULL;
1301 			}
1302 			iboot_hdr = extract_boot_image_v34_header(dev_desc, &part_init_boot);
1303 			if (!iboot_hdr)
1304 				goto image_load_exit;
1305 			if (!iboot_hdr->ramdisk_size) {
1306 				printf("No ramdisk in init boot partition\n");
1307 				goto image_load_exit;
1308 			}
1309 		}
1310 
1311 		andr_hdr = (struct andr_img_hdr *)
1312 				malloc(sizeof(struct andr_img_hdr));
1313 		if (!andr_hdr) {
1314 			printf("No memory for andr hdr\n");
1315 			goto image_load_exit;
1316 		}
1317 
1318 		if (populate_boot_info(boot_hdr, vboot_hdr,
1319 				       iboot_hdr, andr_hdr, false)) {
1320 			printf("populate boot info failed\n");
1321 			goto image_load_exit;
1322 		}
1323 
1324 image_load_exit:
1325 		if (boot_hdr)
1326 			free(boot_hdr);
1327 		if (iboot_hdr)
1328 			free(iboot_hdr);
1329 		if (vboot_hdr)
1330 			free(vboot_hdr);
1331 
1332 		return andr_hdr;
1333 	}
1334 
1335 	return NULL;
1336 }
1337 
1338 #if !defined(CONFIG_SPL_BUILD)
1339 /**
1340  * android_print_contents - prints out the contents of the Android format image
1341  * @hdr: pointer to the Android format image header
1342  *
1343  * android_print_contents() formats a multi line Android image contents
1344  * description.
1345  * The routine prints out Android image properties
1346  *
1347  * returns:
1348  *     no returned results
1349  */
1350 void android_print_contents(const struct andr_img_hdr *hdr)
1351 {
1352 	const char * const p = IMAGE_INDENT_STRING;
1353 	/* os_version = ver << 11 | lvl */
1354 	u32 os_ver = hdr->os_version >> 11;
1355 	u32 os_lvl = hdr->os_version & ((1U << 11) - 1);
1356 	u32 header_version = hdr->header_version;
1357 
1358 	printf("%skernel size:      %x\n", p, hdr->kernel_size);
1359 	printf("%skernel address:   %x\n", p, hdr->kernel_addr);
1360 	printf("%sramdisk size:     %x\n", p, hdr->ramdisk_size);
1361 	printf("%sramdisk address: %x\n", p, hdr->ramdisk_addr);
1362 	printf("%ssecond size:      %x\n", p, hdr->second_size);
1363 	printf("%ssecond address:   %x\n", p, hdr->second_addr);
1364 	printf("%stags address:     %x\n", p, hdr->tags_addr);
1365 	printf("%spage size:        %x\n", p, hdr->page_size);
1366 	printf("%sheader_version:   %x\n", p, header_version);
1367 	/* ver = A << 14 | B << 7 | C         (7 bits for each of A, B, C)
1368 	 * lvl = ((Y - 2000) & 127) << 4 | M  (7 bits for Y, 4 bits for M) */
1369 	printf("%sos_version:       %x (ver: %u.%u.%u, level: %u.%u)\n",
1370 	       p, hdr->os_version,
1371 	       (os_ver >> 7) & 0x7F, (os_ver >> 14) & 0x7F, os_ver & 0x7F,
1372 	       (os_lvl >> 4) + 2000, os_lvl & 0x0F);
1373 	printf("%sname:             %s\n", p, hdr->name);
1374 	printf("%scmdline:          %s\n", p, hdr->cmdline);
1375 
1376 	if (header_version == 1 || header_version == 2) {
1377 		printf("%srecovery dtbo size:    %x\n", p, hdr->recovery_dtbo_size);
1378 		printf("%srecovery dtbo offset:  %llx\n", p, hdr->recovery_dtbo_offset);
1379 		printf("%sheader size:           %x\n", p, hdr->header_size);
1380 	}
1381 
1382 	if (header_version == 2 || header_version == 3) {
1383 		printf("%sdtb size:              %x\n", p, hdr->dtb_size);
1384 		printf("%sdtb addr:              %llx\n", p, hdr->dtb_addr);
1385 	}
1386 
1387 	if (header_version >= 3) {
1388 		printf("%scmdline:               %s\n", p, hdr->total_cmdline);
1389 		printf("%svendor ramdisk size:   %x\n", p, hdr->vendor_ramdisk_size);
1390 		printf("%svendor page size:      %x\n", p, hdr->vendor_page_size);
1391 		printf("%svendor header version: %d\n", p, hdr->vendor_header_version);
1392 		printf("%svendor header size:    %x\n", p, hdr->vendor_header_size);
1393 	}
1394 
1395 	if (header_version >= 4) {
1396 		printf("%svendor ramdisk table size:        %x\n",
1397 		       p, hdr->vendor_ramdisk_table_size);
1398 		printf("%svendor ramdisk table entry num:   %x\n",
1399 		       p, hdr->vendor_ramdisk_table_entry_num);
1400 		printf("%svendor ramdisk table entry size:  %x\n",
1401 		       p, hdr->vendor_ramdisk_table_entry_size);
1402 		printf("%svendor bootconfig size:           %d\n",
1403 		       p, hdr->vendor_bootconfig_size);
1404 	}
1405 }
1406 #endif
1407