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