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