blob: 42aa4bbb6d3bce6248014cd1916d6f0989d0d85a [file] [log] [blame]
Bo Lv4a465022023-02-28 05:51:47 +00001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
4 */
5
6#include <common.h>
7#include <image.h>
8#include <android_image.h>
9#include <malloc.h>
10#include <errno.h>
11#include <version.h>
12#include <xbc.h>
13#include <amlogic/emmc_partitions.h>
14#include <amlogic/store_wrapper.h>
15
16static const unsigned char lzop_magic[] = {
17 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a
18};
19
20static bool _read_in_bootconfig(struct vendor_boot_img_hdr *boot_info, uint32_t ramdisk_size);
21
22#define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000
dongqing.li3d3670e2023-10-17 11:15:45 +080023#define BIG_TO_LITTLE(val) \
24 ((((val) >> 24) & 0x000000FF) | \
25 (((val) >> 8) & 0x0000FF00) | \
26 (((val) << 8) & 0x00FF0000) | \
27 (((val) << 24) & 0xFF000000))
Bo Lv4a465022023-02-28 05:51:47 +000028
Bo Lvda8d5b72023-07-31 14:58:21 +080029#if (defined CONFIG_SUPPORT_BL33Z) && (defined CONFIG_FULL_RAMDUMP)
30#define KNLIMG_DEC_ADDR 0x1880000
Bo Lv4a465022023-02-28 05:51:47 +000031#else
Bo Lvda8d5b72023-07-31 14:58:21 +080032#define KNLIMG_DEC_ADDR 0x1800000
Bo Lv4a465022023-02-28 05:51:47 +000033#endif
34
35static const unsigned char gzip_magic[] = {
36 0x1f, 0x8b
37};
38
39static const unsigned char lz4_magic[] = {
40 0x04, 0x22, 0x4d, 0x18
41};
42
Xindong Xub84a6622023-04-04 08:56:00 +080043static const unsigned char lz4_magic_android[] = {
44 0x02, 0x21, 0x4C, 0x18
45};
46
Tao Zeng0104a982024-04-09 12:29:35 +080047static const unsigned char zstd_magic[] = {
48 0x28, 0xb5, 0x2f, 0xfd
49};
50
Bo Lv4a465022023-02-28 05:51:47 +000051static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
52
53static struct {
54 const unsigned char * szID;
55 int nIDLength;
56 ulong nCompID;
57} arrComp[] = {
58 {lzop_magic,9,IH_COMP_LZO},
59 {gzip_magic,2,IH_COMP_GZIP},
Xindong Xub84a6622023-04-04 08:56:00 +080060 {lz4_magic, 4, IH_COMP_LZ4},
Tao Zeng0104a982024-04-09 12:29:35 +080061 {zstd_magic, 4, IH_COMP_ZSTD},
Xindong Xub84a6622023-04-04 08:56:00 +080062 {lz4_magic_android, 4, IH_COMP_LZ4_ANDROID}
Bo Lv4a465022023-02-28 05:51:47 +000063};
64
65/* android R*/
66static int android_image_get_kernel_v3(const boot_img_hdr_v3_t *hdr, int verify, ulong *os_data, ulong *os_len);
67static int android_image_need_move_v3(ulong *img_addr,const boot_img_hdr_v3_t *hdr);
68static ulong android_image_get_kload_v3(const boot_img_hdr_v3_t *hdr);
69static ulong android_image_get_comp_v3(const boot_img_hdr_v3_t *hdr);
70static ulong android_image_get_end_v3(const boot_img_hdr_v3_t *hdr);
71
72#ifdef CONFIG_OF_LIBFDT_OVERLAY
73static int save_dtbo_idx(const char *cmdline)
74{
75 char *dtbo_chosen_idx_start = NULL;
76 char *dtbo_chosen_idx_end = NULL;
77 char *dtbo_idx = NULL;
78
79 if (!env_get("androidboot.dtbo_idx")) {
80 if (!cmdline)
81 return -1;
82
83 dtbo_chosen_idx_start = strstr(cmdline, "androidboot.dtbo_idx");
84 if (!dtbo_chosen_idx_start) {
85 pr_info("No androidboot.dtbo_idx configured\n");
86 return -1;
87 }
88
89 dtbo_chosen_idx_end = strchr(dtbo_chosen_idx_start, ' ');
90 if (dtbo_chosen_idx_end) {
91 dtbo_idx = malloc(dtbo_chosen_idx_end -
92 dtbo_chosen_idx_start + 1);
93 if (!dtbo_idx) {
94 pr_info("dtbo out of memory\n");
95 return -1;
96 }
97 memset(dtbo_idx, 0x00,
98 dtbo_chosen_idx_end - dtbo_chosen_idx_start + 1);
99 strncpy(dtbo_idx, dtbo_chosen_idx_start,
100 dtbo_chosen_idx_end - dtbo_chosen_idx_start);
101 } else {
102 dtbo_idx = malloc(strlen(dtbo_chosen_idx_start) + 1);
103 if (!dtbo_idx) {
104 pr_info("dtbo out of memory\n");
105 return -1;
106 }
107 memset(dtbo_idx, 0x00,
108 strlen(dtbo_chosen_idx_start) + 1);
109 strncpy(dtbo_idx, dtbo_chosen_idx_start,
110 strlen(dtbo_chosen_idx_start));
111 }
112
113 env_set("androidboot.dtbo_idx",
114 dtbo_idx + strlen("androidboot.dtbo_idx="));
115 }
116
117 free(dtbo_idx);
118 return 0;
119}
120#endif
121
122int is_android_r_image(void *img_addr)
123{
124 /* check android version for R/S/etc */
125 p_boot_img_hdr_v3_t pHDR = (p_boot_img_hdr_v3_t)(img_addr);
126 return ((pHDR->header_version >= 3) ? 1 : 0);
127}
128
129static ulong android_image_get_kernel_addr(const boot_img_hdr_t *hdr)
130{
131 /*
132 * All the Android tools that generate a boot.img use this
133 * address as the default.
134 *
135 * Even though it doesn't really make a lot of sense, and it
136 * might be valid on some platforms, we treat that address as
137 * the default value for this field, and try to execute the
138 * kernel in place in such a case.
139 *
140 * Otherwise, we will return the actual value set by the user.
141 */
dongqing.li3d3670e2023-10-17 11:15:45 +0800142 image_header_t *legacy_hdr = NULL;
dongqing.li830569c2024-10-17 09:27:44 +0000143 unsigned int load_addr;
dongqing.li3d3670e2023-10-17 11:15:45 +0800144
145 legacy_hdr = (image_header_t *)((ulong)hdr + hdr->page_size);
dongqing.li830569c2024-10-17 09:27:44 +0000146 if (image_get_magic(legacy_hdr) == IH_MAGIC &&
147 legacy_hdr->ih_arch == IH_ARCH_ARM) {
dongqing.li3d3670e2023-10-17 11:15:45 +0800148 load_addr = BIG_TO_LITTLE(legacy_hdr->ih_load);
dongqing.li830569c2024-10-17 09:27:44 +0000149 pr_info("Get loadaddr from uImage legacy_hdr->ih_load=0x%08x.\n", load_addr);
150 return load_addr;
dongqing.li3d3670e2023-10-17 11:15:45 +0800151 }
152
dongqing.li830569c2024-10-17 09:27:44 +0000153 pr_info("It is not arm32 legacy_hdr, try using KNLIMG_DEC_ADDR=0x%08x.\n", KNLIMG_DEC_ADDR);
154#if defined(CONFIG_SUPPORT_BL33Z) && defined(CONFIG_FULL_RAMDUMP)
dongqing.li994a05e2023-10-17 09:19:27 +0800155 return KNLIMG_DEC_ADDR;
dongqing.li830569c2024-10-17 09:27:44 +0000156#endif
157 /*
158 * boot.img = boot_img_hdr_t + legacy_header + zImage + ramdisk.
159 * The hdr->kernel_addr is defined by BOARD_KERNEL_OFFSET in Android
160 * /device/.../BoardConfig.mk. Its value is typically 0x01080000.
161 * When TEXT_OFFSET is 0x02008000, loadaddr should be greater than
162 * the 0x01800000.
163 */
164 if (hdr->kernel_addr < KNLIMG_DEC_ADDR)
165 return KNLIMG_DEC_ADDR;
166
Bo Lv4a465022023-02-28 05:51:47 +0000167 if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR)
168 return (ulong)hdr + hdr->page_size;
169
170 return hdr->kernel_addr;
Bo Lv4a465022023-02-28 05:51:47 +0000171}
172
173/**
174 * android_image_get_kernel() - processes kernel part of Android boot images
175 * @hdr: Pointer to image header, which is at the start
176 * of the image.
177 * @verify: Checksum verification flag. Currently unimplemented.
178 * @os_data: Pointer to a ulong variable, will hold os data start
179 * address.
180 * @os_len: Pointer to a ulong variable, will hold os data length.
181 *
182 * This function returns the os image's start address and length. Also,
183 * it appends the kernel command line to the bootargs env variable.
184 *
185 * Return: Zero, os start address and length on success,
186 * otherwise on failure.
187 */
188int android_image_get_kernel(const boot_img_hdr_t *hdr, int verify,
189 ulong *os_data, ulong *os_len)
190{
191 if (is_android_r_image((void*)hdr))
192 return android_image_get_kernel_v3((void*)hdr,verify,os_data,os_len);
193
194 u32 kernel_addr = android_image_get_kernel_addr(hdr);
195
196 /*
197 * Not all Android tools use the id field for signing the image with
198 * sha1 (or anything) so we don't check it. It is not obvious that the
199 * string is null terminated so we take care of this.
200 */
201 strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE);
202 andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0';
203 if (strlen(andr_tmp_str))
204 pr_info("Android's image name: %s\n", andr_tmp_str);
205
206 pr_info("Kernel load addr 0x%08x size %u KiB\n",
207 kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024));
208
209 int len = 0;
210 if (*hdr->cmdline) {
211 pr_info("Kernel command line: %s\n", hdr->cmdline);
212 len += strlen(hdr->cmdline);
213 }
214
215#ifdef CONFIG_OF_LIBFDT_OVERLAY
216 save_dtbo_idx(hdr->cmdline);
217#endif
218 char *bootargs = env_get("bootargs");
219 if (bootargs)
220 len += strlen(bootargs);
221
222 char *newbootargs = malloc(len + 2);
223 if (!newbootargs) {
224 puts("Error: malloc in android_image_get_kernel failed!\n");
225 return -ENOMEM;
226 }
227 *newbootargs = '\0';
228
229 if (bootargs) {
230 strcpy(newbootargs, bootargs);
231 strcat(newbootargs, " ");
232 }
233 if (*hdr->cmdline)
234 strcat(newbootargs, hdr->cmdline);
235
236 env_set("bootargs", newbootargs);
237
238 if (os_data) {
239 *os_data = (ulong)hdr;
240 *os_data += hdr->page_size;
241 }
242 if (os_len)
243 *os_len = hdr->kernel_size;
244
245#if defined(CONFIG_ANDROID_BOOT_IMAGE)
246 ulong end;
247 images.ft_len = (ulong)(hdr->second_size);
248 end = (ulong)hdr;
249 end += hdr->page_size;
250 end += ALIGN(hdr->kernel_size, hdr->page_size);
251 images.rd_start = end;
252 end += ALIGN(hdr->ramdisk_size, hdr->page_size);
253 images.ft_addr = (char *)end;
254#endif
255
256 return 0;
257}
258
259int android_image_check_header(const boot_img_hdr_t *hdr)
260{
261 return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE);
262}
263
264int vendor_boot_image_check_header(const vendor_boot_img_hdr_t * hdr)
265{
266 return memcmp(VENDOR_BOOT_MAGIC, hdr->magic, VENDOR_BOOT_MAGIC_SIZE);
267}
268
269ulong android_image_get_end(const boot_img_hdr_t *hdr)
270{
271 if (is_android_r_image((void*)hdr))
272 return android_image_get_end_v3((void*)hdr);
273
274 ulong end;
275 /*
276 * The header takes a full page, the remaining components are aligned
277 * on page boundary
278 */
279 end = (ulong)hdr;
280 end += hdr->page_size;
281 end += ALIGN(hdr->kernel_size, hdr->page_size);
282 end += ALIGN(hdr->ramdisk_size, hdr->page_size);
283 end += ALIGN(hdr->second_size, hdr->page_size);
284
285 return end;
286}
287
288ulong android_image_get_kload(const boot_img_hdr_t *hdr)
289{
290 if (is_android_r_image((void*)hdr))
291 return android_image_get_kload_v3((void*)hdr);
292 else
293 return android_image_get_kernel_addr(hdr);
294}
295
296bool copy_bootconfig_to_cmdline(void)
297{
298 char *bootargs = env_get("bootargs");
299 char *bootconfig = env_get("bootconfig");
300
301 if (bootconfig && bootargs) {
302 int nlen = strlen(bootconfig) + strlen(bootargs) + 2;
303 char *pnewbootargs = malloc(nlen);
304
305 if (pnewbootargs) {
306 memset((void *)pnewbootargs, 0, nlen);
307 sprintf(pnewbootargs, "%s %s", bootargs, bootconfig);
308 env_set("bootargs", pnewbootargs);
309 free(pnewbootargs);
310 pnewbootargs = NULL;
311 }
312 }
313 return true;
314}
315
316int android_image_get_ramdisk_v3(const boot_img_hdr_v3_t *hdr,
317 ulong *rd_data, ulong *rd_len)
318{
319 /*boot image must contain ramdisk*/
320 unsigned ramdisksize;
321
322 if ((!hdr->ramdisk_size && init_boot_ramdisk_size == 0) || !p_vender_boot_img)
323 {
324 if (rd_data)
325 *rd_data = 0;
326 if (rd_len)
327 *rd_len = 0;
328 return -1;
329 }
330
331 p_vendor_boot_img_hdr_t vb_hdr = &p_vender_boot_img->hdr;
332#ifdef CONFIG_RAMDISK_MEM_ADDR
333 vb_hdr->ramdisk_addr = CONFIG_RAMDISK_MEM_ADDR;
334#endif
335
336 printf("RAM disk load addr 0x%08x size %u KiB\n",
337 vb_hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
338
339 /*ramdisk offset of android R boot image*/
340 int nOffset = (DIV_ROUND_UP(hdr->kernel_size,4096)+1)*4096;
341
342 unsigned char *pRAMdisk = (unsigned char *)(unsigned long)vb_hdr->ramdisk_addr;
343
344 if (init_boot_ramdisk_size != 0)
345 ramdisksize = init_boot_ramdisk_size;
346 else
347 ramdisksize = hdr->ramdisk_size;
348
349 /* copy ramdisk to ramdisk_addr */
350 if (init_boot_ramdisk_size != 0) {
351 printf("use init_boot.img\n");
352 debug("RAM disk load addr 0x%08x size %u KiB\n",
353 vb_hdr->ramdisk_addr, DIV_ROUND_UP(init_boot_ramdisk_size, 1024));
354 }
355
356 if (vb_hdr->header_version < 4) {
357 copy_bootconfig_to_cmdline();
358 memmove(pRAMdisk, (char *)(unsigned long)(simple_strtoul(env_get("loadaddr"),
359 NULL, 16) + nOffset), ramdisksize);
360 memmove(pRAMdisk + ramdisksize, p_vender_boot_img->szData,
361 vb_hdr->vendor_ramdisk_size);
362
363 if (rd_len)
364 *rd_len = ramdisksize + vb_hdr->vendor_ramdisk_size
365 + vb_hdr->vendor_bootconfig_size;
366 } else {
367 unsigned char *pbuffpreload = 0;
368 int i;
369 int table_offset;
370 int ramdisk_offset, ramdisk_size;
371 char *recovery_mode;
372 int flag = 0;
373
374 debug("vendor_ramdisk_table_size: 0x%x\n",
375 vb_hdr->vendor_ramdisk_table_size);
376 debug("vendor_ramdisk_table_entry_num: 0x%x\n",
377 vb_hdr->vendor_ramdisk_table_entry_num);
378 debug("vendor_ramdisk_table_entry_size: 0x%x\n",
379 vb_hdr->vendor_ramdisk_table_entry_size);
380
381 pbuffpreload = malloc(vb_hdr->vendor_ramdisk_table_size);
382 if (!pbuffpreload) {
383 printf("aml log: Fail to allocate memory!\n");
384 return -1;
385 }
386
387 u32 vramdisk_size_page_aligned =
388 ALIGN(vb_hdr->vendor_ramdisk_size, vb_hdr->page_size);
389 u32 vdtb_size_page_aligned =
390 ALIGN(vb_hdr->dtb_size, vb_hdr->page_size);
391
392 table_offset = vramdisk_size_page_aligned
393 + vdtb_size_page_aligned;
394 ramdisk_offset = 0;
395 ramdisk_size = vb_hdr->vendor_ramdisk_size;
396
397 memmove(pbuffpreload, p_vender_boot_img->szData + table_offset,
398 vb_hdr->vendor_ramdisk_table_size);
399
400 recovery_mode = env_get("recovery_mode");
401
402 for (i = 0; i < vb_hdr->vendor_ramdisk_table_entry_num; i++) {
403 p_vendor_ramdisk_table_entry_v4_t ramdisk_table =
404 (p_vendor_ramdisk_table_entry_v4_t)(pbuffpreload +
405 i * vb_hdr->vendor_ramdisk_table_entry_size);
406 printf("ramdisk_entry_name: %s\n", ramdisk_table->ramdisk_name);
407
408 if (strcmp((char *)ramdisk_table->ramdisk_name, "recovery") == 0) {
409 if (recovery_mode && (strcmp(recovery_mode, "true") == 0)) {
410 ramdisk_offset = ramdisk_table->ramdisk_offset;
411 ramdisk_size = ramdisk_table->ramdisk_size;
412 printf("use recovery ramdisk\n");
413 flag = 1;
414 } else {
415 printf("skip\n");
416 continue;
417 }
418 } else {
419 ramdisk_offset = ramdisk_table->ramdisk_offset;
420 ramdisk_size = ramdisk_table->ramdisk_size;
421 }
422 }
423
424 printf("ramdisk_size: 0x%x\n", ramdisk_size);
425 printf("ramdisk_offset: 0x%x\n", ramdisk_offset);
426
427 printf("flag = %d\n", flag);
428 if (flag == 0) {
429 memmove(pRAMdisk, (char *)(unsigned long)(simple_strtoul
430 (env_get("loadaddr"), NULL, 16)
431 + nOffset), ramdisksize);
432 memmove(pRAMdisk + ramdisksize,
433 p_vender_boot_img->szData + ramdisk_offset,
434 ramdisk_size);
435 _read_in_bootconfig(vb_hdr, ramdisksize + ramdisk_size);
436
437 if (rd_len)
438 *rd_len = ramdisksize + ramdisk_size
439 + vb_hdr->vendor_bootconfig_size;
440 } else {
441 printf("vendor_ramdisk_size: 0x%x\n", vb_hdr->vendor_ramdisk_size);
442 memmove(pRAMdisk, p_vender_boot_img->szData, vb_hdr->vendor_ramdisk_size);
443 _read_in_bootconfig(vb_hdr, vb_hdr->vendor_ramdisk_size);
444
445 if (rd_len)
446 *rd_len = vb_hdr->vendor_ramdisk_size
447 + vb_hdr->vendor_bootconfig_size;
448 }
449 free(pbuffpreload);
450 }
451
452 if (rd_data)
453 *rd_data = vb_hdr->ramdisk_addr;
454
455 return 0;
456}
457
458int android_image_get_ramdisk(const boot_img_hdr_t *hdr,
459 ulong *rd_data, ulong *rd_len)
460{
461 if (is_android_r_image((void*)hdr))
462 return android_image_get_ramdisk_v3((void*)hdr,rd_data,rd_len);
463 else
464 copy_bootconfig_to_cmdline();
465
466 if (!hdr->ramdisk_size) {
467 *rd_data = *rd_len = 0;
468 return -1;
469 }
470
471 pr_info("RAM disk load addr 0x%08x size %u KiB\n",
472 hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
473
474 *rd_data = (unsigned long)hdr;
475 *rd_data += hdr->page_size;
476 *rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
477
478 *rd_len = hdr->ramdisk_size;
479 return 0;
480}
481
482int android_image_get_second(const boot_img_hdr_t *hdr,
483 ulong *second_data, ulong *second_len)
484{
485 if (is_android_r_image((void*)hdr))
486 return 0;
487
488 if (!hdr->second_size) {
489 *second_data = *second_len = 0;
490 return -1;
491 }
492
493 *second_data = (unsigned long)hdr;
494 *second_data += hdr->page_size;
495 *second_data += ALIGN(hdr->kernel_size, hdr->page_size);
496 *second_data += ALIGN(hdr->ramdisk_size, hdr->page_size);
497
498 printf("second address is 0x%lx\n",*second_data);
499
500 *second_len = hdr->second_size;
501 return 0;
502}
503
504#if !defined(CONFIG_SPL_BUILD)
505/**
506 * android_print_contents - prints out the contents of the Android format image
507 * @hdr: pointer to the Android format image header
508 *
509 * android_print_contents() formats a multi line Android image contents
510 * description.
511 * The routine prints out Android image properties
512 *
513 * returns:
514 * no returned results
515 */
516void android_print_contents(const boot_img_hdr_t *hdr)
517{
518 const char * const p = IMAGE_INDENT_STRING;
519 /* os_version = ver << 11 | lvl */
520 u32 os_ver = hdr->os_version >> 11;
521 u32 os_lvl = hdr->os_version & ((1U << 11) - 1);
522
523 printf("%skernel size: %x\n", p, hdr->kernel_size);
524 printf("%skernel address: %x\n", p, hdr->kernel_addr);
525 printf("%sramdisk size: %x\n", p, hdr->ramdisk_size);
526 printf("%sramdisk address: %x\n", p, hdr->ramdisk_addr);
527 printf("%ssecond size: %x\n", p, hdr->second_size);
528 printf("%ssecond address: %x\n", p, hdr->second_addr);
529 printf("%stags address: %x\n", p, hdr->tags_addr);
530 printf("%spage size: %x\n", p, hdr->page_size);
531 /* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C)
532 * lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M) */
533 printf("%sos_version: %x (ver: %u.%u.%u, level: %u.%u)\n",
534 p, hdr->os_version,
535 (os_ver >> 7) & 0x7F, (os_ver >> 14) & 0x7F, os_ver & 0x7F,
536 (os_lvl >> 4) + 2000, os_lvl & 0x0F);
537 printf("%sname: %s\n", p, hdr->name);
538 printf("%scmdline: %s\n", p, hdr->cmdline);
539}
540#endif
541
542ulong android_image_get_comp(const boot_img_hdr_t *os_hdr)
543{
544 if (is_android_r_image((void*)os_hdr))
545 return android_image_get_comp_v3((void*)os_hdr);
546
547 int i;
548 unsigned char *src = (unsigned char *)os_hdr + os_hdr->page_size;
549 for (i = 0;i< ARRAY_SIZE(arrComp);++i)
550 {
551 if (!memcmp(arrComp[i].szID,src,arrComp[i].nIDLength))
552 return arrComp[i].nCompID;
553 }
554
555 return IH_COMP_NONE;
556}
557int android_image_need_move(ulong *img_addr, const boot_img_hdr_t *hdr)
558{
559 if (is_android_r_image((void*)hdr))
560 return android_image_need_move_v3(img_addr,(void*)hdr);
561
562 ulong kernel_load_addr = android_image_get_kload(hdr);
563 ulong img_start = *img_addr;
564 ulong val = 0;
565 if (kernel_load_addr > img_start)
566 val = kernel_load_addr - img_start;
567 else
568 val = img_start - kernel_load_addr;
569 if (android_image_get_comp(hdr) == IH_COMP_NONE)
570 return 0;
571 if (val < 32*1024*1024) {
572 ulong total_size = android_image_get_end(hdr)-(ulong)hdr;
573 void *reloc_addr = malloc(total_size);
574 if (!reloc_addr) {
575 puts("Error: malloc in android_image_need_move failed!\n");
576 return -ENOMEM;
577 }
578 printf("reloc_addr =%lx\n", (ulong)reloc_addr);
579 memset(reloc_addr, 0, total_size);
580 memmove(reloc_addr, hdr, total_size);
581 *img_addr = (ulong)reloc_addr;
582 printf("copy done\n");
583 }
584 return 0;
585}
586
587/*Android R boot func*/
588/* definition of vendor_boot partition structure */
589p_vendor_boot_img_t p_vender_boot_img = 0;
590unsigned init_boot_ramdisk_size;
591
592static int android_image_get_kernel_v3(const boot_img_hdr_v3_t *hdr, int verify,
593 ulong *os_data, ulong *os_len)
594{
595 /*
596 * Not all Android tools use the id field for signing the image with
597 * sha1 (or anything) so we don't check it. It is not obvious that the
598 * string is null terminated so we take care of this.
599 */
600 /*check vendor boot image first*/
601 if (p_vender_boot_img)
602 {
603 p_vendor_boot_img_hdr_t vb_hdr = &p_vender_boot_img->hdr;
604 char boot_name[ANDR_BOOT_NAME_SIZE + 8];
605
606 memset(boot_name, 0, sizeof(boot_name));
607 strncpy(boot_name, (char *)vb_hdr->name, ANDR_BOOT_NAME_SIZE);
608 if (strlen(boot_name))
609 printf("Android's image name: %s\n", boot_name);
610
611 //debug("Kernel load addr 0x%08x size %u KiB\n",
612 // hdr_v3->kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024));
613
614 int len = 0;
615#if defined(CONFIG_ANDROID_IMG)
616 ulong end;
617 ulong dtb_size = vb_hdr->dtb_size;
618 ulong dtb_addr = vb_hdr->dtb_addr;
619#endif
620
621 if (*vb_hdr->cmdline) {
622 printf("Kernel command line: %s\n", vb_hdr->cmdline);
623 len += strlen(vb_hdr->cmdline);
624 }
625
626 #ifdef CONFIG_OF_LIBFDT_OVERLAY
627 save_dtbo_idx(vb_hdr->cmdline);
628 #endif
629
630 char *pbootargs = env_get("bootargs");
631
632 if (pbootargs) {
633 int nlen = strlen(pbootargs) + len + 2;
634 char *pnewbootargs = malloc(nlen);
635
636 if (pnewbootargs) {
637 memset((void *)pnewbootargs, 0, nlen);
638 sprintf(pnewbootargs, "%s %s", pbootargs, vb_hdr->cmdline);
639 env_set("bootargs", pnewbootargs);
640 free(pnewbootargs);
641 pnewbootargs = NULL;
642 } else {
643 puts("Error: malloc in pnewbootargs failed!\n");
644 }
645 } else {
646 puts("Error: add kernel command line in bootargs failed!\n");
647 }
648
649 if (os_data) {
650 *os_data = (ulong)hdr;
651 *os_data += 0x1000; //android R header size
652 }
653 if (os_len)
654 *os_len = hdr->kernel_size;
655
656 #if defined(CONFIG_ANDROID_IMG)
657 images.ft_len = dtb_size;
658 end = dtb_addr;
659 images.ft_addr = (char *)end;
660 #endif
661 } else {
662 if (os_data)
663 *os_data = 0;
664 if (os_len)
665 *os_len = 0;
666 }
667 return 0;
668}
669
670
671void aml_u8_printf(void *pBuffer, int nSize)
672{
673 printf("aml log : dump buffer from addr=0x%x\n",(unsigned int)(unsigned long)pBuffer);
674
675 unsigned char *pData = (unsigned char *)pBuffer;
676 int nIndex = 0;
677
678 for (nIndex = 0; nIndex < nSize;++nIndex)
679 {
680 printf("%02x%s",pData[nIndex],
681 (nIndex + 1)%16 ? " ":"\n");
682 }
683
684 printf("\n");
685}
686
687static ulong android_image_get_end_v3(const boot_img_hdr_v3_t *hdr)
688{
689 if (!p_vender_boot_img)
690 return 0;
691
692 /*??*/
693 ulong end;
694 /*
695 * The header takes a full page, the remaining components are aligned
696 * on page boundary
697 */
698
699 end = (ulong)hdr;
700 end += 0x1000;
701 end += ALIGN(hdr->kernel_size, 0x1000);
702 end += ALIGN(hdr->ramdisk_size, 0x1000);
703 return end;
704}
705
706static ulong android_image_get_kload_v3(const boot_img_hdr_v3_t *hdr)
707{
708 if (p_vender_boot_img)
Bo Lvda8d5b72023-07-31 14:58:21 +0800709 return env_get_ulong("decaddr_kernel", 16, KNLIMG_DEC_ADDR);
Bo Lv4a465022023-02-28 05:51:47 +0000710 else
711 return 0;
712}
713
714
715
716static bool _read_in_bootconfig(struct vendor_boot_img_hdr *boot_info, uint32_t ramdisk_size)
717{
718#ifdef CONFIG_XBC
719 char *bootconfig = env_get("bootconfig");
720 char *avb_bootargs = env_get("avb_bootargs");
721
722 char partname[32] = {0};
723 char *slot_name;
724 unsigned int offset = 0;
725 int bootconfig_size = 0;
726 int ret = 0;
727
728 slot_name = env_get("slot-suffixes");
729 if (slot_name && (strcmp(slot_name, "0") == 0))
730 strcpy((char *)partname, "vendor_boot_a");
731 else if (slot_name && (strcmp(slot_name, "1") == 0))
732 strcpy((char *)partname, "vendor_boot_b");
733 else
734 strcpy((char *)partname, "vendor_boot");
735
736 unsigned char *pRAMdisk = (unsigned char *)(unsigned long)boot_info->ramdisk_addr;
737
738 printf("bootconfig_size: 0x%x\n", boot_info->vendor_bootconfig_size);
739
740 if (boot_info->vendor_bootconfig_size > 0) {
741 u32 vramdisk_size_page_aligned =
742 ALIGN(boot_info->vendor_ramdisk_size, boot_info->page_size);
743 u32 vdtb_size_page_aligned =
744 ALIGN(boot_info->dtb_size, boot_info->page_size);
745 u32 vramdisk_table_size_page_aligned =
746 ALIGN(boot_info->vendor_ramdisk_table_size, boot_info->page_size);
747
748 offset = 0x1000 + vramdisk_size_page_aligned
749 + vdtb_size_page_aligned
750 + vramdisk_table_size_page_aligned;
751
752 printf("bootconfig offset 0x%x\n", offset);
753
754 ret = store_logic_read(partname, offset, boot_info->vendor_bootconfig_size,
755 (void *)(pRAMdisk + ramdisk_size));
756 if (ret) {
757 printf("Fail to read 0x%xB from part[%s] at offset 0x%x\n",
758 boot_info->vendor_bootconfig_size, partname, offset);
759 return false;
760 }
761
762 bootconfig_size += boot_info->vendor_bootconfig_size;
763 } else {
764 // there is no bootconfig
765 printf("copy bootconfig to bootargs\n");
766 copy_bootconfig_to_cmdline();
767 }
768
769 if (bootconfig) {
770 int nlen = 0;
771
772 if (avb_bootargs)
773 nlen = strlen(bootconfig) + strlen(avb_bootargs) + 2;
774 else
775 nlen = strlen(bootconfig) + 2;
776
777 char *pnewbootargs = malloc(nlen);
778 char params[128];
779 char param_list[64][128];
780 int i = 0, j = 0, flag = 0;
781
782 if (pnewbootargs) {
783 memset((void *)pnewbootargs, 0, nlen);
784 if (avb_bootargs)
785 sprintf(pnewbootargs, "%s %s", bootconfig, avb_bootargs);
786 else
787 sprintf(pnewbootargs, "%s", bootconfig);
788
789 // Add any additional boot config parameters from the boot loader here. The
790 // final size of the boot config section will need to be tracked.
791 char *result = NULL;
792
793 result = strtok(pnewbootargs, " ");
794
795 while (result != NULL) {
796 sprintf(params, "%s\n", result);
797 for (i = 0; i < j; i++) {
798 if (strcmp(params, param_list[i]) == 0)
799 flag = 1;
800 }
801 if (flag != 1) {
802 strcpy(param_list[j], params);
803 j++;
804 ret = addBootConfigParameters(params, strlen(params),
805 boot_info->ramdisk_addr + ramdisk_size, bootconfig_size);
806 if (ret <= 0)
807 printf("Failed to apply boot config params\n");
808 else
809 bootconfig_size += ret;
810 } else {
811 flag = 0;
812 }
813 result = strtok(NULL, " ");
814 }
815 printf("bootconfig_size: 0x%x\n", bootconfig_size);
816 free(pnewbootargs);
817 pnewbootargs = NULL;
818 }
819 }
820
821 //Add bootconfig MAGIC
822 ret = addBootConfigTrailer(boot_info->ramdisk_addr + ramdisk_size,
823 bootconfig_size);
824 if (ret > 0)
825 bootconfig_size += ret;
826
827 printf("bootconfig_size: 0x%x\n", bootconfig_size);
828
829 // Need to update the size after adding parameters
830 boot_info->vendor_bootconfig_size = bootconfig_size;
831#else
832 printf("--- copy bootconfig to bootargs ---\n");
833 copy_bootconfig_to_cmdline();
834#endif
835 return true;
836}
837
838static ulong android_image_get_comp_v3(const boot_img_hdr_v3_t *os_hdr)
839{
840 int i;
Bo Lv65d86792024-08-30 11:02:03 +0800841 unsigned char *src = (unsigned char *)os_hdr + sizeof(boot_img_hdr_v3_t);
Bo Lv4a465022023-02-28 05:51:47 +0000842
843 for (i = 0;i< ARRAY_SIZE(arrComp);++i)
844 {
845 if (!memcmp(arrComp[i].szID,src,arrComp[i].nIDLength))
846 return arrComp[i].nCompID;
847 }
848
849 return IH_COMP_NONE;
850}
851
852static int android_image_need_move_v3(ulong *img_addr, const boot_img_hdr_v3_t *hdr)
853{
854 /*
855 Gzip format boot.img need relocate to high address.In order to quickly boot,so change load
856 decompress kernel address,when imgread load kernel at 0x3080000 and load decompress kernel
857 address is 0x1080000 needless to relocate,margin calculation is 32M.
858 */
859 ulong kernel_load_addr = android_image_get_kload_v3(hdr);
860 ulong img_start = *img_addr;
861 ulong val = 0;
862 if (kernel_load_addr > img_start)
863 val = kernel_load_addr - img_start;
864 else
865 val = img_start - kernel_load_addr;
866
867 if (android_image_get_comp_v3(hdr) == IH_COMP_NONE)
868 return 0;
869
870 if (val < 32*1024*1024) {
871 ulong total_size = android_image_get_end_v3(hdr)-(ulong)hdr;
872 void *reloc_addr = malloc(total_size);
873 if (!reloc_addr) {
874 puts("Error: malloc in android_image_need_move failed!\n");
875 return -ENOMEM;
876 }
877 printf("reloc_addr =%lx\n", (ulong)reloc_addr);
878 memset(reloc_addr, 0, total_size);
879 memmove(reloc_addr, hdr, total_size);
880 *img_addr = (ulong)reloc_addr;
881 printf("Copy done\n");
882 }
883 return 0;
884}