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