blob: 58c03e03d0b2a239b08709305637658fedea4757 [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>
9#include <linux/libfdt.h>
10#include <android_image.h>
11#if defined(CONFIG_ZIRCON_BOOT_IMAGE)
Bo Lv6170c3e2023-04-04 10:56:51 +080012#include <amlogic/zircon/image.h>
Bo Lv72d0e902023-01-02 14:27:34 +000013#endif
Bo Lv4a465022023-02-28 05:51:47 +000014#include <asm/amlogic/arch/bl31_apis.h>
15#include <asm/amlogic/arch/secure_apb.h>
Bo Lv72d0e902023-01-02 14:27:34 +000016#include <amlogic/store_wrapper.h>
17#include <amlogic/aml_efuse.h>
18#include <malloc.h>
Bo Lv4a465022023-02-28 05:51:47 +000019#include <amlogic/emmc_partitions.h>
Bo Lv72d0e902023-01-02 14:27:34 +000020#include <version.h>
21#include <amlogic/image_check.h>
22#include <fs.h>
Bo Lv4a465022023-02-28 05:51:47 +000023#include <gzip.h>
Mingyen Hung96effce2023-09-01 00:39:46 -070024#if CONFIG_PARTITION_ENCRYPTION_LOCAL
25#include <amlogic/partition_encryption.h>
26#endif
Bo Lv72d0e902023-01-02 14:27:34 +000027
28#ifndef IS_FEAT_BOOT_VERIFY
29//#define IS_FEAT_BOOT_VERIFY() 0 //always undefined as IS_FEAT_BOOT_VERIFY is function not marco
30#endif// #ifndef IS_FEAT_BOOT_VERIFY
31int __attribute__((weak)) store_logic_read(const char *name, loff_t off, size_t size, void *buf)
32{ return store_read(name, off, size, buf);}
33
34#define debugP(fmt...) //printf("[Dbg imgread]L%d:", __LINE__),printf(fmt)
35#define errorP(fmt...) do {pr_err("Err imgread(L%d):", __LINE__); pr_err(fmt); } while (0)
36#define wrnP(fmt...) pr_warning("wrn:" fmt)
37#define MsgP(fmt...) pr_info("[imgread]" fmt)
38
39#define IMG_PRELOAD_SZ (1U<<20) //Total read 1M at first to read the image header
40#define PIC_PRELOAD_SZ (8U<<10) //Total read 4k at first to read the image header
41#define RES_OLD_FMT_READ_SZ (8U<<20)
42
43typedef struct __aml_enc_blk{
44 unsigned int nOffset;
45 unsigned int nRawLength;
46 unsigned int nSigLength;
47 unsigned int nAlignment;
48 unsigned int nTotalLength;
49 unsigned char szPad[12];
50 unsigned char szSHA2IMG[32];
51 unsigned char szSHA2KeyID[32];
52}t_aml_enc_blk;
53
54#define AML_SECU_BOOT_IMG_HDR_MAGIC "AMLSECU!"
55#define AML_SECU_BOOT_IMG_HDR_MAGIC_SIZE (8)
56#define AML_SECU_BOOT_IMG_HDR_VESRION (0x0905)
57
58typedef struct {
59
60 unsigned char magic[AML_SECU_BOOT_IMG_HDR_MAGIC_SIZE];//magic to identify whether it is a encrypted boot image
61
62 unsigned int version; //version for this header struct
63 unsigned int nBlkCnt;
64
65 unsigned char szTimeStamp[16];
66
67 t_aml_enc_blk amlKernel;
68 t_aml_enc_blk amlRamdisk;
69 t_aml_enc_blk amlDTB;
70
71} amlencryptbootimginfo;
72
73typedef struct _boot_img_hdr_secure_boot
74{
75 unsigned char reserve4ImgHdr[1024];
76
77 amlencryptbootimginfo encrypteImgInfo;
78
79}AmlSecureBootImgHeader;
80
81typedef struct{
82 unsigned char reserve4ImgHdr[2048];
83
84 amlencryptbootimginfo encrypteImgInfo;
85
86}AmlSecureBootImg9Header;
87
88
89#define COMPILE_TYPE_ASSERT(expr, t) typedef char t[(expr) ? 1 : -1]
90COMPILE_TYPE_ASSERT(2048 >= sizeof(AmlSecureBootImgHeader), _cc);
91
92static int is_andr_9_image(void* pBuffer)
93{
94 boot_img_hdr_t *pAHdr = (boot_img_hdr_t *)(unsigned long)pBuffer;
95 int nReturn = 0;
96
97 if (!pBuffer)
98 goto exit;
99
100 if (pAHdr->header_version)
101 nReturn = 1;
102
103exit:
104
105 return nReturn;
106
107}
108
109static int _aml_get_secure_boot_kernel_size(const void *ploadaddr, u32 *ptotalenckernelsz)
110{
111 const amlencryptbootimginfo *amlencryptebootimginfo = 0;
112 int rc = 0;
113 u32 securekernelimgsz = 2048;
114 u32 nblkcnt = 0;
115 const t_aml_enc_blk *pblkinf = NULL;
116 int secure_boot_enabled = 0;
117 unsigned char *pandhdr = (unsigned char *)ploadaddr;
118
119#ifdef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
120 secure_boot_enabled = 0;//donnot decrypt kernel/dtb if avb2 enabled
121#else
122 secure_boot_enabled = IS_FEAT_BOOT_VERIFY();
123#endif//#ifdef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
124
125#ifdef CONFIG_IMAGE_CHECK
126 rc = __LINE__;
127
128 if (!ploadaddr || !ptotalenckernelsz)
129 return rc;
130
131 if (secure_boot_enabled) {
132 struct aml_boot_header_t *hdr;
133 ulong ncheckoffset = android_image_check_offset();
134
135 hdr = (struct aml_boot_header_t *)(pandhdr + ncheckoffset
136 - sizeof(struct aml_boot_header_t));
137 if (hdr->magic != AML_BOOT_IMAGE_MAGIC || hdr->version != AML_BOOT_IMAGE_VERSION)
138 return rc;
139 *ptotalenckernelsz = hdr->img_size + ncheckoffset;
140 return 0;
141 }
142
143 *ptotalenckernelsz = 0;
144#endif
145 if (is_andr_9_image(pandhdr))
146 securekernelimgsz = 4096;
147
148 amlencryptebootimginfo = (amlencryptbootimginfo *)(pandhdr + (securekernelimgsz >> 1));
149
150 nblkcnt = amlencryptebootimginfo->nBlkCnt;
151
152 *ptotalenckernelsz = 0;
153
154 rc = memcmp(AML_SECU_BOOT_IMG_HDR_MAGIC, amlencryptebootimginfo->magic,
155 AML_SECU_BOOT_IMG_HDR_MAGIC_SIZE);
156 if (rc) { // img NOT signed
157 if (secure_boot_enabled) {
158 errorP("img NOT signed but secure boot enabled\n");
159 return __LINE__;
160 }
161 *ptotalenckernelsz = 0;
162 return 0;
163 }
164 //img signed
165 if (!secure_boot_enabled) {
166 errorP("Img signed but secure boot NOT enabled\n");
167 return __LINE__;
168 }
169
170 if (amlencryptebootimginfo->version != AML_SECU_BOOT_IMG_HDR_VESRION) {
171 errorP("magic ok but version err, err ver=0x%x\n", amlencryptebootimginfo->version);
172 return __LINE__;
173 }
174 MsgP("szTimeStamp[%s]\n", (char *)&amlencryptebootimginfo->szTimeStamp);
175 debugP("nblkcnt=%d\n", nblkcnt);
176
177 for (pblkinf = &amlencryptebootimginfo->amlKernel; nblkcnt--; ++pblkinf) {
178 const unsigned int thisblklen = pblkinf->nTotalLength;
179
180 debugP("thisblklen=0x%x\n", thisblklen);
181 securekernelimgsz += thisblklen;
182 }
183
184 *ptotalenckernelsz = securekernelimgsz;
185 return 0;
186}
187
188static int do_image_read_dtb_from_knl(const char *partname,
189 unsigned char *loadaddr, uint64_t lflashreadinitoff)
190{
191 int ret = __LINE__;
192 unsigned int nflashloadlen = 0;
193 u64 lflashreadoff = 0;
194 const int preloadsz = 4096 * 2;
195 int pagesz = 0;
196 boot_img_hdr_t *hdr_addr = (boot_img_hdr_t *)loadaddr;
197
198 lflashreadoff = lflashreadinitoff;
199 nflashloadlen = preloadsz;//head info is one page size == 2k
200 debugP("sizeof preloadsz=%u\n", nflashloadlen);
201 ret = store_logic_read(partname, lflashreadoff, nflashloadlen, loadaddr);
202 if (ret) {
203 errorP("Fail to read 0x%xB from part[%s] at offset 0\n", nflashloadlen, partname);
204 return __LINE__;
205 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700206#if CONFIG_PARTITION_ENCRYPTION_LOCAL
207 part_dec(partname, (u8*)loadaddr, nflashloadlen, (u8*)loadaddr, nflashloadlen, lflashreadoff);
208#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000209 if (genimg_get_format(hdr_addr) != IMAGE_FORMAT_ANDROID) {
210 errorP("Fmt unsupported! only support 0x%x\n", IMAGE_FORMAT_ANDROID);
211 return __LINE__;
212 }
213
214 if (is_android_r_image((void *)hdr_addr)) {
215 const int preloadsz_r = preloadsz;
216 int rc_r = 0;
217 char *slot_name;
218
219 slot_name = env_get("slot-suffixes");
220 if (strcmp(slot_name, "0") == 0)
221 strcpy((char *)partname, "vendor_boot_a");
222 else if (strcmp(slot_name, "1") == 0)
223 strcpy((char *)partname, "vendor_boot_b");
224 else
225 strcpy((char *)partname, "vendor_boot");
226
227 MsgP("partname = %s\n", partname);
228 nflashloadlen = preloadsz_r;//head info is one page size == 4k
229 debugP("sizeof preloadSz=%u\n", nflashloadlen);
230
231 ret = store_logic_read(partname, lflashreadoff, nflashloadlen, loadaddr);
232 if (ret) {
233 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
234 nflashloadlen, partname);
235 return __LINE__;
236 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700237#if CONFIG_PARTITION_ENCRYPTION_LOCAL
238 part_dec(partname, (u8*)loadaddr, nflashloadlen, (u8*)loadaddr, nflashloadlen, lflashreadoff);
239#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000240 p_vendor_boot_img_hdr_t pvendorimghdr = (p_vendor_boot_img_hdr_t)loadaddr;
241
242 rc_r = vendor_boot_image_check_header(pvendorimghdr);
243 if (!rc_r) {
244 unsigned long ramdisk_size_r, dtb_size_r;
245
246 pagesz = pvendorimghdr->page_size;
247
248 /* Android R's vendor_boot partition include ramdisk and dtb */
249 ramdisk_size_r = ALIGN(pvendorimghdr->vendor_ramdisk_size, pagesz);
250 dtb_size_r = ALIGN(pvendorimghdr->dtb_size, pagesz);
251 nflashloadlen = dtb_size_r;
252 lflashreadoff = ramdisk_size_r + 0x1000;
253 debugP("ramdisk_size_r 0x%x, totalSz 0x%lx\n",
254 pvendorimghdr->vendor_ramdisk_size, ramdisk_size_r);
255 debugP("dtb_size_r 0x%x, totalSz 0x%lx\n",
256 pvendorimghdr->dtb_size, dtb_size_r);
257 debugP("lflashreadoff=0x%llx\n", lflashreadoff);
258 debugP("nflashloadlen=0x%x\n", nflashloadlen);
259 } else {
260 errorP("check vendor_boot header error\n");
261 return __LINE__;
262 }
263
264 } else {
265 pagesz = hdr_addr->page_size;
266 lflashreadoff += pagesz;
267 lflashreadoff += ALIGN(hdr_addr->kernel_size, pagesz);
268 lflashreadoff += ALIGN(hdr_addr->ramdisk_size, pagesz);
269 nflashloadlen = ALIGN(hdr_addr->second_size, pagesz);
270 }
271
272 debugP("lflashreadoff=0x%llx, nflashloadlen=0x%x\n", lflashreadoff, nflashloadlen);
273 debugP("page sz %u\n", hdr_addr->page_size);
274 if (!nflashloadlen) {
275 errorP("NO second part in kernel image\n");
276 return __LINE__;
277 }
278 unsigned char *secondaddr = (unsigned char *)loadaddr + lflashreadoff;
279
280 loff_t wroff = lflashreadoff;
281 size_t wrsz = nflashloadlen;
282 unsigned char *wraddr = secondaddr;
283#if !defined(CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK) && defined(CONFIG_IMAGE_CHECK)
284 u32 securekernelimgsz = 0;
285
286 ret = _aml_get_secure_boot_kernel_size(loadaddr, &securekernelimgsz);
287 if (ret) {
288 errorP("Fail in _aml_get_secure_boot_kernel_size, rc=%d\n", ret);
289 return __LINE__;
290 }
291
292 if (securekernelimgsz) {
293 debugP("secure kernel sz 0x%x\n", securekernelimgsz);
294 wrsz = securekernelimgsz - preloadsz;
295 wroff = lflashreadinitoff + preloadsz;
296 wraddr = (unsigned char *)loadaddr + preloadsz;
297 }
298#endif//#if !defined(CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK) && defined(CONFIG_IMAGE_CHECK)
299 if ((BOOT_NAND_MTD == store_get_type() || BOOT_SNAND == store_get_type())) {
300 unsigned notAlignSz = wroff & 0xfff;
301
302 wroff -= notAlignSz;
303 wrsz += notAlignSz;
304 secondaddr += notAlignSz;
305 MsgP("not align dtb off 0x%llx\n", wroff);
306 }
307 ret = store_logic_read(partname, wroff, wrsz, wraddr);
308 if (ret) {
309 errorP("Fail to read 0x%xB from part[%s] at offset 0x%x\n",
310 (unsigned int)wrsz, partname, (unsigned int)wroff);
311 return __LINE__;
312 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700313#if CONFIG_PARTITION_ENCRYPTION_LOCAL
314 part_dec(partname, (u8*)wraddr, wrsz, (u8*)wraddr, wrsz, wroff);
315#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000316#ifndef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
317 if (IS_FEAT_BOOT_VERIFY()) {
318#ifndef CONFIG_IMAGE_CHECK
319 //because secure boot will use DMA which need disable MMU temp
320 //here must update the cache, otherwise nand will fail (eMMC is OK)
321 flush_cache((unsigned long)secondaddr, (unsigned long)nflashloadlen);
322
323 ret = aml_sec_boot_check(AML_D_P_IMG_DECRYPT, (unsigned long)loadaddr,
324 GXB_IMG_SIZE, GXB_IMG_DEC_DTB);
325#else
326 //because secure boot will use DMA which need disable MMU temp
327 //here must update the cache, otherwise nand will fail (eMMC is OK)
328 flush_cache((unsigned long)loadaddr, (unsigned long)securekernelimgsz);
329
330 ret = secure_image_check((uint8_t *)(unsigned long)loadaddr,
331 GXB_IMG_SIZE, GXB_IMG_DEC_DTB);
332 secondaddr += android_image_check_offset();
333#endif
334 if (ret) {
335 errorP("\n[dtb]aml log : Sig Check is %d\n", ret);
336 return __LINE__;
337 }
338 MsgP("decrypted dtb sz 0x%x\n", nflashloadlen);
339 }
340#endif
341 char *dtdestaddr = (char *)loadaddr;//simple_strtoull(getenv("dtb_mem_addr"), NULL, 0);
342
343 memmove(dtdestaddr, secondaddr, nflashloadlen);
344
345 return ret;
346}
347
348/*uint32_t store_rsv_size(const char *name);*/
349static int do_image_read_dtb_from_rsv(unsigned char* loadaddr)
350{
351 const int dtbmaxsz = store_rsv_size("dtb");
352
353 if (dtbmaxsz < 0x400) {
354 errorP("dtbmaxsz(0x%x) invalid\n", dtbmaxsz);
355 return -__LINE__;
356 }
357 int ret = store_rsv_read("dtb", dtbmaxsz, loadaddr);
358
359 if (ret) {
360 errorP("Fail read dtb from rsv with sz 0x%x\n", dtbmaxsz);
361 return -__LINE__;
362 }
363#ifndef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
364 if (IS_FEAT_BOOT_VERIFY()) {
365 flush_cache((unsigned long)loadaddr, dtbmaxsz);
366#ifndef CONFIG_IMAGE_CHECK
367 ret = aml_sec_boot_check(AML_D_P_IMG_DECRYPT, (long)loadaddr, dtbmaxsz, 0);
368#else
369 ret = secure_image_check((uint8_t *)(unsigned long)loadaddr, dtbmaxsz, 0);
370 memmove(loadaddr, (void *)(loadaddr + sizeof(struct aml_boot_header_t)), dtbmaxsz);
371#endif
372 if (ret) {
373 MsgP("decrypt dtb: Sig Check %d\n", ret);
374 return -__LINE__;
375 }
376 }
377#endif
378 return 0;
379}
380
381//imgread dtb boot ${dtb_mem_addr}
382//imgread dtb rsv ${dtb_mem_addr}
383static int do_image_read_dtb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
384{
385 int iRet = 0;
Sam Wu6f3d40e2023-04-22 01:10:27 +0800386 const char partName[64] = {0};
Bo Lv72d0e902023-01-02 14:27:34 +0000387 unsigned char* loadaddr = 0;
388 uint64_t lflashReadOff = 0;
Sam Wu6f3d40e2023-04-22 01:10:27 +0800389
390 strlcpy((char *)partName, argv[1], 64);
Bo Lv72d0e902023-01-02 14:27:34 +0000391 if (2 < argc) {
392 loadaddr = (unsigned char*)simple_strtoul(argv[2], NULL, 16);
393 } else{
394 loadaddr = (unsigned char*)simple_strtoul(env_get("loadaddr"), NULL, 16);
395 }
396
397 if (3 < argc) lflashReadOff = simple_strtoull(argv[3], NULL, 0) ;
398
399 const int fromRsv = !strcmp("_aml_dtb", argv[1]);
400 if ( fromRsv ) {
401 iRet = do_image_read_dtb_from_rsv(loadaddr);
402 } else {
403 iRet = do_image_read_dtb_from_knl(partName, loadaddr, lflashReadOff);
404 }
405 if (iRet) {
406 errorP("Fail read dtb from %s, ret %d\n", partName, iRet);
407 return CMD_RET_FAILURE;
408 }
409
410 unsigned long fdtAddr = (unsigned long)loadaddr;
411#ifdef CONFIG_MULTI_DTB
412 extern unsigned long get_multi_dt_entry(unsigned long fdt_addr);
413 fdtAddr = get_multi_dt_entry((unsigned long)fdtAddr);
414 if (!fdtAddr) {
415 errorP("Fail in get_multi_dt_entry\n");
416 return __LINE__;
417 }
418#endif// #ifdef CONFIG_MULTI_DTB
419 iRet = fdt_check_header((char*)fdtAddr);
420 if (iRet) {
421 errorP("Fail in fdt check header\n");
422 return CMD_RET_FAILURE;
423 }
424 const unsigned fdtsz = fdt_totalsize((char*)fdtAddr);
425 memmove(loadaddr, (char*)fdtAddr, fdtsz);
426
427 return iRet;
428}
429
Bo Lv77426d62023-08-11 19:05:38 +0800430uint32_t get_rsv_mem_size(void)
431{
432 uint32_t rsv_start, reg_size, rsv_size;
433#if defined(P_AO_SEC_GP_CFG3)
434 rsv_start = *((volatile uint32_t *)((uintptr_t)(P_AO_SEC_GP_CFG5)));
435 reg_size = *((volatile uint32_t *)((uintptr_t)(P_AO_SEC_GP_CFG3)));
436#elif defined(SYSCTRL_SEC_STATUS_REG15)
437 rsv_start = *((volatile uint32_t *)((uintptr_t)(SYSCTRL_SEC_STATUS_REG17)));
438 reg_size = *((volatile uint32_t *)((uintptr_t)(SYSCTRL_SEC_STATUS_REG15)));
439#endif
440 if ((reg_size >> 16) & 0xff)
441 rsv_size = (((reg_size & 0xffff0000) >> 16) << 16) +
442 ((reg_size & 0x0000ffff) << 16);
443 else
444 rsv_size = (((reg_size & 0xffff0000) >> 16) << 10) +
445 ((reg_size & 0x0000ffff) << 10);
446
447 return (rsv_start + rsv_size);
448}
449
Mingyen Hung96effce2023-09-01 00:39:46 -0700450static int do_image_read_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
451{
452 const char *name = NULL;
453 uint64_t addr = 0;
454 uint64_t offset = 0;
455 uint64_t sz = 0;
456 int rc = 0;
457
458 if (argc < 4 || argc > 5) {
459 return CMD_RET_USAGE;
460 }
461 name = argv[1];
462 addr = simple_strtoull(argv[2], NULL, 16);
463 offset = simple_strtoull(argv[3], NULL, 0);
464
465 if (argc == 5)
466 sz = simple_strtoull(argv[4], NULL, 0);
467 else
468 sz = store_logic_cap(name);
469
470 printf("read %s with %llu bytes at offset %llu to addr %#llx\n",
471 name, sz, offset, addr);
472
473 rc = store_logic_read(name, offset, sz, (void*)addr);
474 if (rc) {
475 printf("Failed to read %s with %llu bytes at offset %llu\n",
476 name, sz, offset);
477 goto out;
478 }
479#if CONFIG_PARTITION_ENCRYPTION_LOCAL
480 part_dec(name, (u8*)addr, sz, (u8*)addr, sz, offset);
481#endif
482out:
483 return rc;
484}
Bo Lv72d0e902023-01-02 14:27:34 +0000485static int do_image_read_kernel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
486{
487 unsigned kernel_size;
488 unsigned ramdisk_size;
489 boot_img_hdr_t *hdr_addr = NULL;
490 int genFmt = 0;
491 u32 actualbootimgsz = 0;
492 u32 dtbsz = 0;
493 const char *const partname = argv[1];
494 unsigned char* loadaddr = 0;
495 int rc = 0;
496 u64 flashreadoff = 0;
497 u32 securekernelimgsz = 0;
498 char *upgrade_step_s = NULL;
499 bool cache_flag = false;
Bo Lvda8d5b72023-07-31 14:58:21 +0800500 ulong kernelEndAddr = 0;
501 ulong kernelLoadAddr = 0;
502 ulong dtbLoadAddr = 0;
Bo Lv77426d62023-08-11 19:05:38 +0800503 ulong secMemSize = get_rsv_mem_size();
Bo Lvda8d5b72023-07-31 14:58:21 +0800504 char strAddr[128] = {0};
Bo Lv72d0e902023-01-02 14:27:34 +0000505
Bo Lvda8d5b72023-07-31 14:58:21 +0800506 if (argc > 2) {
Bo Lv72d0e902023-01-02 14:27:34 +0000507 loadaddr = (unsigned char *)simple_strtoul(argv[2], NULL, 16);
Bo Lvda8d5b72023-07-31 14:58:21 +0800508 env_set("loadaddr", (const char *)argv[2]);
509 } else {
Bo Lv72d0e902023-01-02 14:27:34 +0000510 loadaddr = (unsigned char *)simple_strtoul(env_get("loadaddr"), NULL, 16);
Bo Lvda8d5b72023-07-31 14:58:21 +0800511 }
Bo Lv72d0e902023-01-02 14:27:34 +0000512
513 hdr_addr = (boot_img_hdr_t *)loadaddr;
514
515 if (argc > 3)
516 flashreadoff = simple_strtoull(argv[3], NULL, 0);
517
518 upgrade_step_s = env_get("upgrade_step");
519 if (upgrade_step_s && (strcmp(upgrade_step_s, "3") == 0) &&
520 (strcmp(partname, "recovery") == 0)) {
521 loff_t len_read;
522
523 MsgP("read recovery.img from cache\n");
524 rc = fs_set_blk_dev("mmc", "1:2", FS_TYPE_EXT);
525 if (rc) {
526 errorP("Fail to set blk dev cache\n");
527 cache_flag = false;
528 } else {
529 fs_read("/recovery/recovery.img", (unsigned long)loadaddr,
530 flashreadoff, IMG_PRELOAD_SZ, &len_read);
531 if (IMG_PRELOAD_SZ != len_read) {
532 errorP("Fail to read recovery.img from cache\n");
533 cache_flag = false;
534 } else {
535 cache_flag = true;
536 }
537 }
538 }
539
540 if (!cache_flag) {
541 MsgP("read from part: %s\n", partname);
542 rc = store_logic_read(partname, flashreadoff, IMG_PRELOAD_SZ, loadaddr);
543 if (rc) {
544 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
545 IMG_PRELOAD_SZ, partname);
546 return __LINE__;
547 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700548#if CONFIG_PARTITION_ENCRYPTION_LOCAL
549 part_dec(partname, (u8*)loadaddr, IMG_PRELOAD_SZ, (u8*)loadaddr, IMG_PRELOAD_SZ, flashreadoff);
550#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000551 }
552 flashreadoff += IMG_PRELOAD_SZ;
553
554 if (!is_android_r_image((void *)hdr_addr)) {
555
556 /*free vendor buffer first*/
557 if (p_vender_boot_img) {
558 free(p_vender_boot_img);
559 p_vender_boot_img = 0;
560 }
561 genFmt = genimg_get_format(hdr_addr);
562#if defined(CONFIG_ZIRCON_BOOT_IMAGE)
563 if (IMAGE_FORMAT_ANDROID != genFmt && IMAGE_FORMAT_ZIRCON != genFmt) {
564 errorP("Fmt 0x%x unsupported!, supported genFmt 0x%x or 0x%x\n", genFmt,
565 IMAGE_FORMAT_ANDROID, IMAGE_FORMAT_ZIRCON);
566#else
567 if (IMAGE_FORMAT_ANDROID != genFmt) {
568 errorP("Fmt unsupported!genFmt 0x%x != 0x%x\n", genFmt, IMAGE_FORMAT_ANDROID);
569#endif
570 return __LINE__;
571 }
572
573 //Check if encrypted image
574 rc = _aml_get_secure_boot_kernel_size(loadaddr, &securekernelimgsz);
575 if (rc) {
576 errorP("Fail in _aml_get_secure_boot_kernel_size, rc=%d\n", rc);
577 return __LINE__;
578 }
579 if (securekernelimgsz) {
580 actualbootimgsz = securekernelimgsz;
581 MsgP("securekernelimgsz=0x%x\n", actualbootimgsz);
582 }
583 else {
584 kernel_size =(hdr_addr->kernel_size + (hdr_addr->page_size-1)+hdr_addr->page_size)&(~(hdr_addr->page_size -1));
585 ramdisk_size =(hdr_addr->ramdisk_size + (hdr_addr->page_size-1))&(~(hdr_addr->page_size -1));
586 dtbsz = hdr_addr->second_size;
587 actualbootimgsz = kernel_size + ramdisk_size + dtbsz;
588 debugP("kernel_size 0x%x, page_size 0x%x, totalSz 0x%x\n", hdr_addr->kernel_size, hdr_addr->page_size, kernel_size);
589 debugP("ramdisk_size 0x%x, totalSz 0x%x\n", hdr_addr->ramdisk_size, ramdisk_size);
590 debugP("dtbSz 0x%x, Total actualbootimgsz 0x%x\n", dtbsz, actualbootimgsz);
591 }
592
593#if defined(CONFIG_ZIRCON_BOOT_IMAGE)
594 if (genFmt == IMAGE_FORMAT_ZIRCON) {
595 const zbi_header_t *zbi = (zbi_header_t *)hdr_addr;
596
597 actualbootimgsz = zbi->length + sizeof(*zbi);
598 }
599#endif//#if defined(CONFIG_ZIRCON_BOOT_IMAGE)
600
601 if (actualbootimgsz > IMG_PRELOAD_SZ) {
602 const u32 leftsz = actualbootimgsz - IMG_PRELOAD_SZ;
603
Bo Lvda8d5b72023-07-31 14:58:21 +0800604 /* auto adjust kernel image load address avoid
605 * touch iotrace data and secureOS memory space
606 */
607 kernelLoadAddr =
608 env_get_ulong("loadaddr", 16, KERNEL_DEFAULT_LOAD_ADDR);
609 kernelEndAddr = kernelLoadAddr + actualbootimgsz;
610 dtbLoadAddr = env_get_ulong("dtb_mem_addr", 16, DTB_LOAD_ADDR);
Bo Lv77426d62023-08-11 19:05:38 +0800611 if (kernelEndAddr > IOTRACE_LOAD_ADDR && kernelLoadAddr < secMemSize) {
Bo Lvda8d5b72023-07-31 14:58:21 +0800612 kernelLoadAddr = kernelLoadAddr -
613 ALIGN((kernelEndAddr - IOTRACE_LOAD_ADDR), LOAD_ADDR_ALIGN_LENGTH);
614 if (kernelLoadAddr <= dtbLoadAddr)
615 kernelLoadAddr = KERNEL_LOAD_HIGH_ADDR;
616 sprintf(strAddr, "%lx", kernelLoadAddr);
617 memmove((void *)kernelLoadAddr, (void *)loadaddr, IMG_PRELOAD_SZ);
618 env_set("loadaddr", strAddr);
Bo Lv77426d62023-08-11 19:05:38 +0800619 env_set("loadaddr_kernel", strAddr);
Bo Lvda8d5b72023-07-31 14:58:21 +0800620 loadaddr = (unsigned char *)
621 env_get_ulong("loadaddr", 16, kernelLoadAddr);
622 printf("kernel overlap iotrace, reset kernelLoadAddr = 0x%lx\n",
623 kernelLoadAddr);
624 }
Bo Lv72d0e902023-01-02 14:27:34 +0000625 debugP("Left sz 0x%x\n", leftsz);
626 rc = store_logic_read(partname, flashreadoff,
627 leftsz, loadaddr + IMG_PRELOAD_SZ);
628 if (rc) {
629 errorP("Fail to read 0x%xB from part[%s] at offset 0x%x\n",
630 leftsz, partname, IMG_PRELOAD_SZ);
631 return __LINE__;
632 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700633#if CONFIG_PARTITION_ENCRYPTION_LOCAL
634 part_dec(partname, (u8*)(loadaddr + IMG_PRELOAD_SZ), leftsz,
635 (u8*)(loadaddr + IMG_PRELOAD_SZ), leftsz, flashreadoff);
636#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000637 }
638 debugP("totalSz=0x%x\n", actualbootimgsz);
639
640 //because secure boot will use DMA which need disable MMU temp
641 //here must update the cache, otherwise nand will fail (eMMC is OK)
642 flush_cache((unsigned long)loadaddr, (unsigned long)actualbootimgsz);
643
644 return 0;
645 }
646 else {
647 char partname_init[32] = {0};
648 u64 rc_init;
649 char *slot_name;
650 p_boot_img_hdr_v3_t hdr_addr_v3 = NULL;
651
652 init_boot_ramdisk_size = 0;
653 slot_name = env_get("slot-suffixes");
654 if (slot_name && (strcmp(slot_name, "0") == 0))
655 strcpy((char *)partname_init, "init_boot_a");
656 else if (slot_name && (strcmp(slot_name, "1") == 0))
657 strcpy((char *)partname_init, "init_boot_b");
658 else
659 strcpy((char *)partname_init, "init_boot");
660
661 rc_init = store_part_size(partname_init);
662
663 /*free vendor buffer first*/
664 if (p_vender_boot_img) {
665 free(p_vender_boot_img);
666 p_vender_boot_img = 0;
667 }
668
669 genFmt = genimg_get_format(hdr_addr);
670 if (IMAGE_FORMAT_ANDROID != genFmt) {
671 errorP("Fmt unsupported!genFmt 0x%x != 0x%x\n", genFmt, IMAGE_FORMAT_ANDROID);
672 return __LINE__;
673 }
674
675 //Check if encrypted image
676 rc = _aml_get_secure_boot_kernel_size(loadaddr, &securekernelimgsz);
677 if (rc) {
678 errorP("Fail in _aml_get_secure_boot_kernel_size, rc=%d\n", rc);
679 return __LINE__;
680 }
681
682 hdr_addr_v3 = (p_boot_img_hdr_v3_t)hdr_addr;
683 kernel_size = ALIGN(hdr_addr_v3->kernel_size, 0x1000);
684
685 ramdisk_size = ALIGN(hdr_addr_v3->ramdisk_size, 0x1000);
686
687 MsgP("kernel_size 0x%x, totalSz 0x%x\n",
688 hdr_addr_v3->kernel_size, kernel_size);
689 MsgP("ramdisk_size 0x%x, totalSz 0x%x\n",
690 hdr_addr_v3->ramdisk_size, ramdisk_size);
691 MsgP("boot header_version = %d\n", hdr_addr_v3->header_version);
692 if (securekernelimgsz) {
693 actualbootimgsz = securekernelimgsz;
694 MsgP("securekernelimgsz=0x%x\n", actualbootimgsz);
695 } else {
696 actualbootimgsz = kernel_size + ramdisk_size + 0x1000;
697 }
698
699 if (actualbootimgsz > IMG_PRELOAD_SZ) {
700 const u32 leftsz = actualbootimgsz - IMG_PRELOAD_SZ;
701
Bo Lvda8d5b72023-07-31 14:58:21 +0800702 /* auto adjust kernel image load address avoid
703 * touch iotrace data and secureOS memory space
704 */
705 kernelLoadAddr =
706 env_get_ulong("loadaddr", 16, KERNEL_DEFAULT_LOAD_ADDR);
707 kernelEndAddr = kernelLoadAddr + actualbootimgsz;
708 dtbLoadAddr = env_get_ulong("dtb_mem_addr", 16, DTB_LOAD_ADDR);
Bo Lv77426d62023-08-11 19:05:38 +0800709 if (kernelEndAddr > IOTRACE_LOAD_ADDR && kernelLoadAddr < secMemSize) {
Bo Lvda8d5b72023-07-31 14:58:21 +0800710 kernelLoadAddr = kernelLoadAddr -
711 ALIGN((kernelEndAddr - IOTRACE_LOAD_ADDR), LOAD_ADDR_ALIGN_LENGTH);
712 if (kernelLoadAddr <= dtbLoadAddr)
713 kernelLoadAddr = KERNEL_LOAD_HIGH_ADDR;
714 sprintf(strAddr, "%lx", kernelLoadAddr);
715 memmove((void *)kernelLoadAddr, (void *)loadaddr, IMG_PRELOAD_SZ);
716 env_set("loadaddr", strAddr);
Bo Lv77426d62023-08-11 19:05:38 +0800717 env_set("loadaddr_kernel", strAddr);
Bo Lvda8d5b72023-07-31 14:58:21 +0800718 loadaddr = (unsigned char *)
719 env_get_ulong("loadaddr", 16, kernelLoadAddr);
720 printf("kernel overlap iotrace, reset kernelLoadAddr = 0x%lx\n",
721 kernelLoadAddr);
722 }
723
Bo Lv72d0e902023-01-02 14:27:34 +0000724 debugP("Left sz 0x%x\n", leftsz);
725
726 if (upgrade_step_s && (strcmp(upgrade_step_s, "3") == 0) &&
727 (strcmp(partname, "recovery") == 0)) {
728 loff_t len_read;
729
730 MsgP("read recovery.img from cache\n");
731 rc = fs_set_blk_dev("mmc", "1:2", FS_TYPE_EXT);
732 if (rc) {
733 errorP("Fail to set blk dev cache\n");
734 cache_flag = false;
735 } else {
736 fs_read("/recovery/recovery.img",
737 (unsigned long)loadaddr,
738 0, actualbootimgsz, &len_read);
739 if (actualbootimgsz != len_read) {
740 errorP("Fail to read recovery.img from cache\n");
741 cache_flag = false;
742 } else {
743 cache_flag = true;
744 }
745 }
746 }
747 if (!cache_flag) {
748 MsgP("read from part: %s\n", partname);
749 rc = store_logic_read(partname, flashreadoff,
750 leftsz, loadaddr + IMG_PRELOAD_SZ);
751 if (rc) {
752 errorP("Fail to read 0x%xB from part[%s] at offset 0x%x\n",
753 leftsz, partname, IMG_PRELOAD_SZ);
754 return __LINE__;
755 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700756#if CONFIG_PARTITION_ENCRYPTION_LOCAL
757 part_dec(partname, (u8*)(loadaddr + IMG_PRELOAD_SZ), leftsz,
758 (u8*)(loadaddr + IMG_PRELOAD_SZ), leftsz, flashreadoff);
759#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000760 if (rc_init != -1) {
761 MsgP("read header from part: %s\n", partname_init);
762 unsigned int nflashloadlen_init = 0;
763 const int preloadsz_init = 0x1000 * 2;
764 unsigned char *pbuffpreload_init = 0;
765
766 nflashloadlen_init = preloadsz_init;
767 debugP("sizeof preloadSz=%u\n", nflashloadlen_init);
768
769 pbuffpreload_init = malloc(preloadsz_init);
770
771 if (!pbuffpreload_init) {
772 printf("Fail to allocate memory for %s!\n",
773 partname_init);
774 return __LINE__;
775 }
776
777 rc = store_logic_read(partname_init, 0,
778 nflashloadlen_init, pbuffpreload_init);
779 if (rc) {
780 errorP("Fail to read 0x%xB from part[%s]\n",
781 nflashloadlen_init, partname_init);
782 free(pbuffpreload_init);
783 pbuffpreload_init = 0;
784 return __LINE__;
785 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700786#if CONFIG_PARTITION_ENCRYPTION_LOCAL
787 part_dec(partname_init, (u8*)pbuffpreload_init, nflashloadlen_init,
788 (u8*)pbuffpreload_init, nflashloadlen_init, 0);
789#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000790 p_boot_img_hdr_v3_t pinitbootimghdr;
791
792 pinitbootimghdr = (p_boot_img_hdr_v3_t)pbuffpreload_init;
793
794 ramdisk_size = ALIGN(pinitbootimghdr->ramdisk_size,
795 0x1000);
796 MsgP("ramdisk_size 0x%x, totalSz 0x%x\n",
797 pinitbootimghdr->ramdisk_size, ramdisk_size);
798 MsgP("init_boot header_version = %d\n",
799 pinitbootimghdr->header_version);
800 init_boot_ramdisk_size = pinitbootimghdr->ramdisk_size;
801
802 if (init_boot_ramdisk_size != 0) {
803 MsgP("read ramdisk from part: %s\n", partname_init);
804 rc = store_logic_read(partname_init,
805 BOOT_IMG_V3_HDR_SIZE,
806 ramdisk_size,
807 loadaddr + kernel_size
808 + BOOT_IMG_V3_HDR_SIZE);
809 if (rc) {
810 errorP("Fail to read 0x%xB from part[%s]\n",
811 ramdisk_size, partname_init);
812 free(pbuffpreload_init);
813 pbuffpreload_init = 0;
814 return __LINE__;
815 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700816#if CONFIG_PARTITION_ENCRYPTION_LOCAL
817 part_dec(partname_init, (u8*)(loadaddr + kernel_size + BOOT_IMG_V3_HDR_SIZE),
818 ramdisk_size,
819 (u8*)(loadaddr + kernel_size + BOOT_IMG_V3_HDR_SIZE),
820 ramdisk_size,
821 BOOT_IMG_V3_HDR_SIZE);
822#endif
823
Bo Lv72d0e902023-01-02 14:27:34 +0000824 }
825 free(pbuffpreload_init);
826 pbuffpreload_init = 0;
827 }
828 }
829 }
830 debugP("totalSz=0x%x\n", actualbootimgsz);
831 /*
832 *because secure boot will use DMA which need disable MMU temp
833 *here must update the cache, otherwise nand will fail (eMMC is OK)
834 */
835 flush_cache((unsigned long)loadaddr, (unsigned long)actualbootimgsz);
836
837 /*
838 *Android R need read vendor_boot partition
839 *define Android R variable add suffix xxx_r
840 */
841 char partname_r[32] = {0};
842 int ret_r = __LINE__;
843 u64 lflashreadoff_r = 0;
844 unsigned int nflashloadlen_r = 0;
845 const int preloadsz_r = 0x1000 * 2;//4k not enough for signed
846 p_vendor_boot_img_hdr_t pbuffpreload = 0;
847 u64 vendorboot_part_sz = 0;
848 int rc_r = 0;
849
850 if (strcmp(slot_name, "0") == 0)
851 strcpy((char *)partname_r, "vendor_boot_a");
852 else if (strcmp(slot_name, "1") == 0)
853 strcpy((char *)partname_r, "vendor_boot_b");
854 else
855 strcpy((char *)partname_r, "vendor_boot");
856
857 MsgP("partname_r = %s\n", partname_r);
858 vendorboot_part_sz = store_part_size(partname_r);
859
860 nflashloadlen_r = preloadsz_r; //head info is one page size == 4k
861 debugP("sizeof preloadSz=%u\n", nflashloadlen_r);
862
863 pbuffpreload = malloc(preloadsz_r);
864
Bo Lv56db47f2023-07-10 11:32:25 +0800865 memset((void *)pbuffpreload, 0, preloadsz_r);
866
Bo Lv72d0e902023-01-02 14:27:34 +0000867 if (!pbuffpreload) {
868 printf("aml log : system error! Fail to allocate memory for %s!\n",
869 partname_r);
870 return __LINE__;
871 }
872
873 if (upgrade_step_s && (strcmp(upgrade_step_s, "3") == 0) &&
874 (strcmp(partname_r, "vendor_boot") == 0)) {
875 loff_t len_read;
876
877 MsgP("read vendor_boot from cache\n");
878 ret_r = fs_set_blk_dev("mmc", "1:2", FS_TYPE_EXT);
879 if (ret_r) {
880 errorP("Fail to set blk dev cache\n");
881 cache_flag = false;
882 } else {
883 fs_read("/recovery/vendor_boot.img",
884 (unsigned long)pbuffpreload,
885 0, nflashloadlen_r, &len_read);
886 if (nflashloadlen_r != len_read) {
887 errorP("Fail to read vendor_boot.img from cache\n");
888 cache_flag = false;
889 } else {
890 cache_flag = true;
891 }
892 }
893 }
894 if (!cache_flag) {
895 MsgP("read from part: %s\n", partname_r);
896 ret_r = store_logic_read(partname_r, lflashreadoff_r,
897 nflashloadlen_r, pbuffpreload);
898 if (ret_r) {
899 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
900 nflashloadlen_r, partname_r);
901 free(pbuffpreload);
902 pbuffpreload = 0;
903 return __LINE__;
904 }
Mingyen Hung96effce2023-09-01 00:39:46 -0700905#if CONFIG_PARTITION_ENCRYPTION_LOCAL
906 part_dec(partname_r, (u8*)pbuffpreload, nflashloadlen_r,
907 (u8*)pbuffpreload, nflashloadlen_r, lflashreadoff_r);
908#endif
909
Bo Lv72d0e902023-01-02 14:27:34 +0000910 }
911 p_vendor_boot_img_hdr_t pvendorimghdr = (p_vendor_boot_img_hdr_t)pbuffpreload;
912
913 rc_r = vendor_boot_image_check_header(pvendorimghdr);
914 if (!rc_r) {
915 //Check if encrypted image
916 rc_r = _aml_get_secure_boot_kernel_size(pbuffpreload, &securekernelimgsz);
917 if (rc_r) {
918 errorP("Fail in _aml_get_secure_boot_kernel_size, rc=%d\n", rc_r);
919 free(pbuffpreload);
920 pbuffpreload = 0;
921 return __LINE__;
922 }
923 if (securekernelimgsz) {
924 nflashloadlen_r = securekernelimgsz;
925 MsgP("securekernelimgsz=0x%x\n", nflashloadlen_r);
926 } else {
927 unsigned long ramdisk_size_r, dtb_size_r;
928 unsigned long ramdisk_table_size;
929 const int pagesz_r = pvendorimghdr->page_size;
930
931 /* Android R's vendor_boot partition include ramdisk and dtb */
932 ramdisk_size_r = ALIGN(pvendorimghdr->vendor_ramdisk_size,
933 pagesz_r);
934 dtb_size_r = ALIGN(pvendorimghdr->dtb_size, pagesz_r);
935 nflashloadlen_r = ramdisk_size_r + dtb_size_r + 0x1000;
936 MsgP("ramdisk_size_r 0x%x, totalSz 0x%lx\n",
937 pvendorimghdr->vendor_ramdisk_size, ramdisk_size_r);
938 MsgP("dtb_size_r 0x%x, totalSz 0x%lx\n",
939 pvendorimghdr->dtb_size, dtb_size_r);
940 MsgP("vendor_boot header_version = %d\n",
941 pvendorimghdr->header_version);
942 if (pvendorimghdr->header_version > 3) {
943 MsgP("vendor_ramdisk_table_size: 0x%x\n",
944 pvendorimghdr->vendor_ramdisk_table_size);
945 MsgP("vendor_ramdisk_table_entry_num: 0x%x\n",
946 pvendorimghdr->vendor_ramdisk_table_entry_num);
947 MsgP("vendor_ramdisk_table_entry_size: 0x%x\n",
948 pvendorimghdr->vendor_ramdisk_table_entry_size);
949 MsgP("vendor_bootconfig_size: 0x%x\n",
950 pvendorimghdr->vendor_bootconfig_size);
951 ramdisk_table_size =
952 ALIGN(pvendorimghdr->vendor_ramdisk_table_size,
953 pagesz_r);
954 nflashloadlen_r = nflashloadlen_r + ramdisk_table_size;
955
956 MsgP("ramdisk table offset 0x%lx, nflashloadlen_r 0x%x\n",
957 ramdisk_size_r + dtb_size_r + 0x1000, nflashloadlen_r);
958 }
959 }
960 if (nflashloadlen_r > vendorboot_part_sz) {
961 errorP("nflashloadlen_r 0x%x > vendorboot_part_sz 0x%llx\n",
962 nflashloadlen_r, vendorboot_part_sz);
Bo Lv56db47f2023-07-10 11:32:25 +0800963 free(pbuffpreload);
964 pbuffpreload = 0;
Bo Lv72d0e902023-01-02 14:27:34 +0000965 return __LINE__;
966 }
967
968 if (nflashloadlen_r > preloadsz_r) {
969 free(pbuffpreload);
970 pbuffpreload = malloc(nflashloadlen_r);
971 memset(pbuffpreload, 0, nflashloadlen_r);
972 if (!pbuffpreload)
973 return __LINE__;
974 if (upgrade_step_s && (strcmp(upgrade_step_s, "3") == 0) &&
975 (strcmp(partname_r, "vendor_boot") == 0)) {
976 loff_t len_read;
977
978 MsgP("recovery mode, read vendor_boot from cache\n");
979 ret_r = fs_set_blk_dev("mmc", "1:2", FS_TYPE_EXT);
980 if (ret_r) {
981 errorP("Fail to set blk dev cache\n");
982 cache_flag = false;
983 } else {
984 fs_read("/recovery/vendor_boot.img",
985 (unsigned long)pbuffpreload,
986 lflashreadoff_r, nflashloadlen_r,
987 &len_read);
988 if (nflashloadlen_r != len_read) {
989 errorP("Fail to read from cache\n");
990 cache_flag = false;
991 } else {
992 cache_flag = true;
993 }
994 }
995 }
996 if (!cache_flag) {
997 MsgP("read from part: %s\n", partname_r);
998 rc_r = store_logic_read(partname_r, lflashreadoff_r,
999 nflashloadlen_r, pbuffpreload);
1000 if (rc_r) {
1001 errorP("Fail read 0x%xB from %s at offset 0x%x\n",
1002 (unsigned int)nflashloadlen_r, partname_r,
1003 (unsigned int)lflashreadoff_r);
1004 free(pbuffpreload);
1005 pbuffpreload = 0;
1006 return __LINE__;
1007 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001008#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1009 part_dec(partname_r, (u8*)pbuffpreload, nflashloadlen_r,
1010 (u8*)pbuffpreload, nflashloadlen_r, lflashreadoff_r);
1011#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001012 }
1013 }
1014
1015 debugP("totalSz=0x%x\n", nflashloadlen_r);
1016 flush_cache((unsigned long)pbuffpreload, nflashloadlen_r);
1017#ifndef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
1018 if (IS_FEAT_BOOT_VERIFY()) {
1019#ifndef CONFIG_IMAGE_CHECK
1020 rc_r = aml_sec_boot_check(AML_D_P_IMG_DECRYPT,
1021 (unsigned long)pbuffpreload,
1022 GXB_IMG_SIZE, GXB_IMG_DEC_DTB);
1023#else
1024 rc_r = secure_image_check((uint8_t *)(unsigned long)
1025 pbuffpreload, GXB_IMG_SIZE, GXB_IMG_DEC_DTB);
1026 /*pbuffpreload += android_image_check_offset();*/
1027 memmove(pbuffpreload, pbuffpreload + android_image_check_offset(),
1028 nflashloadlen_r - android_image_check_offset());
1029#endif
1030 if (rc_r) {
1031 errorP("\n[vendor_boot]aml log : Sig Check is %d\n", rc_r);
1032 return __LINE__;
1033 }
1034 MsgP("vendor_boot decrypt at 0x%p\n", pbuffpreload);
1035 }
1036#endif//#ifndef CONFIG_SKIP_KERNEL_DTB_SECBOOT_CHECK
1037
1038 p_vender_boot_img = (p_vendor_boot_img_t)pbuffpreload;
1039 } else {
1040 free(pbuffpreload);
1041 pbuffpreload = 0;
1042 }
1043 } /*ANDROID R/S*/
1044 return 0;
1045}
1046
1047#define AML_RES_IMG_VERSION_V1 (0x01)
1048#define AML_RES_IMG_VERSION_V2 (0x02)
1049#define AML_RES_IMG_V1_MAGIC_LEN 8
1050#define AML_RES_IMG_V1_MAGIC "AML_RES!"//8 chars
1051#define AML_RES_IMG_ITEM_ALIGN_SZ 16
1052#define AML_RES_IMG_HEAD_SZ (AML_RES_IMG_ITEM_ALIGN_SZ * 4)//64
1053#define AML_RES_ITEM_HEAD_SZ (AML_RES_IMG_ITEM_ALIGN_SZ * 4)//64
1054
1055//typedef for amlogic resource image
1056#pragma pack(push, 4)
1057typedef struct {
1058 __u32 crc; //crc32 value for the resouces image
1059 __s32 version;//current version is 0x01
1060
1061 __u8 magic[AML_RES_IMG_V1_MAGIC_LEN]; //resources images magic
1062
1063 __u32 imgSz; //total image size in byte
1064 __u32 imgItemNum;//total item packed in the image
1065
1066 __u32 alignSz;//AML_RES_IMG_ITEM_ALIGN_SZ
1067 __u8 reserv[AML_RES_IMG_HEAD_SZ - 8 * 3 - 4];
1068
1069}AmlResImgHead_t;
1070#pragma pack(pop)
1071
1072#define LOGO_OLD_FMT_READ_SZ (8U<<20)//if logo format old, read 8M
1073
1074static int img_res_check_log_header(const AmlResImgHead_t* pResImgHead)
1075{
1076 int rc = 0;
1077
1078 rc = memcmp(pResImgHead->magic, AML_RES_IMG_V1_MAGIC, AML_RES_IMG_V1_MAGIC_LEN);
1079 if (rc) {
1080 debugP("Magic error for res\n");
1081 return 1;
1082 }
1083 if (AML_RES_IMG_VERSION_V2 != pResImgHead->version) {
1084 errorP("res version 0x%x != 0x%x\n", pResImgHead->version, AML_RES_IMG_VERSION_V2);
1085 return 2;
1086 }
1087
1088 return 0;
1089}
1090
1091static int do_image_read_res(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1092{
1093 const char* const partName = argv[1];
1094 unsigned char* loadaddr = 0;
1095 int rc = 0;
1096 AmlResImgHead_t* pResImgHead = NULL;
1097 unsigned totalSz = 0;
1098 uint64_t flashReadOff = 0;
1099
1100 if (2 < argc) {
1101 loadaddr = (unsigned char*)simple_strtoul(argv[2], NULL, 16);
1102 }
1103 else{
1104 loadaddr = (unsigned char*)simple_strtoul(env_get("loadaddr"), NULL, 16);
1105 }
1106 pResImgHead = (AmlResImgHead_t*)loadaddr;
1107
1108 rc = store_logic_read(partName, flashReadOff, IMG_PRELOAD_SZ, loadaddr);
1109 if (rc) {
1110 errorP("Fail to read 0x%xB from part[%s] at offset 0\n", IMG_PRELOAD_SZ, partName);
1111 return __LINE__;
1112 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001113#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1114 part_dec(partName, (u8*)loadaddr, IMG_PRELOAD_SZ, (u8*)loadaddr, IMG_PRELOAD_SZ, flashReadOff);
1115#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001116 flashReadOff = IMG_PRELOAD_SZ;
1117
1118 if (img_res_check_log_header(pResImgHead)) {
1119 errorP("Logo header err.\n");
1120 return __LINE__;
1121 }
1122
1123 //Read the actual size of the new version res image
1124 totalSz = pResImgHead->imgSz;
1125 if (totalSz > IMG_PRELOAD_SZ )
1126 {
1127 const unsigned leftSz = totalSz - flashReadOff;
1128
1129 rc = store_logic_read(partName, flashReadOff, leftSz, loadaddr + (unsigned)flashReadOff);
1130 if (rc) {
1131 errorP("Fail to read 0x%xB from part[%s] at offset 0x%x\n", leftSz, partName, IMG_PRELOAD_SZ);
1132 return __LINE__;
1133 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001134#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1135 part_dec(partName, (u8*)(loadaddr + (unsigned)flashReadOff), leftSz,
1136 (u8*)(loadaddr + (unsigned)flashReadOff), leftSz, flashReadOff);
1137#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001138 }
1139 debugP("totalSz=0x%x\n", totalSz);
1140
1141 return 0;
1142}
1143
1144#define IH_MAGIC 0x27051956 /* Image Magic Number */
1145#define IH_NMLEN 32 /* Image Name Length */
1146
1147#pragma pack(push, 1)
1148typedef struct pack_header{
1149 unsigned int magic; /* Image Header Magic Number */
1150 unsigned int hcrc; /* Image Header CRC Checksum */
1151 unsigned int size; /* Image Data Size */
1152 unsigned int start; /* item data offset in the image*/
1153 unsigned int end; /* Entry Point Address */
1154 unsigned int next; /* Next item head offset in the image*/
1155 unsigned int dcrc; /* Image Data CRC Checksum */
1156 unsigned char index; /* Operating System */
1157 unsigned char nums; /* CPU architecture */
1158 unsigned char type; /* Image Type */
1159 unsigned char comp; /* Compression Type */
1160 char name[IH_NMLEN]; /* Image Name */
1161}AmlResItemHead_t;
1162#pragma pack(pop)
1163
1164#define CONFIG_MAX_PIC_LEN (12 << 20)
1165static const unsigned char gzip_magic[] = { 0x1f, 0x8b };
1166
1167//uncompress known format for 'imgread pic'
1168static int imgread_uncomp_pic(unsigned char* srcAddr, const unsigned srcSz,
1169 unsigned char* dstAddr, const unsigned dstBufSz, unsigned long* dstDatSz)
1170{
1171 /*debugP("srcAddr[%x, %x]\n", srcAddr[0], srcAddr[1]);*/
1172 if (!memcmp(srcAddr, gzip_magic, sizeof(gzip_magic)))
1173 {
1174 *dstDatSz = srcSz;
1175 return gunzip(dstAddr, dstBufSz, srcAddr, dstDatSz);
1176 }
1177
1178 return 0;
1179}
1180
1181//[imgread pic] logo bootup $loadaddr_misc
1182static int do_image_read_pic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1183{
1184 const char* const partName = argv[1];
1185 unsigned char* loadaddr = 0;
1186 int rc = 0;
1187 const AmlResImgHead_t* pResImgHead = NULL;
1188 //unsigned totalSz = 0;
1189 uint64_t flashReadOff = 0;
1190 const unsigned PreloadSz = PIC_PRELOAD_SZ;//preload 8k, 124-1 pic header, If you need pack more than 123 items, fix this
1191 unsigned itemIndex = 0;
1192 const AmlResItemHead_t* pItem = NULL;
1193 const char* picName = argv[2];
1194
1195 loadaddr = (unsigned char*)simple_strtoul(argc > 3 ? argv[3] : env_get("loadaddr_misc"), NULL, 16);
1196
1197 pResImgHead = (AmlResImgHead_t*)loadaddr;
1198
1199 debugP("to read pic (%s)\n", picName);
1200 rc = store_logic_read(partName, flashReadOff, PreloadSz, loadaddr);
1201 if (rc) {
1202 errorP("Fail to read 0x%xB from part[%s] at offset 0\n", PreloadSz, partName);
1203 return __LINE__;
1204 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001205#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1206 part_dec(partName, (u8*)loadaddr, PreloadSz, (u8*)loadaddr, PreloadSz, flashReadOff);
1207#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001208 flashReadOff = PreloadSz;
1209 debugP("end read pic sz %d\n", PreloadSz);
1210
1211 if (img_res_check_log_header(pResImgHead)) {
1212 errorP("Logo header err.\n");
1213 return __LINE__;
1214 }
1215
1216 //correct bootup for mbox
1217 while (!strcmp("bootup", picName))
1218 {
1219 char* outputmode = env_get("outputmode");
1220 if (!outputmode)break;//not env outputmode
1221
1222 rc = !strncmp("720", outputmode, 3) || !strncmp("576", outputmode, 3) || !strncmp("480", outputmode, 3);
1223 if (rc) {
1224 picName = "bootup_720";
1225 break;
1226 }
1227
1228 picName = "bootup_1080";
1229 break;
1230 }
1231
1232 pItem = (AmlResItemHead_t*)(pResImgHead + 1);
1233 for (itemIndex = 0; itemIndex < pResImgHead->imgItemNum; ++itemIndex, ++pItem)
1234 {
1235 if (IH_MAGIC != pItem->magic) {
1236 errorP("item magic 0x%x != 0x%x\n", pItem->magic, IH_MAGIC);
1237 return __LINE__;
1238 }
1239 if (!strcmp(picName, pItem->name) || !strcmp(argv[2], pItem->name))
1240 {
1241 char env_name[IH_NMLEN*2];
1242 char env_data[IH_NMLEN*2];
1243 unsigned long picLoadAddr = (unsigned long)loadaddr + (unsigned)pItem->start;
1244 int itemSz = pItem->size;
1245 unsigned long uncompSz = 0;
1246
1247 if (pItem->start + itemSz > flashReadOff)
1248 {
1249 unsigned long rdOff = pItem->start;
1250 unsigned long rdOffAlign = (rdOff >> 11) << 11;//align 2k page for mtd nand, 512 for emmc
1251 rc = store_logic_read(partName, rdOffAlign, itemSz + (rdOff & 0x7ff),(char*)((picLoadAddr>>11)<<11));
1252 if (rc) {
1253 errorP("Fail to read pic at offset 0x%x\n", pItem->start);
1254 return __LINE__;
1255 }
Mingyen Hung96effce2023-09-01 00:39:46 -07001256#if CONFIG_PARTITION_ENCRYPTION_LOCAL
1257 part_dec(partName, (u8*)((picLoadAddr>>11)<<11), itemSz + (rdOff & 0x7ff),
1258 (u8*)((picLoadAddr>>11)<<11), itemSz + (rdOff & 0x7ff), rdOffAlign);
1259#endif
Bo Lv72d0e902023-01-02 14:27:34 +00001260 debugP("pic sz 0x%x\n", itemSz);
1261 }
1262
1263 //uncompress supported format
1264 unsigned long uncompLoadaddr = picLoadAddr + itemSz + 7;
1265 uncompLoadaddr &= ~(0x7U);
1266 rc = imgread_uncomp_pic((unsigned char *)picLoadAddr, itemSz,
1267 (unsigned char *)uncompLoadaddr, CONFIG_MAX_PIC_LEN, &uncompSz);
1268 if (rc) {
1269 errorP("Fail in uncomp pic,rc[%d]\n", rc);
1270 return __LINE__;
1271 }
1272 if (uncompSz) {
1273 itemSz = (int)uncompSz;
1274 picLoadAddr = uncompLoadaddr;
1275 }
1276
1277 sprintf(env_name, "%s_offset", argv[2]);//be bootup_offset ,not bootup_720_offset
1278 sprintf(env_data, "0x%lx", picLoadAddr);
1279 env_set(env_name, env_data);
1280
1281 sprintf(env_name, "%s_size", argv[2]);
1282 sprintf(env_data, "0x%x", itemSz);
1283 env_set(env_name, env_data);
1284
1285 debugP("end read pic[%s]\n", picName);
1286 return 0;//success
1287 }
1288 }
1289
1290 return __LINE__;//fail
1291}
1292
1293static cmd_tbl_t cmd_imgread_sub[] = {
1294 U_BOOT_CMD_MKENT(kernel, 4, 0, do_image_read_kernel, "", ""),
1295 U_BOOT_CMD_MKENT(dtb, 4, 0, do_image_read_dtb, "", ""),
1296 U_BOOT_CMD_MKENT(res, 3, 0, do_image_read_res, "", ""),
1297 U_BOOT_CMD_MKENT(pic, 4, 0, do_image_read_pic, "", ""),
Mingyen Hung96effce2023-09-01 00:39:46 -07001298 U_BOOT_CMD_MKENT(part, 5, 0, do_image_read_part, "", ""),
Bo Lv72d0e902023-01-02 14:27:34 +00001299};
1300
1301static int do_image_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1302{
1303
1304#ifdef CONFIG_PXP_EMULATOR
1305 printf("\naml log : PXP image all use preload\n");
1306 do { (void)cmd_imgread_sub[0]; } while(0);
1307 return 0;
1308#else
1309 cmd_tbl_t *c;
1310
1311 /* Strip off leading 'imgread' command argument */
1312 argc--;
1313 argv++;
1314
1315 c = find_cmd_tbl(argv[0], &cmd_imgread_sub[0], ARRAY_SIZE(cmd_imgread_sub));
1316
1317 if (c) {
1318 return c->cmd(cmdtp, flag, argc, argv);
1319 } else {
1320 cmd_usage(cmdtp);
1321 return 1;
1322 }
1323#endif //CONFIG_PXP_EMULATOR
1324}
1325
1326U_BOOT_CMD(
1327 imgread, //command name
Mingyen Hung96effce2023-09-01 00:39:46 -07001328 6, //maxargs
Bo Lv72d0e902023-01-02 14:27:34 +00001329 0, //repeatable
1330 do_image_read, //command function
1331 "Read the image from internal flash with actual size", //description
1332 " argv: <imageType> <part_name> <loadaddr> \n" //usage
1333 " - <image_type> Current support is kernel/res(ource).\n"
1334 "imgread kernel --- Read image in format IMAGE_FORMAT_ANDROID\n"
1335 "imgread dtb --- Read dtb in format IMAGE_FORMAT_ANDROID\n"
1336 "imgread res --- Read image packed by 'Amlogic resource packer'\n"
1337 "imgread picture --- Read one picture from Amlogic logo"
Mingyen Hung96effce2023-09-01 00:39:46 -07001338 "imgread part --- Read partition"
Bo Lv72d0e902023-01-02 14:27:34 +00001339 " - e.g. \n"
1340 " to read boot.img from part boot from flash: <imgread kernel boot loadaddr> \n" //usage
1341 " to read recovery.img from part recovery from flash: <imgread kernel recovery loadaddr $offset> \n" //usage
1342 " to read logo.img from part logo from flash: <imgread res logo loadaddr> \n" //usage
1343 " 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 -07001344 " to read partition from from flash: <imgread part <part_name> <load_addr> <offset> <sz>> \n" //usage
Bo Lv72d0e902023-01-02 14:27:34 +00001345);
1346
1347//[imgread pic] logo bootup $loadaddr_misc
1348static int do_unpackimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1349{
1350 unsigned char* loadaddr = 0;
1351 const AmlResImgHead_t* pResImgHead = NULL;
1352 unsigned itemIndex = 0;
1353 const AmlResItemHead_t* pItem = NULL;
1354
1355 loadaddr = (unsigned char*)simple_strtoul(argc > 1 ? argv[1] : env_get("loadaddr_misc"), NULL, 16);
1356
1357 pResImgHead = (AmlResImgHead_t*)loadaddr;
1358 const int totalSz = pResImgHead->imgSz;
1359 unsigned long unCompressBuf = (long)loadaddr + totalSz;
1360
1361 if (img_res_check_log_header(pResImgHead)) {
1362 errorP("Logo header err.\n");
1363 return __LINE__;
1364 }
1365
1366 pItem = (AmlResItemHead_t*)(pResImgHead + 1);
1367 for (itemIndex = 0; itemIndex < pResImgHead->imgItemNum; ++itemIndex, ++pItem)
1368 {
1369 if (IH_MAGIC != pItem->magic) {
1370 errorP("item magic 0x%x != 0x%x\n", pItem->magic, IH_MAGIC);
1371 return __LINE__;
1372 }
1373 char env_name[IH_NMLEN*2];
1374 char env_data[IH_NMLEN*2];
1375 unsigned long picLoadAddr = (unsigned long)loadaddr + (unsigned)pItem->start;
1376
1377 int itemSz = pItem->size;
1378 unsigned long uncompSz = 0;
1379
1380 if (unCompressBuf & 0x7U)
1381 unCompressBuf = ((unCompressBuf + 8) >> 3) << 3;
1382 imgread_uncomp_pic((unsigned char *)picLoadAddr, pItem->size,
1383 (unsigned char *)unCompressBuf, CONFIG_MAX_PIC_LEN, &uncompSz);
1384 if (uncompSz) {
1385 picLoadAddr = (unsigned long)unCompressBuf;
1386 itemSz = uncompSz;
1387 unCompressBuf += uncompSz;
1388 }
1389 sprintf(env_name, "%s_offset", pItem->name);//be bootup_offset ,not bootup_720_offset
1390 sprintf(env_data, "0x%lx", picLoadAddr);
1391 env_set(env_name, env_data);
1392
1393 sprintf(env_name, "%s_size", pItem->name);
1394 sprintf(env_data, "0x%x", itemSz);
1395 env_set(env_name, env_data);
1396 }
1397
1398 return 0;//success
1399}
1400
1401U_BOOT_CMD(
1402 unpackimg, //command name
1403 2, //maxargs
1404 0, //repeatable
1405 do_unpackimg, //command function
1406 "un pack logo image into pictures", //description
1407 " argv: unpackimg <imgLoadaddr> \n" //usage
1408 " un pack the logo image, which already loaded at <imgLoadaddr>.\n"
1409);
1410
1411#if defined(CONFIG_CMD_AUTOSCR)
1412/*
1413 * Keep for now for backward compatibility;
1414 * remove later when support for "autoscr" goes away.
1415 */
1416static int
1417do_autoscr (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1418{
1419 printf ("\n### WARNING ### "
1420 "\"autoscr\" is deprecated, use \"source\" instead ###\n\n");
1421 if (argc < 2) {
1422 printf("too few argc %d for %s\n", argc, argv[0]);
1423 return CMD_RET_FAILURE;
1424 }
1425 env_set("_src_addr", argv[1]);
1426 return run_command("echo _src_addr ${_src_addr}; source ${_src_addr}; env delete _src_addr", 0);
1427}
1428
1429U_BOOT_CMD_COMPLETE(
1430 autoscr, 2, 0, do_autoscr,
1431 "DEPRECATED - use \"source\" command instead",
1432 " argv: autoscr script_mem_addr",
1433 var_complete
1434);
1435#endif//#if defined(CONFIG_CMD_AUTOSCR)
1436
1437#if defined(CONFIG_CMD_EXT4) && defined(CONFIG_MMC_MESON_GX)
1438/*"if ext4load mmc 1:x ${dtb_mem_addr} /recovery/dtb.img; then echo cache dtb.img loaded; fi;"\*/
1439static int do_load_logo_from_ext4(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1440{
1441 if (3 > argc) {
1442 errorP("argc(%d) < 3 illegal\n", argc);
1443 return CMD_RET_USAGE;
1444 }
1445 int iRet = 0;
1446 const char* ext4Part = argv[1];
1447 void* loadaddr = (void*)simple_strtoul(argv[2], NULL, 16);
1448 int autoSelectSlot = 1;//auto detect if need add _a/_b
1449
1450 if (argc > 3) {
1451 env_set("ext4LogoPath", argv[3]);
1452 } else {
1453 env_set("ext4LogoPath", "/logo_files/bootup.bmp");
1454 }
1455 if (argc > 4) {
1456 const char *paraAutoSel = argv[4];
1457
1458 autoSelectSlot = !memcmp(paraAutoSel, "true", 5);
1459 if (!autoSelectSlot && strcmp(paraAutoSel, "false")) {
1460 errorP("illegal para4 %s\n", paraAutoSel);
1461 return CMD_RET_FAILURE;
1462 }
1463 }
1464
1465 if (!loadaddr) {
1466 errorP("illegal loadaddr %s\n", argv[2]);
1467 return CMD_RET_FAILURE;
1468 }
1469
1470 if (BOOT_EMMC != store_get_type() ) {
1471 errorP("only support emmc, but store type %d\n", store_get_type() );
1472 return CMD_RET_FAILURE;
1473 }
1474
1475 env_set("bootLogoPart", ext4Part);
1476 if (autoSelectSlot)
1477 run_command("if test ${active_slot} != normal; then setenv bootLogoPart ${bootLogoPart}${active_slot}; printenv bootLogoPart; fi", 0);
1478 const int partIndex = get_partition_num_by_name(env_get("bootLogoPart"));
1479 if (partIndex < 0) {
1480 errorP("fail find part index for name(%s)\n", env_get("bootLogoPart")); return CMD_RET_FAILURE;
1481 }
1482 env_set_hex("logoPart", partIndex);
1483 env_set_hex("logoLoadAddr", (ulong)loadaddr);
1484 env_set("ext4logoLoadCmd", "ext4load mmc 1:${logoPart} ${logoLoadAddr} ${ext4LogoPath}");
1485 iRet = run_command("printenv ext4logoLoadCmd; run ext4logoLoadCmd", 0);
1486 if (iRet) {
1487 errorP("Fail in load logo cmd\n"); return CMD_RET_FAILURE;
1488 }
1489 MsgP("load bmp from ext4 part okay\n");
1490 run_command("setenv ext4LogoSz ${filesize}", 0);
1491 const int bmpSz = env_get_hex("filesize", 0);
1492 if (bmpSz <= 0) {
1493 errorP("err bmp sz\n"); return CMD_RET_FAILURE;
1494 }
1495
1496#if defined(CONFIG_GZIP)
1497 if (memcmp(loadaddr, gzip_magic, sizeof(gzip_magic))) {
1498 return CMD_RET_SUCCESS;
1499 }
1500 MsgP("gunzip bmp logo\n");
1501 void* uncompress = (char*)loadaddr + (((bmpSz + 0xf)>>4)<<4);
1502 unsigned long uncompSz = 0;
1503 iRet = imgread_uncomp_pic((unsigned char*)loadaddr, bmpSz, (unsigned char*)uncompress,
1504 CONFIG_MAX_PIC_LEN, (unsigned long*)&uncompSz);
1505 if (iRet) {
1506 errorP("Fail in uncomp pic,rc[%d]\n", iRet); return __LINE__;
1507 }
1508 if (uncompSz <= 0) {
1509 errorP("Fail uncompress logo bmp\n"); return CMD_RET_FAILURE;
1510 }
1511 memmove(loadaddr, uncompress, uncompSz);
1512 env_set_hex("ext4LogoSz", uncompSz);
1513#endif//#if defined(CONFIG_GZIP)
1514
1515 return CMD_RET_SUCCESS;
1516}
1517
1518U_BOOT_CMD_COMPLETE(
1519 rdext4pic, //read ext4 picture
1520 5, //maxargs
1521 0, //repeatable
1522 do_load_logo_from_ext4, //command function
1523 "read logo bmp from ext4 part", //description
1524 " argv: rdext4pic <partName> <memAddr> <logoPath>\n" //usage
1525 " load bmp picture from <logoPath> of <partName> to <memAddr>.\n",
1526 var_complete
1527);
1528#endif// #if defined(CONFIG_CMD_EXT4) && defined(CONFIG_MMC_MESON_GX)
1529