1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
9 #include <image-android-dt.h>
10 #include <android_image.h>
13 #include <asm/unaligned.h>
15 #include <linux/libfdt.h>
17 #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000
19 static char andr_tmp_str
[ANDR_BOOT_ARGS_SIZE
+ 1];
21 static ulong
android_image_get_kernel_addr(const struct andr_img_hdr
*hdr
)
24 * All the Android tools that generate a boot.img use this
25 * address as the default.
27 * Even though it doesn't really make a lot of sense, and it
28 * might be valid on some platforms, we treat that adress as
29 * the default value for this field, and try to execute the
30 * kernel in place in such a case.
32 * Otherwise, we will return the actual value set by the user.
34 if (hdr
->kernel_addr
== ANDROID_IMAGE_DEFAULT_KERNEL_ADDR
)
35 return (ulong
)hdr
+ hdr
->page_size
;
38 * abootimg creates images where all load addresses are 0
39 * and we need to fix them.
41 if (hdr
->kernel_addr
== 0 && hdr
->ramdisk_addr
== 0)
42 return env_get_ulong("kernel_addr_r", 16, 0);
44 return hdr
->kernel_addr
;
48 * android_image_get_kernel() - processes kernel part of Android boot images
49 * @hdr: Pointer to image header, which is at the start
51 * @verify: Checksum verification flag. Currently unimplemented.
52 * @os_data: Pointer to a ulong variable, will hold os data start
54 * @os_len: Pointer to a ulong variable, will hold os data length.
56 * This function returns the os image's start address and length. Also,
57 * it appends the kernel command line to the bootargs env variable.
59 * Return: Zero, os start address and length on success,
60 * otherwise on failure.
62 int android_image_get_kernel(const struct andr_img_hdr
*hdr
, int verify
,
63 ulong
*os_data
, ulong
*os_len
)
65 u32 kernel_addr
= android_image_get_kernel_addr(hdr
);
66 const struct legacy_img_hdr
*ihdr
= (const struct legacy_img_hdr
*)
67 ((uintptr_t)hdr
+ hdr
->page_size
);
70 * Not all Android tools use the id field for signing the image with
71 * sha1 (or anything) so we don't check it. It is not obvious that the
72 * string is null terminated so we take care of this.
74 strncpy(andr_tmp_str
, hdr
->name
, ANDR_BOOT_NAME_SIZE
);
75 andr_tmp_str
[ANDR_BOOT_NAME_SIZE
] = '\0';
76 if (strlen(andr_tmp_str
))
77 printf("Android's image name: %s\n", andr_tmp_str
);
79 printf("Kernel load addr 0x%08x size %u KiB\n",
80 kernel_addr
, DIV_ROUND_UP(hdr
->kernel_size
, 1024));
84 printf("Kernel command line: %s\n", hdr
->cmdline
);
85 len
+= strlen(hdr
->cmdline
);
88 char *bootargs
= env_get("bootargs");
90 len
+= strlen(bootargs
);
92 char *newbootargs
= malloc(len
+ 2);
94 puts("Error: malloc in android_image_get_kernel failed!\n");
100 strcpy(newbootargs
, bootargs
);
101 strcat(newbootargs
, " ");
104 strcat(newbootargs
, hdr
->cmdline
);
106 env_set("bootargs", newbootargs
);
109 if (image_get_magic(ihdr
) == IH_MAGIC
) {
110 *os_data
= image_get_data(ihdr
);
112 *os_data
= (ulong
)hdr
;
113 *os_data
+= hdr
->page_size
;
117 if (image_get_magic(ihdr
) == IH_MAGIC
)
118 *os_len
= image_get_data_size(ihdr
);
120 *os_len
= hdr
->kernel_size
;
125 int android_image_check_header(const struct andr_img_hdr
*hdr
)
127 return memcmp(ANDR_BOOT_MAGIC
, hdr
->magic
, ANDR_BOOT_MAGIC_SIZE
);
130 ulong
android_image_get_end(const struct andr_img_hdr
*hdr
)
135 * The header takes a full page, the remaining components are aligned
139 end
+= hdr
->page_size
;
140 end
+= ALIGN(hdr
->kernel_size
, hdr
->page_size
);
141 end
+= ALIGN(hdr
->ramdisk_size
, hdr
->page_size
);
142 end
+= ALIGN(hdr
->second_size
, hdr
->page_size
);
144 if (hdr
->header_version
>= 1)
145 end
+= ALIGN(hdr
->recovery_dtbo_size
, hdr
->page_size
);
147 if (hdr
->header_version
>= 2)
148 end
+= ALIGN(hdr
->dtb_size
, hdr
->page_size
);
153 ulong
android_image_get_kload(const struct andr_img_hdr
*hdr
)
155 return android_image_get_kernel_addr(hdr
);
158 ulong
android_image_get_kcomp(const struct andr_img_hdr
*hdr
)
160 const void *p
= (void *)((uintptr_t)hdr
+ hdr
->page_size
);
162 if (image_get_magic((struct legacy_img_hdr
*)p
) == IH_MAGIC
)
163 return image_get_comp((struct legacy_img_hdr
*)p
);
164 else if (get_unaligned_le32(p
) == LZ4F_MAGIC
)
167 return image_decomp_type(p
, sizeof(u32
));
170 int android_image_get_ramdisk(const struct andr_img_hdr
*hdr
,
171 ulong
*rd_data
, ulong
*rd_len
)
173 if (!hdr
->ramdisk_size
) {
174 *rd_data
= *rd_len
= 0;
178 printf("RAM disk load addr 0x%08x size %u KiB\n",
179 hdr
->ramdisk_addr
, DIV_ROUND_UP(hdr
->ramdisk_size
, 1024));
181 *rd_data
= (unsigned long)hdr
;
182 *rd_data
+= hdr
->page_size
;
183 *rd_data
+= ALIGN(hdr
->kernel_size
, hdr
->page_size
);
185 *rd_len
= hdr
->ramdisk_size
;
189 int android_image_get_second(const struct andr_img_hdr
*hdr
,
190 ulong
*second_data
, ulong
*second_len
)
192 if (!hdr
->second_size
) {
193 *second_data
= *second_len
= 0;
197 *second_data
= (unsigned long)hdr
;
198 *second_data
+= hdr
->page_size
;
199 *second_data
+= ALIGN(hdr
->kernel_size
, hdr
->page_size
);
200 *second_data
+= ALIGN(hdr
->ramdisk_size
, hdr
->page_size
);
202 printf("second address is 0x%lx\n",*second_data
);
204 *second_len
= hdr
->second_size
;
209 * android_image_get_dtbo() - Get address and size of recovery DTBO image.
210 * @hdr_addr: Boot image header address
211 * @addr: If not NULL, will contain address of recovery DTBO image
212 * @size: If not NULL, will contain size of recovery DTBO image
214 * Get the address and size of DTBO image in "Recovery DTBO" area of Android
215 * Boot Image in RAM. The format of this image is Android DTBO (see
216 * corresponding "DTB/DTBO Partitions" AOSP documentation for details). Once
217 * the address is obtained from this function, one can use 'adtimg' U-Boot
218 * command or android_dt_*() functions to extract desired DTBO blob.
220 * This DTBO (included in boot image) is only needed for non-A/B devices, and it
221 * only can be found in recovery image. On A/B devices we can always rely on
222 * "dtbo" partition. See "Including DTBO in Recovery for Non-A/B Devices" in
223 * AOSP documentation for details.
225 * Return: true on success or false on error.
227 bool android_image_get_dtbo(ulong hdr_addr
, ulong
*addr
, u32
*size
)
229 const struct andr_img_hdr
*hdr
;
233 hdr
= map_sysmem(hdr_addr
, sizeof(*hdr
));
234 if (android_image_check_header(hdr
)) {
235 printf("Error: Boot Image header is incorrect\n");
240 if (hdr
->header_version
< 1) {
241 printf("Error: header_version must be >= 1 to get dtbo\n");
246 if (hdr
->recovery_dtbo_size
== 0) {
247 printf("Error: recovery_dtbo_size is 0\n");
252 /* Calculate the address of DTB area in boot image */
253 dtbo_img_addr
= hdr_addr
;
254 dtbo_img_addr
+= hdr
->page_size
;
255 dtbo_img_addr
+= ALIGN(hdr
->kernel_size
, hdr
->page_size
);
256 dtbo_img_addr
+= ALIGN(hdr
->ramdisk_size
, hdr
->page_size
);
257 dtbo_img_addr
+= ALIGN(hdr
->second_size
, hdr
->page_size
);
260 *addr
= dtbo_img_addr
;
262 *size
= hdr
->recovery_dtbo_size
;
270 * android_image_get_dtb_img_addr() - Get the address of DTB area in boot image.
271 * @hdr_addr: Boot image header address
272 * @addr: Will contain the address of DTB area in boot image
274 * Return: true on success or false on fail.
276 static bool android_image_get_dtb_img_addr(ulong hdr_addr
, ulong
*addr
)
278 const struct andr_img_hdr
*hdr
;
282 hdr
= map_sysmem(hdr_addr
, sizeof(*hdr
));
283 if (android_image_check_header(hdr
)) {
284 printf("Error: Boot Image header is incorrect\n");
289 if (hdr
->header_version
< 2) {
290 printf("Error: header_version must be >= 2 to get dtb\n");
295 if (hdr
->dtb_size
== 0) {
296 printf("Error: dtb_size is 0\n");
301 /* Calculate the address of DTB area in boot image */
302 dtb_img_addr
= hdr_addr
;
303 dtb_img_addr
+= hdr
->page_size
;
304 dtb_img_addr
+= ALIGN(hdr
->kernel_size
, hdr
->page_size
);
305 dtb_img_addr
+= ALIGN(hdr
->ramdisk_size
, hdr
->page_size
);
306 dtb_img_addr
+= ALIGN(hdr
->second_size
, hdr
->page_size
);
307 dtb_img_addr
+= ALIGN(hdr
->recovery_dtbo_size
, hdr
->page_size
);
309 *addr
= dtb_img_addr
;
317 * android_image_get_dtb_by_index() - Get address and size of blob in DTB area.
318 * @hdr_addr: Boot image header address
319 * @index: Index of desired DTB in DTB area (starting from 0)
320 * @addr: If not NULL, will contain address to specified DTB
321 * @size: If not NULL, will contain size of specified DTB
323 * Get the address and size of DTB blob by its index in DTB area of Android
326 * Return: true on success or false on error.
328 bool android_image_get_dtb_by_index(ulong hdr_addr
, u32 index
, ulong
*addr
,
331 const struct andr_img_hdr
*hdr
;
333 ulong dtb_img_addr
; /* address of DTB part in boot image */
334 u32 dtb_img_size
; /* size of DTB payload in boot image */
335 ulong dtb_addr
; /* address of DTB blob with specified index */
336 u32 i
; /* index iterator */
338 res
= android_image_get_dtb_img_addr(hdr_addr
, &dtb_img_addr
);
342 /* Check if DTB area of boot image is in DTBO format */
343 if (android_dt_check_header(dtb_img_addr
)) {
344 return android_dt_get_fdt_by_index(dtb_img_addr
, index
, addr
,
348 /* Find out the address of DTB with specified index in concat blobs */
349 hdr
= map_sysmem(hdr_addr
, sizeof(*hdr
));
350 dtb_img_size
= hdr
->dtb_size
;
353 dtb_addr
= dtb_img_addr
;
354 while (dtb_addr
< dtb_img_addr
+ dtb_img_size
) {
355 const struct fdt_header
*fdt
;
358 fdt
= map_sysmem(dtb_addr
, sizeof(*fdt
));
359 if (fdt_check_header(fdt
) != 0) {
361 printf("Error: Invalid FDT header for index %u\n", i
);
365 dtb_size
= fdt_totalsize(fdt
);
376 dtb_addr
+= dtb_size
;
380 printf("Error: Index is out of bounds (%u/%u)\n", index
, i
);
384 #if !defined(CONFIG_SPL_BUILD)
386 * android_print_contents - prints out the contents of the Android format image
387 * @hdr: pointer to the Android format image header
389 * android_print_contents() formats a multi line Android image contents
391 * The routine prints out Android image properties
394 * no returned results
396 void android_print_contents(const struct andr_img_hdr
*hdr
)
398 const char * const p
= IMAGE_INDENT_STRING
;
399 /* os_version = ver << 11 | lvl */
400 u32 os_ver
= hdr
->os_version
>> 11;
401 u32 os_lvl
= hdr
->os_version
& ((1U << 11) - 1);
403 printf("%skernel size: %x\n", p
, hdr
->kernel_size
);
404 printf("%skernel address: %x\n", p
, hdr
->kernel_addr
);
405 printf("%sramdisk size: %x\n", p
, hdr
->ramdisk_size
);
406 printf("%sramdisk address: %x\n", p
, hdr
->ramdisk_addr
);
407 printf("%ssecond size: %x\n", p
, hdr
->second_size
);
408 printf("%ssecond address: %x\n", p
, hdr
->second_addr
);
409 printf("%stags address: %x\n", p
, hdr
->tags_addr
);
410 printf("%spage size: %x\n", p
, hdr
->page_size
);
411 /* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C)
412 * lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M) */
413 printf("%sos_version: %x (ver: %u.%u.%u, level: %u.%u)\n",
415 (os_ver
>> 7) & 0x7F, (os_ver
>> 14) & 0x7F, os_ver
& 0x7F,
416 (os_lvl
>> 4) + 2000, os_lvl
& 0x0F);
417 printf("%sname: %s\n", p
, hdr
->name
);
418 printf("%scmdline: %s\n", p
, hdr
->cmdline
);
419 printf("%sheader_version: %d\n", p
, hdr
->header_version
);
421 if (hdr
->header_version
>= 1) {
422 printf("%srecovery dtbo size: %x\n", p
,
423 hdr
->recovery_dtbo_size
);
424 printf("%srecovery dtbo offset: %llx\n", p
,
425 hdr
->recovery_dtbo_offset
);
426 printf("%sheader size: %x\n", p
,
430 if (hdr
->header_version
>= 2) {
431 printf("%sdtb size: %x\n", p
, hdr
->dtb_size
);
432 printf("%sdtb addr: %llx\n", p
, hdr
->dtb_addr
);
437 * android_image_print_dtb_info - Print info for one DTB blob in DTB area.
439 * @index: Number of DTB blob in DTB area.
441 * Return: true on success or false on error.
443 static bool android_image_print_dtb_info(const struct fdt_header
*fdt
,
449 const char *compatible
;
451 root_node_off
= fdt_path_offset(fdt
, "/");
452 if (root_node_off
< 0) {
453 printf("Error: Root node not found\n");
457 fdt_size
= fdt_totalsize(fdt
);
458 compatible
= fdt_getprop(fdt
, root_node_off
, "compatible",
460 model
= fdt_getprop(fdt
, root_node_off
, "model", NULL
);
462 printf(" - DTB #%u:\n", index
);
463 printf(" (DTB)size = %d\n", fdt_size
);
464 printf(" (DTB)model = %s\n", model
? model
: "(unknown)");
465 printf(" (DTB)compatible = %s\n",
466 compatible
? compatible
: "(unknown)");
472 * android_image_print_dtb_contents() - Print info for DTB blobs in DTB area.
473 * @hdr_addr: Boot image header address
475 * DTB payload in Android Boot Image v2+ can be in one of following formats:
476 * 1. Concatenated DTB blobs
477 * 2. Android DTBO format (see CONFIG_CMD_ADTIMG for details)
479 * This function does next:
480 * 1. Prints out the format used in DTB area
481 * 2. Iterates over all DTB blobs in DTB area and prints out the info for
484 * Return: true on success or false on error.
486 bool android_image_print_dtb_contents(ulong hdr_addr
)
488 const struct andr_img_hdr
*hdr
;
490 ulong dtb_img_addr
; /* address of DTB part in boot image */
491 u32 dtb_img_size
; /* size of DTB payload in boot image */
492 ulong dtb_addr
; /* address of DTB blob with specified index */
493 u32 i
; /* index iterator */
495 res
= android_image_get_dtb_img_addr(hdr_addr
, &dtb_img_addr
);
499 /* Check if DTB area of boot image is in DTBO format */
500 if (android_dt_check_header(dtb_img_addr
)) {
501 printf("## DTB area contents (DTBO format):\n");
502 android_dt_print_contents(dtb_img_addr
);
506 printf("## DTB area contents (concat format):\n");
508 /* Iterate over concatenated DTB blobs */
509 hdr
= map_sysmem(hdr_addr
, sizeof(*hdr
));
510 dtb_img_size
= hdr
->dtb_size
;
513 dtb_addr
= dtb_img_addr
;
514 while (dtb_addr
< dtb_img_addr
+ dtb_img_size
) {
515 const struct fdt_header
*fdt
;
518 fdt
= map_sysmem(dtb_addr
, sizeof(*fdt
));
519 if (fdt_check_header(fdt
) != 0) {
521 printf("Error: Invalid FDT header for index %u\n", i
);
525 res
= android_image_print_dtb_info(fdt
, i
);
531 dtb_size
= fdt_totalsize(fdt
);
533 dtb_addr
+= dtb_size
;