blob: 8c9d82398be0a0750087d09b9f9b9cc6a91b2137 [file] [log] [blame]
Bo Lv72d0e902023-01-02 14:27:34 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <config.h>
7#include <common.h>
8#include <image.h>
Bo Lv52186632024-02-22 16:32:44 +08009#include <linux/compat.h>
Bo Lv72d0e902023-01-02 14:27:34 +000010#include <linux/libfdt.h>
11#include <android_image.h>
12#if defined(CONFIG_ZIRCON_BOOT_IMAGE)
Bo Lv6170c3e2023-04-04 10:56:51 +080013#include <amlogic/zircon/image.h>
Bo Lv72d0e902023-01-02 14:27:34 +000014#endif
Bo Lv4a465022023-02-28 05:51:47 +000015#include <asm/amlogic/arch/bl31_apis.h>
16#include <asm/amlogic/arch/secure_apb.h>
Bo Lv72d0e902023-01-02 14:27:34 +000017#include <amlogic/store_wrapper.h>
18#include <amlogic/aml_efuse.h>
19#include <malloc.h>
Bo Lv4a465022023-02-28 05:51:47 +000020#include <amlogic/emmc_partitions.h>
Bo Lv72d0e902023-01-02 14:27:34 +000021#include <version.h>
22#include <amlogic/image_check.h>
23#include <fs.h>
Bo Lv4a465022023-02-28 05:51:47 +000024#include <gzip.h>
Mingyen Hung96effce2023-09-01 00:39:46 -070025#if CONFIG_PARTITION_ENCRYPTION_LOCAL
26#include <amlogic/partition_encryption.h>
27#endif
Matthew Shyu837ffa52024-05-03 01:59:44 -070028#ifdef CONFIG_AVB2
29#include <amlogic/libavb/libavb.h>
30#endif
Meng yufceeb992024-08-06 11:34:39 +080031#include <amlogic/aml_profile.h>
Bo Lv72d0e902023-01-02 14:27:34 +000032
33#ifndef IS_FEAT_BOOT_VERIFY
34//#define IS_FEAT_BOOT_VERIFY() 0 //always undefined as IS_FEAT_BOOT_VERIFY is function not marco
35#endif// #ifndef IS_FEAT_BOOT_VERIFY
36int __attribute__((weak)) store_logic_read(const char *name, loff_t off, size_t size, void *buf)
37{ return store_read(name, off, size, buf);}
38
39#define debugP(fmt...) //printf("[Dbg imgread]L%d:", __LINE__),printf(fmt)
40#define errorP(fmt...) do {pr_err("Err imgread(L%d):", __LINE__); pr_err(fmt); } while (0)
Matthew Shyu837ffa52024-05-03 01:59:44 -070041#define wrnP(fmt...) pr_warn("wrn:" fmt)
Bo Lv72d0e902023-01-02 14:27:34 +000042#define MsgP(fmt...) pr_info("[imgread]" fmt)
43
44#define IMG_PRELOAD_SZ (1U<<20) //Total read 1M at first to read the image header
45#define PIC_PRELOAD_SZ (8U<<10) //Total read 4k at first to read the image header
46#define RES_OLD_FMT_READ_SZ (8U<<20)
47
Bo Lv52186632024-02-22 16:32:44 +080048#define MAX_RAMDISK_SIZE SZ_64M
49#define MAX_KERNEL_SIZE SZ_64M
50#define MAX_DTB_SIZE SZ_16M
51
Bo Lv72d0e902023-01-02 14:27:34 +000052typedef struct __aml_enc_blk{
53 unsigned int nOffset;
54 unsigned int nRawLength;
55 unsigned int nSigLength;
56 unsigned int nAlignment;
57 unsigned int nTotalLength;
58 unsigned char szPad[12];
59 unsigned char szSHA2IMG[32];
60 unsigned char szSHA2KeyID[32];
61}t_aml_enc_blk;
62
63#define AML_SECU_BOOT_IMG_HDR_MAGIC "AMLSECU!"
64#define AML_SECU_BOOT_IMG_HDR_MAGIC_SIZE (8)
65#define AML_SECU_BOOT_IMG_HDR_VESRION (0x0905)
66
67typedef struct {
68
69 unsigned char magic[AML_SECU_BOOT_IMG_HDR_MAGIC_SIZE];//magic to identify whether it is a encrypted boot image
70
71 unsigned int version; //version for this header struct
72 unsigned int nBlkCnt;
73
74 unsigned char szTimeStamp[16];
75
76 t_aml_enc_blk amlKernel;
77 t_aml_enc_blk amlRamdisk;
78 t_aml_enc_blk amlDTB;
79
80} amlencryptbootimginfo;
81
82typedef struct _boot_img_hdr_secure_boot
83{
84 unsigned char reserve4ImgHdr[1024];
85
86 amlencryptbootimginfo encrypteImgInfo;
87
88}AmlSecureBootImgHeader;
89
90typedef struct{
91 unsigned char reserve4ImgHdr[2048];
92
93 amlencryptbootimginfo encrypteImgInfo;
94
95}AmlSecureBootImg9Header;
96
97
98#define COMPILE_TYPE_ASSERT(expr, t) typedef char t[(expr) ? 1 : -1]
99COMPILE_TYPE_ASSERT(2048 >= sizeof(AmlSecureBootImgHeader), _cc);
100
101static int is_andr_9_image(void* pBuffer)
102{
103 boot_img_hdr_t *pAHdr = (boot_img_hdr_t *)(unsigned long)pBuffer;
104 int nReturn = 0;
105
106 if (!pBuffer)
107 goto exit;
108
109 if (pAHdr->header_version)
110 nReturn = 1;
111
112exit:
113
114 return nReturn;
115
116}
117
118static int _aml_get_secure_boot_kernel_size(const void *ploadaddr, u32 *ptotalenckernelsz)
119{
120 const amlencryptbootimginfo *amlencryptebootimginfo = 0;
121 int rc = 0;
122 u32 securekernelimgsz = 2048;
123 u32 nblkcnt = 0;
124 const t_aml_enc_blk *pblkinf = NULL;
125 int secure_boot_enabled = 0;
126 unsigned char *pandhdr = (unsigned char *)ploadaddr;
127
128#ifdef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
129 secure_boot_enabled = 0;//donnot decrypt kernel/dtb if avb2 enabled
130#else
131 secure_boot_enabled = IS_FEAT_BOOT_VERIFY();
132#endif//#ifdef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
133
134#ifdef CONFIG_IMAGE_CHECK
135 rc = __LINE__;
136
137 if (!ploadaddr || !ptotalenckernelsz)
138 return rc;
139
140 if (secure_boot_enabled) {
141 struct aml_boot_header_t *hdr;
142 ulong ncheckoffset = android_image_check_offset();
143
144 hdr = (struct aml_boot_header_t *)(pandhdr + ncheckoffset
145 - sizeof(struct aml_boot_header_t));
146 if (hdr->magic != AML_BOOT_IMAGE_MAGIC || hdr->version != AML_BOOT_IMAGE_VERSION)
147 return rc;
148 *ptotalenckernelsz = hdr->img_size + ncheckoffset;
149 return 0;
150 }
151
152 *ptotalenckernelsz = 0;
153#endif
154 if (is_andr_9_image(pandhdr))
155 securekernelimgsz = 4096;
156
157 amlencryptebootimginfo = (amlencryptbootimginfo *)(pandhdr + (securekernelimgsz >> 1));
158
159 nblkcnt = amlencryptebootimginfo->nBlkCnt;
160
161 *ptotalenckernelsz = 0;
162
163 rc = memcmp(AML_SECU_BOOT_IMG_HDR_MAGIC, amlencryptebootimginfo->magic,
164 AML_SECU_BOOT_IMG_HDR_MAGIC_SIZE);
165 if (rc) { // img NOT signed
166 if (secure_boot_enabled) {
167 errorP("img NOT signed but secure boot enabled\n");
168 return __LINE__;
169 }
170 *ptotalenckernelsz = 0;
171 return 0;
172 }
173 //img signed
174 if (!secure_boot_enabled) {
175 errorP("Img signed but secure boot NOT enabled\n");
176 return __LINE__;
177 }
178
179 if (amlencryptebootimginfo->version != AML_SECU_BOOT_IMG_HDR_VESRION) {
180 errorP("magic ok but version err, err ver=0x%x\n", amlencryptebootimginfo->version);
181 return __LINE__;
182 }
183 MsgP("szTimeStamp[%s]\n", (char *)&amlencryptebootimginfo->szTimeStamp);
184 debugP("nblkcnt=%d\n", nblkcnt);
185
186 for (pblkinf = &amlencryptebootimginfo->amlKernel; nblkcnt--; ++pblkinf) {
187 const unsigned int thisblklen = pblkinf->nTotalLength;
188
189 debugP("thisblklen=0x%x\n", thisblklen);
190 securekernelimgsz += thisblklen;
191 }
192
193 *ptotalenckernelsz = securekernelimgsz;
194 return 0;
195}
196
197static int do_image_read_dtb_from_knl(const char *partname,
198 unsigned char *loadaddr, uint64_t lflashreadinitoff)
199{
200 int ret = __LINE__;
201 unsigned int nflashloadlen = 0;
202 u64 lflashreadoff = 0;
203 const int preloadsz = 4096 * 2;
Bo Lv52186632024-02-22 16:32:44 +0800204 unsigned int pagesz = 0;
Bo Lv72d0e902023-01-02 14:27:34 +0000205 boot_img_hdr_t *hdr_addr = (boot_img_hdr_t *)loadaddr;
206
207 lflashreadoff = lflashreadinitoff;
208 nflashloadlen = preloadsz;//head info is one page size == 2k
209 debugP("sizeof preloadsz=%u\n", nflashloadlen);
210 ret = store_logic_read(partname, lflashreadoff, nflashloadlen, loadaddr);
211 if (ret) {
212 errorP("Fail to read 0x%xB from part[%s] at offset 0\n", nflashloadlen, partname);
213 return __LINE__;
214 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700215#if CONFIG_PARTITION_ENCRYPTION_LOCAL
216 part_dec(partname, (u8*)loadaddr, nflashloadlen, (u8*)loadaddr, nflashloadlen, lflashreadoff);
217#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000218 if (genimg_get_format(hdr_addr) != IMAGE_FORMAT_ANDROID) {
219 errorP("Fmt unsupported! only support 0x%x\n", IMAGE_FORMAT_ANDROID);
220 return __LINE__;
221 }
222
223 if (is_android_r_image((void *)hdr_addr)) {
224 const int preloadsz_r = preloadsz;
225 int rc_r = 0;
226 char *slot_name;
227
228 slot_name = env_get("slot-suffixes");
229 if (strcmp(slot_name, "0") == 0)
230 strcpy((char *)partname, "vendor_boot_a");
231 else if (strcmp(slot_name, "1") == 0)
232 strcpy((char *)partname, "vendor_boot_b");
233 else
234 strcpy((char *)partname, "vendor_boot");
235
236 MsgP("partname = %s\n", partname);
237 nflashloadlen = preloadsz_r;//head info is one page size == 4k
238 debugP("sizeof preloadSz=%u\n", nflashloadlen);
239
240 ret = store_logic_read(partname, lflashreadoff, nflashloadlen, loadaddr);
241 if (ret) {
242 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
243 nflashloadlen, partname);
244 return __LINE__;
245 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700246#if CONFIG_PARTITION_ENCRYPTION_LOCAL
247 part_dec(partname, (u8*)loadaddr, nflashloadlen, (u8*)loadaddr, nflashloadlen, lflashreadoff);
248#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000249 p_vendor_boot_img_hdr_t pvendorimghdr = (p_vendor_boot_img_hdr_t)loadaddr;
250
251 rc_r = vendor_boot_image_check_header(pvendorimghdr);
252 if (!rc_r) {
253 unsigned long ramdisk_size_r, dtb_size_r;
254
255 pagesz = pvendorimghdr->page_size;
256
257 /* Android R's vendor_boot partition include ramdisk and dtb */
258 ramdisk_size_r = ALIGN(pvendorimghdr->vendor_ramdisk_size, pagesz);
259 dtb_size_r = ALIGN(pvendorimghdr->dtb_size, pagesz);
260 nflashloadlen = dtb_size_r;
261 lflashreadoff = ramdisk_size_r + 0x1000;
262 debugP("ramdisk_size_r 0x%x, totalSz 0x%lx\n",
263 pvendorimghdr->vendor_ramdisk_size, ramdisk_size_r);
264 debugP("dtb_size_r 0x%x, totalSz 0x%lx\n",
265 pvendorimghdr->dtb_size, dtb_size_r);
266 debugP("lflashreadoff=0x%llx\n", lflashreadoff);
267 debugP("nflashloadlen=0x%x\n", nflashloadlen);
268 } else {
269 errorP("check vendor_boot header error\n");
270 return __LINE__;
271 }
272
273 } else {
274 pagesz = hdr_addr->page_size;
275 lflashreadoff += pagesz;
276 lflashreadoff += ALIGN(hdr_addr->kernel_size, pagesz);
277 lflashreadoff += ALIGN(hdr_addr->ramdisk_size, pagesz);
278 nflashloadlen = ALIGN(hdr_addr->second_size, pagesz);
279 }
280
281 debugP("lflashreadoff=0x%llx, nflashloadlen=0x%x\n", lflashreadoff, nflashloadlen);
282 debugP("page sz %u\n", hdr_addr->page_size);
Bo Lv52186632024-02-22 16:32:44 +0800283
284 if (pagesz > PAGE_SIZE) {
285 errorP("Wrong pagesz:%d\n", pagesz);
Bo Lv72d0e902023-01-02 14:27:34 +0000286 return __LINE__;
287 }
Bo Lv52186632024-02-22 16:32:44 +0800288 if (!nflashloadlen || nflashloadlen > MAX_DTB_SIZE) {
289 errorP("Wrong nflashloadlen:%d\n", nflashloadlen);
290 return __LINE__;
291 }
292 if (lflashreadoff > (MAX_RAMDISK_SIZE + MAX_KERNEL_SIZE)) {
293 errorP("Wrong lflashreadoff:%lld\n", lflashreadoff);
294 return __LINE__;
295 }
296
Bo Lv72d0e902023-01-02 14:27:34 +0000297 unsigned char *secondaddr = (unsigned char *)loadaddr + lflashreadoff;
298
299 loff_t wroff = lflashreadoff;
300 size_t wrsz = nflashloadlen;
301 unsigned char *wraddr = secondaddr;
302#if !defined(CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK) && defined(CONFIG_IMAGE_CHECK)
303 u32 securekernelimgsz = 0;
304
305 ret = _aml_get_secure_boot_kernel_size(loadaddr, &securekernelimgsz);
306 if (ret) {
307 errorP("Fail in _aml_get_secure_boot_kernel_size, rc=%d\n", ret);
308 return __LINE__;
309 }
310
311 if (securekernelimgsz) {
312 debugP("secure kernel sz 0x%x\n", securekernelimgsz);
313 wrsz = securekernelimgsz - preloadsz;
314 wroff = lflashreadinitoff + preloadsz;
315 wraddr = (unsigned char *)loadaddr + preloadsz;
316 }
317#endif//#if !defined(CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK) && defined(CONFIG_IMAGE_CHECK)
318 if ((BOOT_NAND_MTD == store_get_type() || BOOT_SNAND == store_get_type())) {
319 unsigned notAlignSz = wroff & 0xfff;
320
321 wroff -= notAlignSz;
322 wrsz += notAlignSz;
323 secondaddr += notAlignSz;
324 MsgP("not align dtb off 0x%llx\n", wroff);
325 }
326 ret = store_logic_read(partname, wroff, wrsz, wraddr);
327 if (ret) {
328 errorP("Fail to read 0x%xB from part[%s] at offset 0x%x\n",
329 (unsigned int)wrsz, partname, (unsigned int)wroff);
330 return __LINE__;
331 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700332#if CONFIG_PARTITION_ENCRYPTION_LOCAL
333 part_dec(partname, (u8*)wraddr, wrsz, (u8*)wraddr, wrsz, wroff);
334#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000335#ifndef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
336 if (IS_FEAT_BOOT_VERIFY()) {
337#ifndef CONFIG_IMAGE_CHECK
338 //because secure boot will use DMA which need disable MMU temp
339 //here must update the cache, otherwise nand will fail (eMMC is OK)
340 flush_cache((unsigned long)secondaddr, (unsigned long)nflashloadlen);
341
342 ret = aml_sec_boot_check(AML_D_P_IMG_DECRYPT, (unsigned long)loadaddr,
343 GXB_IMG_SIZE, GXB_IMG_DEC_DTB);
344#else
345 //because secure boot will use DMA which need disable MMU temp
346 //here must update the cache, otherwise nand will fail (eMMC is OK)
347 flush_cache((unsigned long)loadaddr, (unsigned long)securekernelimgsz);
348
349 ret = secure_image_check((uint8_t *)(unsigned long)loadaddr,
350 GXB_IMG_SIZE, GXB_IMG_DEC_DTB);
351 secondaddr += android_image_check_offset();
352#endif
353 if (ret) {
354 errorP("\n[dtb]aml log : Sig Check is %d\n", ret);
355 return __LINE__;
356 }
357 MsgP("decrypted dtb sz 0x%x\n", nflashloadlen);
358 }
359#endif
360 char *dtdestaddr = (char *)loadaddr;//simple_strtoull(getenv("dtb_mem_addr"), NULL, 0);
361
362 memmove(dtdestaddr, secondaddr, nflashloadlen);
363
364 return ret;
365}
366
367/*uint32_t store_rsv_size(const char *name);*/
368static int do_image_read_dtb_from_rsv(unsigned char* loadaddr)
369{
370 const int dtbmaxsz = store_rsv_size("dtb");
371
372 if (dtbmaxsz < 0x400) {
373 errorP("dtbmaxsz(0x%x) invalid\n", dtbmaxsz);
374 return -__LINE__;
375 }
376 int ret = store_rsv_read("dtb", dtbmaxsz, loadaddr);
377
378 if (ret) {
379 errorP("Fail read dtb from rsv with sz 0x%x\n", dtbmaxsz);
380 return -__LINE__;
381 }
382#ifndef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
383 if (IS_FEAT_BOOT_VERIFY()) {
384 flush_cache((unsigned long)loadaddr, dtbmaxsz);
385#ifndef CONFIG_IMAGE_CHECK
386 ret = aml_sec_boot_check(AML_D_P_IMG_DECRYPT, (long)loadaddr, dtbmaxsz, 0);
387#else
388 ret = secure_image_check((uint8_t *)(unsigned long)loadaddr, dtbmaxsz, 0);
389 memmove(loadaddr, (void *)(loadaddr + sizeof(struct aml_boot_header_t)), dtbmaxsz);
390#endif
391 if (ret) {
392 MsgP("decrypt dtb: Sig Check %d\n", ret);
393 return -__LINE__;
394 }
395 }
396#endif
397 return 0;
398}
399
400//imgread dtb boot ${dtb_mem_addr}
401//imgread dtb rsv ${dtb_mem_addr}
402static int do_image_read_dtb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
403{
404 int iRet = 0;
Sam Wu6f3d40e2023-04-22 01:10:27 +0800405 const char partName[64] = {0};
Bo Lv72d0e902023-01-02 14:27:34 +0000406 unsigned char* loadaddr = 0;
407 uint64_t lflashReadOff = 0;
Sam Wu6f3d40e2023-04-22 01:10:27 +0800408
409 strlcpy((char *)partName, argv[1], 64);
Bo Lv72d0e902023-01-02 14:27:34 +0000410 if (2 < argc) {
411 loadaddr = (unsigned char*)simple_strtoul(argv[2], NULL, 16);
412 } else{
413 loadaddr = (unsigned char*)simple_strtoul(env_get("loadaddr"), NULL, 16);
414 }
415
416 if (3 < argc) lflashReadOff = simple_strtoull(argv[3], NULL, 0) ;
417
418 const int fromRsv = !strcmp("_aml_dtb", argv[1]);
419 if ( fromRsv ) {
420 iRet = do_image_read_dtb_from_rsv(loadaddr);
421 } else {
422 iRet = do_image_read_dtb_from_knl(partName, loadaddr, lflashReadOff);
423 }
424 if (iRet) {
425 errorP("Fail read dtb from %s, ret %d\n", partName, iRet);
426 return CMD_RET_FAILURE;
427 }
428
429 unsigned long fdtAddr = (unsigned long)loadaddr;
430#ifdef CONFIG_MULTI_DTB
431 extern unsigned long get_multi_dt_entry(unsigned long fdt_addr);
432 fdtAddr = get_multi_dt_entry((unsigned long)fdtAddr);
433 if (!fdtAddr) {
434 errorP("Fail in get_multi_dt_entry\n");
435 return __LINE__;
436 }
437#endif// #ifdef CONFIG_MULTI_DTB
438 iRet = fdt_check_header((char*)fdtAddr);
439 if (iRet) {
440 errorP("Fail in fdt check header\n");
441 return CMD_RET_FAILURE;
442 }
443 const unsigned fdtsz = fdt_totalsize((char*)fdtAddr);
Bo Lv52186632024-02-22 16:32:44 +0800444
445 if (fdtsz >= SZ_1M) {
446 errorP("bad fdt size:%d\n", fdtsz);
447 return CMD_RET_FAILURE;
448 }
449
Bo Lv72d0e902023-01-02 14:27:34 +0000450 memmove(loadaddr, (char*)fdtAddr, fdtsz);
451
452 return iRet;
453}
454
Bo Lv77426d62023-08-11 19:05:38 +0800455uint32_t get_rsv_mem_size(void)
456{
457 uint32_t rsv_start, reg_size, rsv_size;
458#if defined(P_AO_SEC_GP_CFG3)
459 rsv_start = *((volatile uint32_t *)((uintptr_t)(P_AO_SEC_GP_CFG5)));
460 reg_size = *((volatile uint32_t *)((uintptr_t)(P_AO_SEC_GP_CFG3)));
461#elif defined(SYSCTRL_SEC_STATUS_REG15)
462 rsv_start = *((volatile uint32_t *)((uintptr_t)(SYSCTRL_SEC_STATUS_REG17)));
463 reg_size = *((volatile uint32_t *)((uintptr_t)(SYSCTRL_SEC_STATUS_REG15)));
464#endif
465 if ((reg_size >> 16) & 0xff)
466 rsv_size = (((reg_size & 0xffff0000) >> 16) << 16) +
467 ((reg_size & 0x0000ffff) << 16);
468 else
469 rsv_size = (((reg_size & 0xffff0000) >> 16) << 10) +
470 ((reg_size & 0x0000ffff) << 10);
471
472 return (rsv_start + rsv_size);
473}
474
Mingyen Hung96effce2023-09-01 00:39:46 -0700475static int do_image_read_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
476{
477 const char *name = NULL;
478 uint64_t addr = 0;
479 uint64_t offset = 0;
480 uint64_t sz = 0;
481 int rc = 0;
482
483 if (argc < 4 || argc > 5) {
484 return CMD_RET_USAGE;
485 }
486 name = argv[1];
487 addr = simple_strtoull(argv[2], NULL, 16);
488 offset = simple_strtoull(argv[3], NULL, 0);
489
490 if (argc == 5)
491 sz = simple_strtoull(argv[4], NULL, 0);
492 else
493 sz = store_logic_cap(name);
494
495 printf("read %s with %llu bytes at offset %llu to addr %#llx\n",
496 name, sz, offset, addr);
497
498 rc = store_logic_read(name, offset, sz, (void*)addr);
499 if (rc) {
500 printf("Failed to read %s with %llu bytes at offset %llu\n",
501 name, sz, offset);
502 goto out;
503 }
504#if CONFIG_PARTITION_ENCRYPTION_LOCAL
505 part_dec(name, (u8*)addr, sz, (u8*)addr, sz, offset);
506#endif
507out:
508 return rc;
509}
Bo Lv72d0e902023-01-02 14:27:34 +0000510static int do_image_read_kernel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
511{
512 unsigned kernel_size;
513 unsigned ramdisk_size;
514 boot_img_hdr_t *hdr_addr = NULL;
515 int genFmt = 0;
516 u32 actualbootimgsz = 0;
517 u32 dtbsz = 0;
518 const char *const partname = argv[1];
519 unsigned char* loadaddr = 0;
520 int rc = 0;
521 u64 flashreadoff = 0;
522 u32 securekernelimgsz = 0;
523 char *upgrade_step_s = NULL;
524 bool cache_flag = false;
Bo Lvda8d5b72023-07-31 14:58:21 +0800525 ulong kernelEndAddr = 0;
526 ulong kernelLoadAddr = 0;
527 ulong dtbLoadAddr = 0;
Bo Lv77426d62023-08-11 19:05:38 +0800528 ulong secMemSize = get_rsv_mem_size();
Bo Lvda8d5b72023-07-31 14:58:21 +0800529 char strAddr[128] = {0};
Matthew Shyu837ffa52024-05-03 01:59:44 -0700530#ifdef CONFIG_AVB2
531 u64 original_size = 0;
532#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000533
Bo Lvda8d5b72023-07-31 14:58:21 +0800534 if (argc > 2) {
Bo Lv72d0e902023-01-02 14:27:34 +0000535 loadaddr = (unsigned char *)simple_strtoul(argv[2], NULL, 16);
Bo Lvda8d5b72023-07-31 14:58:21 +0800536 env_set("loadaddr", (const char *)argv[2]);
537 } else {
Bo Lv72d0e902023-01-02 14:27:34 +0000538 loadaddr = (unsigned char *)simple_strtoul(env_get("loadaddr"), NULL, 16);
Bo Lvda8d5b72023-07-31 14:58:21 +0800539 }
Bo Lv72d0e902023-01-02 14:27:34 +0000540
541 hdr_addr = (boot_img_hdr_t *)loadaddr;
542
543 if (argc > 3)
544 flashreadoff = simple_strtoull(argv[3], NULL, 0);
545
546 upgrade_step_s = env_get("upgrade_step");
547 if (upgrade_step_s && (strcmp(upgrade_step_s, "3") == 0) &&
548 (strcmp(partname, "recovery") == 0)) {
549 loff_t len_read;
550
551 MsgP("read recovery.img from cache\n");
552 rc = fs_set_blk_dev("mmc", "1:2", FS_TYPE_EXT);
553 if (rc) {
554 errorP("Fail to set blk dev cache\n");
555 cache_flag = false;
556 } else {
557 fs_read("/recovery/recovery.img", (unsigned long)loadaddr,
558 flashreadoff, IMG_PRELOAD_SZ, &len_read);
559 if (IMG_PRELOAD_SZ != len_read) {
560 errorP("Fail to read recovery.img from cache\n");
561 cache_flag = false;
562 } else {
563 cache_flag = true;
564 }
565 }
566 }
567
568 if (!cache_flag) {
569 MsgP("read from part: %s\n", partname);
570 rc = store_logic_read(partname, flashreadoff, IMG_PRELOAD_SZ, loadaddr);
571 if (rc) {
572 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
573 IMG_PRELOAD_SZ, partname);
574 return __LINE__;
575 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700576#if CONFIG_PARTITION_ENCRYPTION_LOCAL
577 part_dec(partname, (u8*)loadaddr, IMG_PRELOAD_SZ, (u8*)loadaddr, IMG_PRELOAD_SZ, flashreadoff);
578#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000579 }
580 flashreadoff += IMG_PRELOAD_SZ;
581
582 if (!is_android_r_image((void *)hdr_addr)) {
583
584 /*free vendor buffer first*/
585 if (p_vender_boot_img) {
586 free(p_vender_boot_img);
587 p_vender_boot_img = 0;
588 }
589 genFmt = genimg_get_format(hdr_addr);
590#if defined(CONFIG_ZIRCON_BOOT_IMAGE)
591 if (IMAGE_FORMAT_ANDROID != genFmt && IMAGE_FORMAT_ZIRCON != genFmt) {
592 errorP("Fmt 0x%x unsupported!, supported genFmt 0x%x or 0x%x\n", genFmt,
593 IMAGE_FORMAT_ANDROID, IMAGE_FORMAT_ZIRCON);
594#else
595 if (IMAGE_FORMAT_ANDROID != genFmt) {
596 errorP("Fmt unsupported!genFmt 0x%x != 0x%x\n", genFmt, IMAGE_FORMAT_ANDROID);
597#endif
598 return __LINE__;
599 }
600
601 //Check if encrypted image
602 rc = _aml_get_secure_boot_kernel_size(loadaddr, &securekernelimgsz);
603 if (rc) {
604 errorP("Fail in _aml_get_secure_boot_kernel_size, rc=%d\n", rc);
605 return __LINE__;
606 }
607 if (securekernelimgsz) {
608 actualbootimgsz = securekernelimgsz;
609 MsgP("securekernelimgsz=0x%x\n", actualbootimgsz);
610 }
611 else {
612 kernel_size =(hdr_addr->kernel_size + (hdr_addr->page_size-1)+hdr_addr->page_size)&(~(hdr_addr->page_size -1));
613 ramdisk_size =(hdr_addr->ramdisk_size + (hdr_addr->page_size-1))&(~(hdr_addr->page_size -1));
614 dtbsz = hdr_addr->second_size;
615 actualbootimgsz = kernel_size + ramdisk_size + dtbsz;
616 debugP("kernel_size 0x%x, page_size 0x%x, totalSz 0x%x\n", hdr_addr->kernel_size, hdr_addr->page_size, kernel_size);
617 debugP("ramdisk_size 0x%x, totalSz 0x%x\n", hdr_addr->ramdisk_size, ramdisk_size);
618 debugP("dtbSz 0x%x, Total actualbootimgsz 0x%x\n", dtbsz, actualbootimgsz);
Meng yu629d20c2024-03-06 13:41:33 +0800619 if (kernel_size > MAX_KERNEL_SIZE) {
620 errorP("kernel size limit 0x%x,0x%x\n", kernel_size,
621 MAX_KERNEL_SIZE);
622 return __LINE__;
623 }
624 if (ramdisk_size > MAX_RAMDISK_SIZE) {
625 errorP("ramdisk size limit 0x%x,0x%x\n", ramdisk_size,
626 MAX_RAMDISK_SIZE);
627 return __LINE__;
628 }
629 if (dtbsz > MAX_DTB_SIZE) {
630 errorP("dtb size limit 0x%x,0x%x\n", dtbsz, MAX_DTB_SIZE);
631 return __LINE__;
632 }
Bo Lv72d0e902023-01-02 14:27:34 +0000633 }
634
635#if defined(CONFIG_ZIRCON_BOOT_IMAGE)
636 if (genFmt == IMAGE_FORMAT_ZIRCON) {
637 const zbi_header_t *zbi = (zbi_header_t *)hdr_addr;
638
639 actualbootimgsz = zbi->length + sizeof(*zbi);
640 }
641#endif//#if defined(CONFIG_ZIRCON_BOOT_IMAGE)
642
643 if (actualbootimgsz > IMG_PRELOAD_SZ) {
644 const u32 leftsz = actualbootimgsz - IMG_PRELOAD_SZ;
645
Bo Lvda8d5b72023-07-31 14:58:21 +0800646 /* auto adjust kernel image load address avoid
647 * touch iotrace data and secureOS memory space
648 */
649 kernelLoadAddr =
650 env_get_ulong("loadaddr", 16, KERNEL_DEFAULT_LOAD_ADDR);
651 kernelEndAddr = kernelLoadAddr + actualbootimgsz;
652 dtbLoadAddr = env_get_ulong("dtb_mem_addr", 16, DTB_LOAD_ADDR);
Bo Lv77426d62023-08-11 19:05:38 +0800653 if (kernelEndAddr > IOTRACE_LOAD_ADDR && kernelLoadAddr < secMemSize) {
Bo Lvda8d5b72023-07-31 14:58:21 +0800654 kernelLoadAddr = kernelLoadAddr -
655 ALIGN((kernelEndAddr - IOTRACE_LOAD_ADDR), LOAD_ADDR_ALIGN_LENGTH);
656 if (kernelLoadAddr <= dtbLoadAddr)
657 kernelLoadAddr = KERNEL_LOAD_HIGH_ADDR;
658 sprintf(strAddr, "%lx", kernelLoadAddr);
659 memmove((void *)kernelLoadAddr, (void *)loadaddr, IMG_PRELOAD_SZ);
660 env_set("loadaddr", strAddr);
Bo Lv77426d62023-08-11 19:05:38 +0800661 env_set("loadaddr_kernel", strAddr);
Bo Lvda8d5b72023-07-31 14:58:21 +0800662 loadaddr = (unsigned char *)
663 env_get_ulong("loadaddr", 16, kernelLoadAddr);
664 printf("kernel overlap iotrace, reset kernelLoadAddr = 0x%lx\n",
665 kernelLoadAddr);
666 }
Bo Lv72d0e902023-01-02 14:27:34 +0000667 debugP("Left sz 0x%x\n", leftsz);
668 rc = store_logic_read(partname, flashreadoff,
669 leftsz, loadaddr + IMG_PRELOAD_SZ);
670 if (rc) {
671 errorP("Fail to read 0x%xB from part[%s] at offset 0x%x\n",
672 leftsz, partname, IMG_PRELOAD_SZ);
673 return __LINE__;
674 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700675#if CONFIG_PARTITION_ENCRYPTION_LOCAL
676 part_dec(partname, (u8*)(loadaddr + IMG_PRELOAD_SZ), leftsz,
677 (u8*)(loadaddr + IMG_PRELOAD_SZ), leftsz, flashreadoff);
678#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000679 }
680 debugP("totalSz=0x%x\n", actualbootimgsz);
681
682 //because secure boot will use DMA which need disable MMU temp
683 //here must update the cache, otherwise nand will fail (eMMC is OK)
684 flush_cache((unsigned long)loadaddr, (unsigned long)actualbootimgsz);
Bo Lv72d0e902023-01-02 14:27:34 +0000685 }
686 else {
687 char partname_init[32] = {0};
688 u64 rc_init;
689 char *slot_name;
690 p_boot_img_hdr_v3_t hdr_addr_v3 = NULL;
Matthew Shyu837ffa52024-05-03 01:59:44 -0700691#ifdef CONFIG_AVB2
692 bool kernel_preload = true;
693 bool init_boot_preload = true;
694 bool vendor_boot_preload = true;
695#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000696
697 init_boot_ramdisk_size = 0;
698 slot_name = env_get("slot-suffixes");
699 if (slot_name && (strcmp(slot_name, "0") == 0))
700 strcpy((char *)partname_init, "init_boot_a");
701 else if (slot_name && (strcmp(slot_name, "1") == 0))
702 strcpy((char *)partname_init, "init_boot_b");
703 else
704 strcpy((char *)partname_init, "init_boot");
705
706 rc_init = store_part_size(partname_init);
707
708 /*free vendor buffer first*/
709 if (p_vender_boot_img) {
710 free(p_vender_boot_img);
711 p_vender_boot_img = 0;
712 }
713
714 genFmt = genimg_get_format(hdr_addr);
715 if (IMAGE_FORMAT_ANDROID != genFmt) {
716 errorP("Fmt unsupported!genFmt 0x%x != 0x%x\n", genFmt, IMAGE_FORMAT_ANDROID);
717 return __LINE__;
718 }
719
720 //Check if encrypted image
721 rc = _aml_get_secure_boot_kernel_size(loadaddr, &securekernelimgsz);
722 if (rc) {
723 errorP("Fail in _aml_get_secure_boot_kernel_size, rc=%d\n", rc);
724 return __LINE__;
725 }
726
727 hdr_addr_v3 = (p_boot_img_hdr_v3_t)hdr_addr;
728 kernel_size = ALIGN(hdr_addr_v3->kernel_size, 0x1000);
729
730 ramdisk_size = ALIGN(hdr_addr_v3->ramdisk_size, 0x1000);
731
732 MsgP("kernel_size 0x%x, totalSz 0x%x\n",
733 hdr_addr_v3->kernel_size, kernel_size);
734 MsgP("ramdisk_size 0x%x, totalSz 0x%x\n",
735 hdr_addr_v3->ramdisk_size, ramdisk_size);
736 MsgP("boot header_version = %d\n", hdr_addr_v3->header_version);
Meng yu629d20c2024-03-06 13:41:33 +0800737 if (kernel_size > MAX_KERNEL_SIZE) {
738 errorP("kernel size limit 0x%x,0x%x\n", kernel_size, MAX_KERNEL_SIZE);
739 return __LINE__;
740 }
741 if (ramdisk_size > MAX_RAMDISK_SIZE) {
742 errorP("ramdisk size limit 0x%x,0x%x\n", ramdisk_size, MAX_RAMDISK_SIZE);
743 return __LINE__;
744 }
Bo Lv72d0e902023-01-02 14:27:34 +0000745 if (securekernelimgsz) {
746 actualbootimgsz = securekernelimgsz;
747 MsgP("securekernelimgsz=0x%x\n", actualbootimgsz);
748 } else {
749 actualbootimgsz = kernel_size + ramdisk_size + 0x1000;
Matthew Shyu837ffa52024-05-03 01:59:44 -0700750#ifdef CONFIG_AVB2
751 original_size = actualbootimgsz;
752 actualbootimgsz = get_size_avb_footer(partname);
Matthew Shyu4dabf572024-05-22 04:23:21 -0700753 if (!actualbootimgsz || actualbootimgsz < original_size) {
Matthew Shyu837ffa52024-05-03 01:59:44 -0700754 actualbootimgsz = original_size;
755 kernel_preload = false;
756 wrnP("part: %s footer not at correct location\n", partname);
757 }
758#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000759 }
760
761 if (actualbootimgsz > IMG_PRELOAD_SZ) {
762 const u32 leftsz = actualbootimgsz - IMG_PRELOAD_SZ;
763
Bo Lvda8d5b72023-07-31 14:58:21 +0800764 /* auto adjust kernel image load address avoid
765 * touch iotrace data and secureOS memory space
766 */
767 kernelLoadAddr =
768 env_get_ulong("loadaddr", 16, KERNEL_DEFAULT_LOAD_ADDR);
769 kernelEndAddr = kernelLoadAddr + actualbootimgsz;
770 dtbLoadAddr = env_get_ulong("dtb_mem_addr", 16, DTB_LOAD_ADDR);
Bo Lv77426d62023-08-11 19:05:38 +0800771 if (kernelEndAddr > IOTRACE_LOAD_ADDR && kernelLoadAddr < secMemSize) {
Bo Lvda8d5b72023-07-31 14:58:21 +0800772 kernelLoadAddr = kernelLoadAddr -
773 ALIGN((kernelEndAddr - IOTRACE_LOAD_ADDR), LOAD_ADDR_ALIGN_LENGTH);
774 if (kernelLoadAddr <= dtbLoadAddr)
775 kernelLoadAddr = KERNEL_LOAD_HIGH_ADDR;
776 sprintf(strAddr, "%lx", kernelLoadAddr);
777 memmove((void *)kernelLoadAddr, (void *)loadaddr, IMG_PRELOAD_SZ);
778 env_set("loadaddr", strAddr);
Bo Lv77426d62023-08-11 19:05:38 +0800779 env_set("loadaddr_kernel", strAddr);
Bo Lvda8d5b72023-07-31 14:58:21 +0800780 loadaddr = (unsigned char *)
781 env_get_ulong("loadaddr", 16, kernelLoadAddr);
782 printf("kernel overlap iotrace, reset kernelLoadAddr = 0x%lx\n",
783 kernelLoadAddr);
784 }
785
Bo Lv72d0e902023-01-02 14:27:34 +0000786 debugP("Left sz 0x%x\n", leftsz);
787
788 if (upgrade_step_s && (strcmp(upgrade_step_s, "3") == 0) &&
789 (strcmp(partname, "recovery") == 0)) {
790 loff_t len_read;
791
792 MsgP("read recovery.img from cache\n");
793 rc = fs_set_blk_dev("mmc", "1:2", FS_TYPE_EXT);
794 if (rc) {
795 errorP("Fail to set blk dev cache\n");
796 cache_flag = false;
797 } else {
798 fs_read("/recovery/recovery.img",
799 (unsigned long)loadaddr,
800 0, actualbootimgsz, &len_read);
801 if (actualbootimgsz != len_read) {
802 errorP("Fail to read recovery.img from cache\n");
803 cache_flag = false;
804 } else {
805 cache_flag = true;
806 }
807 }
808 }
809 if (!cache_flag) {
810 MsgP("read from part: %s\n", partname);
811 rc = store_logic_read(partname, flashreadoff,
812 leftsz, loadaddr + IMG_PRELOAD_SZ);
813 if (rc) {
814 errorP("Fail to read 0x%xB from part[%s] at offset 0x%x\n",
815 leftsz, partname, IMG_PRELOAD_SZ);
816 return __LINE__;
817 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700818#if CONFIG_PARTITION_ENCRYPTION_LOCAL
819 part_dec(partname, (u8*)(loadaddr + IMG_PRELOAD_SZ), leftsz,
820 (u8*)(loadaddr + IMG_PRELOAD_SZ), leftsz, flashreadoff);
821#endif
Matthew Shyu837ffa52024-05-03 01:59:44 -0700822#ifdef CONFIG_AVB2
823 if (kernel_preload)
824 set_avb_parts(partname, loadaddr, leftsz + IMG_PRELOAD_SZ);
825#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000826 if (rc_init != -1) {
827 MsgP("read header from part: %s\n", partname_init);
828 unsigned int nflashloadlen_init = 0;
829 const int preloadsz_init = 0x1000 * 2;
830 unsigned char *pbuffpreload_init = 0;
Matthew Shyu837ffa52024-05-03 01:59:44 -0700831#ifdef CONFIG_AVB2
832 u8 *init_boot_buf = 0;
833#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000834
835 nflashloadlen_init = preloadsz_init;
836 debugP("sizeof preloadSz=%u\n", nflashloadlen_init);
837
838 pbuffpreload_init = malloc(preloadsz_init);
839
840 if (!pbuffpreload_init) {
841 printf("Fail to allocate memory for %s!\n",
842 partname_init);
843 return __LINE__;
844 }
845
846 rc = store_logic_read(partname_init, 0,
847 nflashloadlen_init, pbuffpreload_init);
848 if (rc) {
849 errorP("Fail to read 0x%xB from part[%s]\n",
850 nflashloadlen_init, partname_init);
851 free(pbuffpreload_init);
852 pbuffpreload_init = 0;
853 return __LINE__;
854 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700855#if CONFIG_PARTITION_ENCRYPTION_LOCAL
856 part_dec(partname_init, (u8*)pbuffpreload_init, nflashloadlen_init,
857 (u8*)pbuffpreload_init, nflashloadlen_init, 0);
858#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000859 p_boot_img_hdr_v3_t pinitbootimghdr;
860
861 pinitbootimghdr = (p_boot_img_hdr_v3_t)pbuffpreload_init;
862
863 ramdisk_size = ALIGN(pinitbootimghdr->ramdisk_size,
864 0x1000);
865 MsgP("ramdisk_size 0x%x, totalSz 0x%x\n",
866 pinitbootimghdr->ramdisk_size, ramdisk_size);
867 MsgP("init_boot header_version = %d\n",
868 pinitbootimghdr->header_version);
869 init_boot_ramdisk_size = pinitbootimghdr->ramdisk_size;
870
Matthew Shyu837ffa52024-05-03 01:59:44 -0700871#ifdef CONFIG_AVB2
872 original_size = ramdisk_size;
873 ramdisk_size = get_size_avb_footer(partname_init);
Matthew Shyu4dabf572024-05-22 04:23:21 -0700874 if (!ramdisk_size || ramdisk_size < original_size) {
Matthew Shyu837ffa52024-05-03 01:59:44 -0700875 ramdisk_size = original_size;
876 init_boot_preload = false;
877 wrnP("part: %s footer not at correct location\n",
878 partname_init);
879 }
880 if (init_boot_preload) {
881 init_boot_buf = malloc(ramdisk_size);
882 if (!init_boot_buf) {
883 printf("Fail to allocate memory for %s!\n",
884 partname_init);
885 free(pbuffpreload_init);
886 pbuffpreload_init = 0;
887 return __LINE__;
888 }
889 memcpy(init_boot_buf, pbuffpreload_init,
890 nflashloadlen_init);
891 ramdisk_size -= BOOT_IMG_V3_HDR_SIZE;
892 }
893#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000894 if (init_boot_ramdisk_size != 0) {
895 MsgP("read ramdisk from part: %s\n", partname_init);
896 rc = store_logic_read(partname_init,
897 BOOT_IMG_V3_HDR_SIZE,
898 ramdisk_size,
899 loadaddr + kernel_size
900 + BOOT_IMG_V3_HDR_SIZE);
901 if (rc) {
902 errorP("Fail to read 0x%xB from part[%s]\n",
903 ramdisk_size, partname_init);
904 free(pbuffpreload_init);
905 pbuffpreload_init = 0;
906 return __LINE__;
907 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700908#if CONFIG_PARTITION_ENCRYPTION_LOCAL
909 part_dec(partname_init, (u8*)(loadaddr + kernel_size + BOOT_IMG_V3_HDR_SIZE),
910 ramdisk_size,
911 (u8*)(loadaddr + kernel_size + BOOT_IMG_V3_HDR_SIZE),
912 ramdisk_size,
913 BOOT_IMG_V3_HDR_SIZE);
914#endif
915
Matthew Shyu837ffa52024-05-03 01:59:44 -0700916#ifdef CONFIG_AVB2
917 if (init_boot_preload)
918 memcpy(init_boot_buf + BOOT_IMG_V3_HDR_SIZE,
919 loadaddr + kernel_size +
920 BOOT_IMG_V3_HDR_SIZE,
921 ramdisk_size);
922#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000923 }
Matthew Shyu837ffa52024-05-03 01:59:44 -0700924#ifdef CONFIG_AVB2
925 if (init_boot_ramdisk_size != 0 && init_boot_preload)
926 set_avb_parts(partname_init, init_boot_buf,
927 ramdisk_size + BOOT_IMG_V3_HDR_SIZE);
928 if (init_boot_preload)
929 free(init_boot_buf);
930#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000931 free(pbuffpreload_init);
932 pbuffpreload_init = 0;
933 }
934 }
935 }
936 debugP("totalSz=0x%x\n", actualbootimgsz);
937 /*
938 *because secure boot will use DMA which need disable MMU temp
939 *here must update the cache, otherwise nand will fail (eMMC is OK)
940 */
941 flush_cache((unsigned long)loadaddr, (unsigned long)actualbootimgsz);
942
943 /*
944 *Android R need read vendor_boot partition
945 *define Android R variable add suffix xxx_r
946 */
947 char partname_r[32] = {0};
948 int ret_r = __LINE__;
949 u64 lflashreadoff_r = 0;
950 unsigned int nflashloadlen_r = 0;
951 const int preloadsz_r = 0x1000 * 2;//4k not enough for signed
952 p_vendor_boot_img_hdr_t pbuffpreload = 0;
953 u64 vendorboot_part_sz = 0;
954 int rc_r = 0;
955
956 if (strcmp(slot_name, "0") == 0)
957 strcpy((char *)partname_r, "vendor_boot_a");
958 else if (strcmp(slot_name, "1") == 0)
959 strcpy((char *)partname_r, "vendor_boot_b");
960 else
961 strcpy((char *)partname_r, "vendor_boot");
962
963 MsgP("partname_r = %s\n", partname_r);
964 vendorboot_part_sz = store_part_size(partname_r);
965
966 nflashloadlen_r = preloadsz_r; //head info is one page size == 4k
967 debugP("sizeof preloadSz=%u\n", nflashloadlen_r);
968
969 pbuffpreload = malloc(preloadsz_r);
970
Bo Lv56db47f2023-07-10 11:32:25 +0800971 memset((void *)pbuffpreload, 0, preloadsz_r);
972
Bo Lv72d0e902023-01-02 14:27:34 +0000973 if (!pbuffpreload) {
974 printf("aml log : system error! Fail to allocate memory for %s!\n",
975 partname_r);
976 return __LINE__;
977 }
978
979 if (upgrade_step_s && (strcmp(upgrade_step_s, "3") == 0) &&
980 (strcmp(partname_r, "vendor_boot") == 0)) {
981 loff_t len_read;
982
983 MsgP("read vendor_boot from cache\n");
984 ret_r = fs_set_blk_dev("mmc", "1:2", FS_TYPE_EXT);
985 if (ret_r) {
986 errorP("Fail to set blk dev cache\n");
987 cache_flag = false;
988 } else {
989 fs_read("/recovery/vendor_boot.img",
990 (unsigned long)pbuffpreload,
991 0, nflashloadlen_r, &len_read);
992 if (nflashloadlen_r != len_read) {
993 errorP("Fail to read vendor_boot.img from cache\n");
994 cache_flag = false;
995 } else {
996 cache_flag = true;
997 }
998 }
999 }
1000 if (!cache_flag) {
1001 MsgP("read from part: %s\n", partname_r);
1002 ret_r = store_logic_read(partname_r, lflashreadoff_r,
1003 nflashloadlen_r, pbuffpreload);
1004 if (ret_r) {
1005 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
1006 nflashloadlen_r, partname_r);
1007 free(pbuffpreload);
1008 pbuffpreload = 0;
1009 return __LINE__;
1010 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001011#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1012 part_dec(partname_r, (u8*)pbuffpreload, nflashloadlen_r,
1013 (u8*)pbuffpreload, nflashloadlen_r, lflashreadoff_r);
1014#endif
1015
Bo Lv72d0e902023-01-02 14:27:34 +00001016 }
1017 p_vendor_boot_img_hdr_t pvendorimghdr = (p_vendor_boot_img_hdr_t)pbuffpreload;
1018
1019 rc_r = vendor_boot_image_check_header(pvendorimghdr);
1020 if (!rc_r) {
1021 //Check if encrypted image
1022 rc_r = _aml_get_secure_boot_kernel_size(pbuffpreload, &securekernelimgsz);
1023 if (rc_r) {
1024 errorP("Fail in _aml_get_secure_boot_kernel_size, rc=%d\n", rc_r);
1025 free(pbuffpreload);
1026 pbuffpreload = 0;
1027 return __LINE__;
1028 }
1029 if (securekernelimgsz) {
1030 nflashloadlen_r = securekernelimgsz;
1031 MsgP("securekernelimgsz=0x%x\n", nflashloadlen_r);
1032 } else {
1033 unsigned long ramdisk_size_r, dtb_size_r;
1034 unsigned long ramdisk_table_size;
1035 const int pagesz_r = pvendorimghdr->page_size;
1036
1037 /* Android R's vendor_boot partition include ramdisk and dtb */
1038 ramdisk_size_r = ALIGN(pvendorimghdr->vendor_ramdisk_size,
1039 pagesz_r);
1040 dtb_size_r = ALIGN(pvendorimghdr->dtb_size, pagesz_r);
1041 nflashloadlen_r = ramdisk_size_r + dtb_size_r + 0x1000;
1042 MsgP("ramdisk_size_r 0x%x, totalSz 0x%lx\n",
1043 pvendorimghdr->vendor_ramdisk_size, ramdisk_size_r);
1044 MsgP("dtb_size_r 0x%x, totalSz 0x%lx\n",
1045 pvendorimghdr->dtb_size, dtb_size_r);
1046 MsgP("vendor_boot header_version = %d\n",
1047 pvendorimghdr->header_version);
1048 if (pvendorimghdr->header_version > 3) {
1049 MsgP("vendor_ramdisk_table_size: 0x%x\n",
1050 pvendorimghdr->vendor_ramdisk_table_size);
1051 MsgP("vendor_ramdisk_table_entry_num: 0x%x\n",
1052 pvendorimghdr->vendor_ramdisk_table_entry_num);
1053 MsgP("vendor_ramdisk_table_entry_size: 0x%x\n",
1054 pvendorimghdr->vendor_ramdisk_table_entry_size);
1055 MsgP("vendor_bootconfig_size: 0x%x\n",
1056 pvendorimghdr->vendor_bootconfig_size);
1057 ramdisk_table_size =
1058 ALIGN(pvendorimghdr->vendor_ramdisk_table_size,
1059 pagesz_r);
1060 nflashloadlen_r = nflashloadlen_r + ramdisk_table_size;
1061
1062 MsgP("ramdisk table offset 0x%lx, nflashloadlen_r 0x%x\n",
1063 ramdisk_size_r + dtb_size_r + 0x1000, nflashloadlen_r);
1064 }
1065 }
1066 if (nflashloadlen_r > vendorboot_part_sz) {
1067 errorP("nflashloadlen_r 0x%x > vendorboot_part_sz 0x%llx\n",
1068 nflashloadlen_r, vendorboot_part_sz);
Bo Lv56db47f2023-07-10 11:32:25 +08001069 free(pbuffpreload);
1070 pbuffpreload = 0;
Bo Lv72d0e902023-01-02 14:27:34 +00001071 return __LINE__;
1072 }
1073
Matthew Shyu837ffa52024-05-03 01:59:44 -07001074#ifdef CONFIG_AVB2
1075 if (!(upgrade_step_s && !(strcmp(upgrade_step_s, "3")))) {
1076 original_size = nflashloadlen_r;
Matthew Shyu4dabf572024-05-22 04:23:21 -07001077 nflashloadlen_r = get_size_avb_footer(partname_r);
1078 if (!nflashloadlen_r || nflashloadlen_r < original_size) {
Matthew Shyu837ffa52024-05-03 01:59:44 -07001079 nflashloadlen_r = original_size;
1080 vendor_boot_preload = false;
1081 wrnP("part: %s footer not at correct location\n",
1082 partname);
1083 }
1084 }
1085#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001086 if (nflashloadlen_r > preloadsz_r) {
1087 free(pbuffpreload);
1088 pbuffpreload = malloc(nflashloadlen_r);
1089 memset(pbuffpreload, 0, nflashloadlen_r);
1090 if (!pbuffpreload)
1091 return __LINE__;
1092 if (upgrade_step_s && (strcmp(upgrade_step_s, "3") == 0) &&
1093 (strcmp(partname_r, "vendor_boot") == 0)) {
1094 loff_t len_read;
1095
1096 MsgP("recovery mode, read vendor_boot from cache\n");
1097 ret_r = fs_set_blk_dev("mmc", "1:2", FS_TYPE_EXT);
1098 if (ret_r) {
1099 errorP("Fail to set blk dev cache\n");
1100 cache_flag = false;
1101 } else {
1102 fs_read("/recovery/vendor_boot.img",
1103 (unsigned long)pbuffpreload,
1104 lflashreadoff_r, nflashloadlen_r,
1105 &len_read);
1106 if (nflashloadlen_r != len_read) {
1107 errorP("Fail to read from cache\n");
1108 cache_flag = false;
1109 } else {
1110 cache_flag = true;
1111 }
1112 }
1113 }
1114 if (!cache_flag) {
1115 MsgP("read from part: %s\n", partname_r);
1116 rc_r = store_logic_read(partname_r, lflashreadoff_r,
1117 nflashloadlen_r, pbuffpreload);
1118 if (rc_r) {
1119 errorP("Fail read 0x%xB from %s at offset 0x%x\n",
1120 (unsigned int)nflashloadlen_r, partname_r,
1121 (unsigned int)lflashreadoff_r);
1122 free(pbuffpreload);
1123 pbuffpreload = 0;
1124 return __LINE__;
1125 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001126#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1127 part_dec(partname_r, (u8*)pbuffpreload, nflashloadlen_r,
1128 (u8*)pbuffpreload, nflashloadlen_r, lflashreadoff_r);
1129#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001130 }
1131 }
1132
Matthew Shyu837ffa52024-05-03 01:59:44 -07001133#ifdef CONFIG_AVB2
1134 if (!rc_r && !(upgrade_step_s && !(strcmp(upgrade_step_s, "3"))) &&
1135 vendor_boot_preload)
1136 set_avb_parts(partname_r, (void *)pbuffpreload, nflashloadlen_r);
1137#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001138 debugP("totalSz=0x%x\n", nflashloadlen_r);
1139 flush_cache((unsigned long)pbuffpreload, nflashloadlen_r);
1140#ifndef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
1141 if (IS_FEAT_BOOT_VERIFY()) {
1142#ifndef CONFIG_IMAGE_CHECK
1143 rc_r = aml_sec_boot_check(AML_D_P_IMG_DECRYPT,
1144 (unsigned long)pbuffpreload,
1145 GXB_IMG_SIZE, GXB_IMG_DEC_DTB);
1146#else
1147 rc_r = secure_image_check((uint8_t *)(unsigned long)
1148 pbuffpreload, GXB_IMG_SIZE, GXB_IMG_DEC_DTB);
1149 /*pbuffpreload += android_image_check_offset();*/
1150 memmove(pbuffpreload, pbuffpreload + android_image_check_offset(),
1151 nflashloadlen_r - android_image_check_offset());
1152#endif
1153 if (rc_r) {
1154 errorP("\n[vendor_boot]aml log : Sig Check is %d\n", rc_r);
1155 return __LINE__;
1156 }
1157 MsgP("vendor_boot decrypt at 0x%p\n", pbuffpreload);
1158 }
1159#endif//#ifndef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
1160
1161 p_vender_boot_img = (p_vendor_boot_img_t)pbuffpreload;
1162 } else {
1163 free(pbuffpreload);
1164 pbuffpreload = 0;
1165 }
1166 } /*ANDROID R/S*/
Bo Lv65d86792024-08-30 11:02:03 +08001167
1168 /* image size exceed 24M meanwhile need to decompress would overlap secure zone */
1169 if ((android_image_get_comp((void *)loadaddr) != IH_COMP_NONE) &&
1170 (kernel_size > KERNEL_DECOMPRESS_MAX_SIZE)) {
1171 memset(strAddr, 0, sizeof(strAddr));
1172 sprintf(strAddr, "%x", KERNEL_HIGH_DEC_ADDR);
1173 env_set("decaddr_kernel", strAddr);
1174 }
1175
Bo Lv72d0e902023-01-02 14:27:34 +00001176 return 0;
1177}
1178
1179#define AML_RES_IMG_VERSION_V1 (0x01)
1180#define AML_RES_IMG_VERSION_V2 (0x02)
1181#define AML_RES_IMG_V1_MAGIC_LEN 8
1182#define AML_RES_IMG_V1_MAGIC "AML_RES!"//8 chars
1183#define AML_RES_IMG_ITEM_ALIGN_SZ 16
1184#define AML_RES_IMG_HEAD_SZ (AML_RES_IMG_ITEM_ALIGN_SZ * 4)//64
1185#define AML_RES_ITEM_HEAD_SZ (AML_RES_IMG_ITEM_ALIGN_SZ * 4)//64
1186
1187//typedef for amlogic resource image
1188#pragma pack(push, 4)
1189typedef struct {
1190 __u32 crc; //crc32 value for the resouces image
1191 __s32 version;//current version is 0x01
1192
1193 __u8 magic[AML_RES_IMG_V1_MAGIC_LEN]; //resources images magic
1194
1195 __u32 imgSz; //total image size in byte
1196 __u32 imgItemNum;//total item packed in the image
1197
1198 __u32 alignSz;//AML_RES_IMG_ITEM_ALIGN_SZ
1199 __u8 reserv[AML_RES_IMG_HEAD_SZ - 8 * 3 - 4];
1200
1201}AmlResImgHead_t;
1202#pragma pack(pop)
1203
1204#define LOGO_OLD_FMT_READ_SZ (8U<<20)//if logo format old, read 8M
Meng yu2d8820b2024-03-06 11:33:25 +08001205#define LOGO_TOTAL_ITEM (16)
Bo Lv72d0e902023-01-02 14:27:34 +00001206
1207static int img_res_check_log_header(const AmlResImgHead_t* pResImgHead)
1208{
1209 int rc = 0;
1210
1211 rc = memcmp(pResImgHead->magic, AML_RES_IMG_V1_MAGIC, AML_RES_IMG_V1_MAGIC_LEN);
1212 if (rc) {
1213 debugP("Magic error for res\n");
1214 return 1;
1215 }
1216 if (AML_RES_IMG_VERSION_V2 != pResImgHead->version) {
1217 errorP("res version 0x%x != 0x%x\n", pResImgHead->version, AML_RES_IMG_VERSION_V2);
1218 return 2;
1219 }
Meng yu2d8820b2024-03-06 11:33:25 +08001220 if (pResImgHead->imgItemNum > LOGO_TOTAL_ITEM) {
1221 errorP("logo size err 0x%x != 0x%x\n", pResImgHead->imgItemNum, LOGO_TOTAL_ITEM);
1222 return 3;
1223 }
Bo Lv72d0e902023-01-02 14:27:34 +00001224
1225 return 0;
1226}
1227
1228static int do_image_read_res(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1229{
1230 const char* const partName = argv[1];
1231 unsigned char* loadaddr = 0;
1232 int rc = 0;
1233 AmlResImgHead_t* pResImgHead = NULL;
1234 unsigned totalSz = 0;
1235 uint64_t flashReadOff = 0;
1236
1237 if (2 < argc) {
1238 loadaddr = (unsigned char*)simple_strtoul(argv[2], NULL, 16);
1239 }
1240 else{
1241 loadaddr = (unsigned char*)simple_strtoul(env_get("loadaddr"), NULL, 16);
1242 }
1243 pResImgHead = (AmlResImgHead_t*)loadaddr;
1244
1245 rc = store_logic_read(partName, flashReadOff, IMG_PRELOAD_SZ, loadaddr);
1246 if (rc) {
1247 errorP("Fail to read 0x%xB from part[%s] at offset 0\n", IMG_PRELOAD_SZ, partName);
1248 return __LINE__;
1249 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001250#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1251 part_dec(partName, (u8*)loadaddr, IMG_PRELOAD_SZ, (u8*)loadaddr, IMG_PRELOAD_SZ, flashReadOff);
1252#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001253 flashReadOff = IMG_PRELOAD_SZ;
1254
1255 if (img_res_check_log_header(pResImgHead)) {
1256 errorP("Logo header err.\n");
1257 return __LINE__;
1258 }
1259
1260 //Read the actual size of the new version res image
1261 totalSz = pResImgHead->imgSz;
1262 if (totalSz > IMG_PRELOAD_SZ )
1263 {
1264 const unsigned leftSz = totalSz - flashReadOff;
1265
1266 rc = store_logic_read(partName, flashReadOff, leftSz, loadaddr + (unsigned)flashReadOff);
1267 if (rc) {
1268 errorP("Fail to read 0x%xB from part[%s] at offset 0x%x\n", leftSz, partName, IMG_PRELOAD_SZ);
1269 return __LINE__;
1270 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001271#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1272 part_dec(partName, (u8*)(loadaddr + (unsigned)flashReadOff), leftSz,
1273 (u8*)(loadaddr + (unsigned)flashReadOff), leftSz, flashReadOff);
1274#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001275 }
1276 debugP("totalSz=0x%x\n", totalSz);
1277
1278 return 0;
1279}
1280
1281#define IH_MAGIC 0x27051956 /* Image Magic Number */
1282#define IH_NMLEN 32 /* Image Name Length */
1283
1284#pragma pack(push, 1)
1285typedef struct pack_header{
1286 unsigned int magic; /* Image Header Magic Number */
1287 unsigned int hcrc; /* Image Header CRC Checksum */
1288 unsigned int size; /* Image Data Size */
1289 unsigned int start; /* item data offset in the image*/
1290 unsigned int end; /* Entry Point Address */
1291 unsigned int next; /* Next item head offset in the image*/
1292 unsigned int dcrc; /* Image Data CRC Checksum */
1293 unsigned char index; /* Operating System */
1294 unsigned char nums; /* CPU architecture */
1295 unsigned char type; /* Image Type */
1296 unsigned char comp; /* Compression Type */
1297 char name[IH_NMLEN]; /* Image Name */
1298}AmlResItemHead_t;
1299#pragma pack(pop)
1300
1301#define CONFIG_MAX_PIC_LEN (12 << 20)
1302static const unsigned char gzip_magic[] = { 0x1f, 0x8b };
1303
1304//uncompress known format for 'imgread pic'
1305static int imgread_uncomp_pic(unsigned char* srcAddr, const unsigned srcSz,
1306 unsigned char* dstAddr, const unsigned dstBufSz, unsigned long* dstDatSz)
1307{
1308 /*debugP("srcAddr[%x, %x]\n", srcAddr[0], srcAddr[1]);*/
1309 if (!memcmp(srcAddr, gzip_magic, sizeof(gzip_magic)))
1310 {
1311 *dstDatSz = srcSz;
1312 return gunzip(dstAddr, dstBufSz, srcAddr, dstDatSz);
1313 }
1314
1315 return 0;
1316}
1317
1318//[imgread pic] logo bootup $loadaddr_misc
1319static int do_image_read_pic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1320{
1321 const char* const partName = argv[1];
1322 unsigned char* loadaddr = 0;
1323 int rc = 0;
1324 const AmlResImgHead_t* pResImgHead = NULL;
1325 //unsigned totalSz = 0;
1326 uint64_t flashReadOff = 0;
1327 const unsigned PreloadSz = PIC_PRELOAD_SZ;//preload 8k, 124-1 pic header, If you need pack more than 123 items, fix this
1328 unsigned itemIndex = 0;
1329 const AmlResItemHead_t* pItem = NULL;
1330 const char* picName = argv[2];
1331
1332 loadaddr = (unsigned char*)simple_strtoul(argc > 3 ? argv[3] : env_get("loadaddr_misc"), NULL, 16);
1333
1334 pResImgHead = (AmlResImgHead_t*)loadaddr;
1335
1336 debugP("to read pic (%s)\n", picName);
1337 rc = store_logic_read(partName, flashReadOff, PreloadSz, loadaddr);
1338 if (rc) {
1339 errorP("Fail to read 0x%xB from part[%s] at offset 0\n", PreloadSz, partName);
1340 return __LINE__;
1341 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001342#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1343 part_dec(partName, (u8*)loadaddr, PreloadSz, (u8*)loadaddr, PreloadSz, flashReadOff);
1344#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001345 flashReadOff = PreloadSz;
1346 debugP("end read pic sz %d\n", PreloadSz);
1347
1348 if (img_res_check_log_header(pResImgHead)) {
1349 errorP("Logo header err.\n");
1350 return __LINE__;
1351 }
1352
1353 //correct bootup for mbox
1354 while (!strcmp("bootup", picName))
1355 {
1356 char* outputmode = env_get("outputmode");
1357 if (!outputmode)break;//not env outputmode
1358
1359 rc = !strncmp("720", outputmode, 3) || !strncmp("576", outputmode, 3) || !strncmp("480", outputmode, 3);
1360 if (rc) {
1361 picName = "bootup_720";
1362 break;
1363 }
1364
1365 picName = "bootup_1080";
1366 break;
1367 }
1368
1369 pItem = (AmlResItemHead_t*)(pResImgHead + 1);
1370 for (itemIndex = 0; itemIndex < pResImgHead->imgItemNum; ++itemIndex, ++pItem)
1371 {
1372 if (IH_MAGIC != pItem->magic) {
1373 errorP("item magic 0x%x != 0x%x\n", pItem->magic, IH_MAGIC);
1374 return __LINE__;
1375 }
Meng yu2d8820b2024-03-06 11:33:25 +08001376 if (pItem->start > CONFIG_MAX_PIC_LEN) {
1377 errorP("item data offset err 0x%x != 0x%x\n", pItem->start,
1378 CONFIG_MAX_PIC_LEN);
1379 return __LINE__;
1380 }
1381 if (pItem->size > CONFIG_MAX_PIC_LEN) {
1382 errorP("item data size err 0x%x != 0x%x\n", pItem->size,
1383 CONFIG_MAX_PIC_LEN);
1384 return __LINE__;
1385 }
Bo Lv72d0e902023-01-02 14:27:34 +00001386 if (!strcmp(picName, pItem->name) || !strcmp(argv[2], pItem->name))
1387 {
1388 char env_name[IH_NMLEN*2];
1389 char env_data[IH_NMLEN*2];
1390 unsigned long picLoadAddr = (unsigned long)loadaddr + (unsigned)pItem->start;
Meng yu2d8820b2024-03-06 11:33:25 +08001391 unsigned int itemSz = pItem->size;
Bo Lv72d0e902023-01-02 14:27:34 +00001392 unsigned long uncompSz = 0;
1393
1394 if (pItem->start + itemSz > flashReadOff)
1395 {
1396 unsigned long rdOff = pItem->start;
1397 unsigned long rdOffAlign = (rdOff >> 11) << 11;//align 2k page for mtd nand, 512 for emmc
1398 rc = store_logic_read(partName, rdOffAlign, itemSz + (rdOff & 0x7ff),(char*)((picLoadAddr>>11)<<11));
1399 if (rc) {
1400 errorP("Fail to read pic at offset 0x%x\n", pItem->start);
1401 return __LINE__;
1402 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001403#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1404 part_dec(partName, (u8*)((picLoadAddr>>11)<<11), itemSz + (rdOff & 0x7ff),
1405 (u8*)((picLoadAddr>>11)<<11), itemSz + (rdOff & 0x7ff), rdOffAlign);
1406#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001407 debugP("pic sz 0x%x\n", itemSz);
1408 }
1409
1410 //uncompress supported format
1411 unsigned long uncompLoadaddr = picLoadAddr + itemSz + 7;
1412 uncompLoadaddr &= ~(0x7U);
1413 rc = imgread_uncomp_pic((unsigned char *)picLoadAddr, itemSz,
1414 (unsigned char *)uncompLoadaddr, CONFIG_MAX_PIC_LEN, &uncompSz);
1415 if (rc) {
1416 errorP("Fail in uncomp pic,rc[%d]\n", rc);
1417 return __LINE__;
1418 }
1419 if (uncompSz) {
Meng yu2d8820b2024-03-06 11:33:25 +08001420 itemSz = uncompSz;
Bo Lv72d0e902023-01-02 14:27:34 +00001421 picLoadAddr = uncompLoadaddr;
1422 }
1423
1424 sprintf(env_name, "%s_offset", argv[2]);//be bootup_offset ,not bootup_720_offset
1425 sprintf(env_data, "0x%lx", picLoadAddr);
1426 env_set(env_name, env_data);
1427
1428 sprintf(env_name, "%s_size", argv[2]);
1429 sprintf(env_data, "0x%x", itemSz);
1430 env_set(env_name, env_data);
1431
1432 debugP("end read pic[%s]\n", picName);
1433 return 0;//success
1434 }
1435 }
1436
1437 return __LINE__;//fail
1438}
1439
1440static cmd_tbl_t cmd_imgread_sub[] = {
1441 U_BOOT_CMD_MKENT(kernel, 4, 0, do_image_read_kernel, "", ""),
1442 U_BOOT_CMD_MKENT(dtb, 4, 0, do_image_read_dtb, "", ""),
1443 U_BOOT_CMD_MKENT(res, 3, 0, do_image_read_res, "", ""),
1444 U_BOOT_CMD_MKENT(pic, 4, 0, do_image_read_pic, "", ""),
Mingyen Hung96effce2023-09-01 00:39:46 -07001445 U_BOOT_CMD_MKENT(part, 5, 0, do_image_read_part, "", ""),
Bo Lv72d0e902023-01-02 14:27:34 +00001446};
1447
1448static int do_image_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1449{
Bo Lv72d0e902023-01-02 14:27:34 +00001450#ifdef CONFIG_PXP_EMULATOR
1451 printf("\naml log : PXP image all use preload\n");
1452 do { (void)cmd_imgread_sub[0]; } while(0);
1453 return 0;
1454#else
1455 cmd_tbl_t *c;
Meng yufceeb992024-08-06 11:34:39 +08001456 int ret;
Bo Lv72d0e902023-01-02 14:27:34 +00001457
1458 /* Strip off leading 'imgread' command argument */
1459 argc--;
1460 argv++;
1461
1462 c = find_cmd_tbl(argv[0], &cmd_imgread_sub[0], ARRAY_SIZE(cmd_imgread_sub));
1463
1464 if (c) {
Meng yufceeb992024-08-06 11:34:39 +08001465 if (!strcmp("kernel", argv[0]))
1466 PUSH_TIME_TE(__func__, BL33_LOAD_UIMAGE_s);
1467 ret = c->cmd(cmdtp, flag, argc, argv);
1468 if (!strcmp("kernel", argv[0]))
1469 PUSH_TIME_TE(__func__, BL33_LOAD_UIMAGE_e);
1470 return ret;
Bo Lv72d0e902023-01-02 14:27:34 +00001471 } else {
1472 cmd_usage(cmdtp);
1473 return 1;
1474 }
1475#endif //CONFIG_PXP_EMULATOR
1476}
1477
1478U_BOOT_CMD(
1479 imgread, //command name
Mingyen Hung96effce2023-09-01 00:39:46 -07001480 6, //maxargs
Bo Lv72d0e902023-01-02 14:27:34 +00001481 0, //repeatable
1482 do_image_read, //command function
1483 "Read the image from internal flash with actual size", //description
1484 " argv: <imageType> <part_name> <loadaddr> \n" //usage
1485 " - <image_type> Current support is kernel/res(ource).\n"
1486 "imgread kernel --- Read image in format IMAGE_FORMAT_ANDROID\n"
1487 "imgread dtb --- Read dtb in format IMAGE_FORMAT_ANDROID\n"
1488 "imgread res --- Read image packed by 'Amlogic resource packer'\n"
1489 "imgread picture --- Read one picture from Amlogic logo"
Mingyen Hung96effce2023-09-01 00:39:46 -07001490 "imgread part --- Read partition"
Bo Lv72d0e902023-01-02 14:27:34 +00001491 " - e.g. \n"
1492 " to read boot.img from part boot from flash: <imgread kernel boot loadaddr> \n" //usage
1493 " to read recovery.img from part recovery from flash: <imgread kernel recovery loadaddr $offset> \n" //usage
1494 " to read logo.img from part logo from flash: <imgread res logo loadaddr> \n" //usage
1495 " to read one picture named 'bootup' from logo.img from logo: <imgread pic logo bootup loadaddr> \n" //usage
Mingyen Hung96effce2023-09-01 00:39:46 -07001496 " to read partition from from flash: <imgread part <part_name> <load_addr> <offset> <sz>> \n" //usage
Bo Lv72d0e902023-01-02 14:27:34 +00001497);
1498
1499//[imgread pic] logo bootup $loadaddr_misc
1500static int do_unpackimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1501{
1502 unsigned char* loadaddr = 0;
1503 const AmlResImgHead_t* pResImgHead = NULL;
1504 unsigned itemIndex = 0;
1505 const AmlResItemHead_t* pItem = NULL;
1506
1507 loadaddr = (unsigned char*)simple_strtoul(argc > 1 ? argv[1] : env_get("loadaddr_misc"), NULL, 16);
1508
1509 pResImgHead = (AmlResImgHead_t*)loadaddr;
1510 const int totalSz = pResImgHead->imgSz;
1511 unsigned long unCompressBuf = (long)loadaddr + totalSz;
1512
1513 if (img_res_check_log_header(pResImgHead)) {
1514 errorP("Logo header err.\n");
1515 return __LINE__;
1516 }
1517
1518 pItem = (AmlResItemHead_t*)(pResImgHead + 1);
1519 for (itemIndex = 0; itemIndex < pResImgHead->imgItemNum; ++itemIndex, ++pItem)
1520 {
1521 if (IH_MAGIC != pItem->magic) {
1522 errorP("item magic 0x%x != 0x%x\n", pItem->magic, IH_MAGIC);
1523 return __LINE__;
1524 }
1525 char env_name[IH_NMLEN*2];
1526 char env_data[IH_NMLEN*2];
1527 unsigned long picLoadAddr = (unsigned long)loadaddr + (unsigned)pItem->start;
1528
1529 int itemSz = pItem->size;
1530 unsigned long uncompSz = 0;
1531
1532 if (unCompressBuf & 0x7U)
1533 unCompressBuf = ((unCompressBuf + 8) >> 3) << 3;
1534 imgread_uncomp_pic((unsigned char *)picLoadAddr, pItem->size,
1535 (unsigned char *)unCompressBuf, CONFIG_MAX_PIC_LEN, &uncompSz);
1536 if (uncompSz) {
1537 picLoadAddr = (unsigned long)unCompressBuf;
1538 itemSz = uncompSz;
1539 unCompressBuf += uncompSz;
1540 }
1541 sprintf(env_name, "%s_offset", pItem->name);//be bootup_offset ,not bootup_720_offset
1542 sprintf(env_data, "0x%lx", picLoadAddr);
1543 env_set(env_name, env_data);
1544
1545 sprintf(env_name, "%s_size", pItem->name);
1546 sprintf(env_data, "0x%x", itemSz);
1547 env_set(env_name, env_data);
1548 }
1549
1550 return 0;//success
1551}
1552
1553U_BOOT_CMD(
1554 unpackimg, //command name
1555 2, //maxargs
1556 0, //repeatable
1557 do_unpackimg, //command function
1558 "un pack logo image into pictures", //description
1559 " argv: unpackimg <imgLoadaddr> \n" //usage
1560 " un pack the logo image, which already loaded at <imgLoadaddr>.\n"
1561);
1562
1563#if defined(CONFIG_CMD_AUTOSCR)
1564/*
1565 * Keep for now for backward compatibility;
1566 * remove later when support for "autoscr" goes away.
1567 */
1568static int
1569do_autoscr (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1570{
1571 printf ("\n### WARNING ### "
1572 "\"autoscr\" is deprecated, use \"source\" instead ###\n\n");
1573 if (argc < 2) {
1574 printf("too few argc %d for %s\n", argc, argv[0]);
1575 return CMD_RET_FAILURE;
1576 }
1577 env_set("_src_addr", argv[1]);
1578 return run_command("echo _src_addr ${_src_addr}; source ${_src_addr}; env delete _src_addr", 0);
1579}
1580
1581U_BOOT_CMD_COMPLETE(
1582 autoscr, 2, 0, do_autoscr,
1583 "DEPRECATED - use \"source\" command instead",
1584 " argv: autoscr script_mem_addr",
1585 var_complete
1586);
1587#endif//#if defined(CONFIG_CMD_AUTOSCR)
1588
1589#if defined(CONFIG_CMD_EXT4) && defined(CONFIG_MMC_MESON_GX)
1590/*"if ext4load mmc 1:x ${dtb_mem_addr} /recovery/dtb.img; then echo cache dtb.img loaded; fi;"\*/
1591static int do_load_logo_from_ext4(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1592{
1593 if (3 > argc) {
1594 errorP("argc(%d) < 3 illegal\n", argc);
1595 return CMD_RET_USAGE;
1596 }
1597 int iRet = 0;
1598 const char* ext4Part = argv[1];
1599 void* loadaddr = (void*)simple_strtoul(argv[2], NULL, 16);
1600 int autoSelectSlot = 1;//auto detect if need add _a/_b
1601
hao.qi6d47c6a2024-05-20 16:57:16 +08001602 if (argc > 3) {
1603 env_set("ext4LogoPath", argv[3]);
1604 } else {
1605 char *tmp = env_get("usb_status");
1606 char *cc_enable = env_get("cc_enable");
1607
1608 if (tmp && strcmp("0.5a@5v", tmp) == 0 &&
1609 cc_enable && strcmp("1", cc_enable) == 0) {
1610 env_set("ext4LogoPath", "/logo_files/bootup_lowcurrent.bmp");
1611 } else {
1612 env_set("ext4LogoPath", "/logo_files/bootup.bmp");
1613 }
1614 }
Bo Lv72d0e902023-01-02 14:27:34 +00001615 if (argc > 4) {
1616 const char *paraAutoSel = argv[4];
1617
1618 autoSelectSlot = !memcmp(paraAutoSel, "true", 5);
1619 if (!autoSelectSlot && strcmp(paraAutoSel, "false")) {
1620 errorP("illegal para4 %s\n", paraAutoSel);
1621 return CMD_RET_FAILURE;
1622 }
1623 }
1624
1625 if (!loadaddr) {
1626 errorP("illegal loadaddr %s\n", argv[2]);
1627 return CMD_RET_FAILURE;
1628 }
1629
1630 if (BOOT_EMMC != store_get_type() ) {
1631 errorP("only support emmc, but store type %d\n", store_get_type() );
1632 return CMD_RET_FAILURE;
1633 }
1634
1635 env_set("bootLogoPart", ext4Part);
1636 if (autoSelectSlot)
1637 run_command("if test ${active_slot} != normal; then setenv bootLogoPart ${bootLogoPart}${active_slot}; printenv bootLogoPart; fi", 0);
1638 const int partIndex = get_partition_num_by_name(env_get("bootLogoPart"));
1639 if (partIndex < 0) {
1640 errorP("fail find part index for name(%s)\n", env_get("bootLogoPart")); return CMD_RET_FAILURE;
1641 }
1642 env_set_hex("logoPart", partIndex);
1643 env_set_hex("logoLoadAddr", (ulong)loadaddr);
1644 env_set("ext4logoLoadCmd", "ext4load mmc 1:${logoPart} ${logoLoadAddr} ${ext4LogoPath}");
1645 iRet = run_command("printenv ext4logoLoadCmd; run ext4logoLoadCmd", 0);
1646 if (iRet) {
1647 errorP("Fail in load logo cmd\n"); return CMD_RET_FAILURE;
1648 }
1649 MsgP("load bmp from ext4 part okay\n");
1650 run_command("setenv ext4LogoSz ${filesize}", 0);
1651 const int bmpSz = env_get_hex("filesize", 0);
1652 if (bmpSz <= 0) {
1653 errorP("err bmp sz\n"); return CMD_RET_FAILURE;
1654 }
1655
1656#if defined(CONFIG_GZIP)
1657 if (memcmp(loadaddr, gzip_magic, sizeof(gzip_magic))) {
1658 return CMD_RET_SUCCESS;
1659 }
1660 MsgP("gunzip bmp logo\n");
1661 void* uncompress = (char*)loadaddr + (((bmpSz + 0xf)>>4)<<4);
1662 unsigned long uncompSz = 0;
1663 iRet = imgread_uncomp_pic((unsigned char*)loadaddr, bmpSz, (unsigned char*)uncompress,
1664 CONFIG_MAX_PIC_LEN, (unsigned long*)&uncompSz);
1665 if (iRet) {
1666 errorP("Fail in uncomp pic,rc[%d]\n", iRet); return __LINE__;
1667 }
1668 if (uncompSz <= 0) {
1669 errorP("Fail uncompress logo bmp\n"); return CMD_RET_FAILURE;
1670 }
1671 memmove(loadaddr, uncompress, uncompSz);
1672 env_set_hex("ext4LogoSz", uncompSz);
1673#endif//#if defined(CONFIG_GZIP)
1674
1675 return CMD_RET_SUCCESS;
1676}
1677
1678U_BOOT_CMD_COMPLETE(
1679 rdext4pic, //read ext4 picture
1680 5, //maxargs
1681 0, //repeatable
1682 do_load_logo_from_ext4, //command function
1683 "read logo bmp from ext4 part", //description
1684 " argv: rdext4pic <partName> <memAddr> <logoPath>\n" //usage
1685 " load bmp picture from <logoPath> of <partName> to <memAddr>.\n",
1686 var_complete
1687);
1688#endif// #if defined(CONFIG_CMD_EXT4) && defined(CONFIG_MMC_MESON_GX)
1689