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