6
6
* Author: Weijie Gao <[email protected] >
7
7
*/
8
8
9
+ #include <time.h>
9
10
#include <image.h>
11
+ #include <u-boot/crc.h>
10
12
#include <u-boot/sha256.h>
11
13
#include "imagetool.h"
12
14
#include "mtk_image.h"
@@ -251,17 +253,45 @@ static uint32_t img_size;
251
253
static enum brlyt_img_type hdr_media ;
252
254
static uint32_t hdr_offset ;
253
255
static int use_lk_hdr ;
256
+ static int use_mt7621_hdr ;
254
257
static bool is_arm64_image ;
255
258
256
259
/* LK image name */
257
260
static char lk_name [32 ] = "U-Boot" ;
258
261
262
+ /* CRC32 normal table required by MT7621 image */
263
+ static uint32_t crc32tbl [256 ];
264
+
259
265
/* NAND header selected by user */
260
266
static const union nand_boot_header * hdr_nand ;
261
267
262
268
/* GFH header + 2 * 4KB pages of NAND */
263
269
static char hdr_tmp [sizeof (struct gfh_header ) + 0x2000 ];
264
270
271
+ static uint32_t crc32_normal_cal (uint32_t crc , const void * data , size_t length ,
272
+ const uint32_t * crc32c_table )
273
+ {
274
+ const uint8_t * p = data ;
275
+
276
+ while (length -- )
277
+ crc = crc32c_table [(uint8_t )((crc >> 24 ) ^ * p ++ )] ^ (crc << 8 );
278
+
279
+ return crc ;
280
+ }
281
+
282
+ static void crc32_normal_init (uint32_t * crc32c_table , uint32_t poly )
283
+ {
284
+ uint32_t v , i , j ;
285
+
286
+ for (i = 0 ; i < 256 ; i ++ ) {
287
+ v = i << 24 ;
288
+ for (j = 0 ; j < 8 ; j ++ )
289
+ v = (v << 1 ) ^ ((v & (1 << 31 )) ? poly : 0 );
290
+
291
+ crc32c_table [i ] = v ;
292
+ }
293
+ }
294
+
265
295
static int mtk_image_check_image_types (uint8_t type )
266
296
{
267
297
if (type == IH_TYPE_MTKIMAGE )
@@ -283,6 +313,7 @@ static int mtk_brom_parse_imagename(const char *imagename)
283
313
static const char * hdr_offs = "" ;
284
314
static const char * nandinfo = "" ;
285
315
static const char * lk = "" ;
316
+ static const char * mt7621 = "" ;
286
317
static const char * arm64_param = "" ;
287
318
288
319
key = buf ;
@@ -332,6 +363,9 @@ static int mtk_brom_parse_imagename(const char *imagename)
332
363
if (!strcmp (key , "lk" ))
333
364
lk = val ;
334
365
366
+ if (!strcmp (key , "mt7621" ))
367
+ mt7621 = val ;
368
+
335
369
if (!strcmp (key , "lkname" ))
336
370
snprintf (lk_name , sizeof (lk_name ), "%s" , val );
337
371
@@ -352,6 +386,13 @@ static int mtk_brom_parse_imagename(const char *imagename)
352
386
return 0 ;
353
387
}
354
388
389
+ /* if user specified MT7621 image header, skip following checks */
390
+ if (mt7621 && mt7621 [0 ] == '1' ) {
391
+ use_mt7621_hdr = 1 ;
392
+ free (buf );
393
+ return 0 ;
394
+ }
395
+
355
396
/* parse media type */
356
397
for (i = 0 ; i < ARRAY_SIZE (brom_images ); i ++ ) {
357
398
if (!strcmp (brom_images [i ].name , media )) {
@@ -419,6 +460,13 @@ static int mtk_image_vrec_header(struct image_tool_params *params,
419
460
return 0 ;
420
461
}
421
462
463
+ if (use_mt7621_hdr ) {
464
+ tparams -> header_size = image_get_header_size ();
465
+ tparams -> hdr = & hdr_tmp ;
466
+ memset (& hdr_tmp , 0 , tparams -> header_size );
467
+ return 0 ;
468
+ }
469
+
422
470
if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND )
423
471
tparams -> header_size = 2 * le16_to_cpu (hdr_nand -> pagesize );
424
472
else
@@ -579,9 +627,90 @@ static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
579
627
return 0 ;
580
628
}
581
629
630
+ static uint32_t crc32be_cal (const void * data , size_t length )
631
+ {
632
+ uint32_t crc = 0 ;
633
+ uint8_t c ;
634
+
635
+ if (crc32tbl [1 ] != MT7621_IH_CRC_POLYNOMIAL )
636
+ crc32_normal_init (crc32tbl , MT7621_IH_CRC_POLYNOMIAL );
637
+
638
+ crc = crc32_normal_cal (crc , data , length , crc32tbl );
639
+
640
+ for (; length ; length >>= 8 ) {
641
+ c = length & 0xff ;
642
+ crc = crc32_normal_cal (crc , & c , 1 , crc32tbl );
643
+ }
644
+
645
+ return ~crc ;
646
+ }
647
+
648
+ static int mtk_image_verify_mt7621_header (const uint8_t * ptr , int print )
649
+ {
650
+ const image_header_t * hdr = (const image_header_t * )ptr ;
651
+ struct mt7621_nand_header * nhdr ;
652
+ uint32_t spl_size , crcval ;
653
+ image_header_t header ;
654
+ int ret ;
655
+
656
+ spl_size = image_get_size (hdr );
657
+
658
+ if (spl_size > img_size ) {
659
+ if (print )
660
+ printf ("Incomplete SPL image\n" );
661
+ return -1 ;
662
+ }
663
+
664
+ ret = image_check_hcrc (hdr );
665
+ if (!ret ) {
666
+ if (print )
667
+ printf ("Bad header CRC\n" );
668
+ return -1 ;
669
+ }
670
+
671
+ ret = image_check_dcrc (hdr );
672
+ if (!ret ) {
673
+ if (print )
674
+ printf ("Bad data CRC\n" );
675
+ return -1 ;
676
+ }
677
+
678
+ /* Copy header so we can blank CRC field for re-calculation */
679
+ memmove (& header , hdr , image_get_header_size ());
680
+ image_set_hcrc (& header , 0 );
681
+
682
+ nhdr = (struct mt7621_nand_header * )header .ih_name ;
683
+ crcval = be32_to_cpu (nhdr -> crc );
684
+ nhdr -> crc = 0 ;
685
+
686
+ if (crcval != crc32be_cal (& header , image_get_header_size ())) {
687
+ if (print )
688
+ printf ("Bad NAND header CRC\n" );
689
+ return -1 ;
690
+ }
691
+
692
+ if (print ) {
693
+ printf ("Load Address: %08x\n" , image_get_load (hdr ));
694
+
695
+ printf ("Image Name: %.*s\n" , MT7621_IH_NMLEN ,
696
+ image_get_name (hdr ));
697
+
698
+ if (IMAGE_ENABLE_TIMESTAMP ) {
699
+ printf ("Created: " );
700
+ genimg_print_time ((time_t )image_get_time (hdr ));
701
+ }
702
+
703
+ printf ("Data Size: " );
704
+ genimg_print_size (image_get_data_size (hdr ));
705
+ }
706
+
707
+ return 0 ;
708
+ }
709
+
582
710
static int mtk_image_verify_header (unsigned char * ptr , int image_size ,
583
711
struct image_tool_params * params )
584
712
{
713
+ image_header_t * hdr = (image_header_t * )ptr ;
585
714
union lk_hdr * lk = (union lk_hdr * )ptr ;
586
715
587
716
/* nothing to verify for LK image header */
@@ -590,6 +719,9 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size,
590
719
591
720
img_size = image_size ;
592
721
722
+ if (image_get_magic (hdr ) == IH_MAGIC )
723
+ return mtk_image_verify_mt7621_header (ptr , 0 );
724
+
593
725
if (!strcmp ((char * )ptr , NAND_BOOT_NAME ))
594
726
return mtk_image_verify_nand_header (ptr , 0 );
595
727
else
@@ -600,6 +732,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size,
600
732
601
733
static void mtk_image_print_header (const void * ptr )
602
734
{
735
+ image_header_t * hdr = (image_header_t * )ptr ;
603
736
union lk_hdr * lk = (union lk_hdr * )ptr ;
604
737
605
738
if (le32_to_cpu (lk -> magic ) == LK_PART_MAGIC ) {
@@ -610,6 +743,11 @@ static void mtk_image_print_header(const void *ptr)
610
743
611
744
printf ("Image Type: MediaTek BootROM Loadable Image\n" );
612
745
746
+ if (image_get_magic (hdr ) == IH_MAGIC ) {
747
+ mtk_image_verify_mt7621_header (ptr , 1 );
748
+ return ;
749
+ }
750
+
613
751
if (!strcmp ((char * )ptr , NAND_BOOT_NAME ))
614
752
mtk_image_verify_nand_header (ptr , 1 );
615
753
else
@@ -773,6 +911,45 @@ static void mtk_image_set_nand_header(void *ptr, off_t filesize,
773
911
filesize - 2 * le16_to_cpu (hdr_nand -> pagesize ) - SHA256_SUM_LEN );
774
912
}
775
913
914
+ static void mtk_image_set_mt7621_header (void * ptr , off_t filesize ,
915
+ uint32_t loadaddr )
916
+ {
917
+ image_header_t * hdr = (image_header_t * )ptr ;
918
+ struct mt7621_stage1_header * shdr ;
919
+ struct mt7621_nand_header * nhdr ;
920
+ uint32_t datasize , crcval ;
921
+
922
+ datasize = filesize - image_get_header_size ();
923
+ nhdr = (struct mt7621_nand_header * )hdr -> ih_name ;
924
+ shdr = (struct mt7621_stage1_header * )(ptr + image_get_header_size ());
925
+
926
+ shdr -> ep = cpu_to_be32 (loadaddr );
927
+ shdr -> stage_size = cpu_to_be32 (datasize );
928
+
929
+ image_set_magic (hdr , IH_MAGIC );
930
+ image_set_time (hdr , time (NULL ));
931
+ image_set_size (hdr , datasize );
932
+ image_set_load (hdr , loadaddr );
933
+ image_set_ep (hdr , loadaddr );
934
+ image_set_os (hdr , IH_OS_U_BOOT );
935
+ image_set_arch (hdr , IH_ARCH_MIPS );
936
+ image_set_type (hdr , IH_TYPE_STANDALONE );
937
+ image_set_comp (hdr , IH_COMP_NONE );
938
+
939
+ crcval = crc32 (0 , (uint8_t * )shdr , datasize );
940
+ image_set_dcrc (hdr , crcval );
941
+
942
+ strncpy (nhdr -> ih_name , "MT7621 NAND" , MT7621_IH_NMLEN );
943
+
944
+ nhdr -> ih_stage_offset = cpu_to_be32 (image_get_header_size ());
945
+
946
+ crcval = crc32be_cal (hdr , image_get_header_size ());
947
+ nhdr -> crc = cpu_to_be32 (crcval );
948
+
949
+ crcval = crc32 (0 , (uint8_t * )hdr , image_get_header_size ());
950
+ image_set_hcrc (hdr , crcval );
951
+ }
952
+
776
953
static void mtk_image_set_header (void * ptr , struct stat * sbuf , int ifd ,
777
954
struct image_tool_params * params )
778
955
{
@@ -791,6 +968,11 @@ static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
791
968
img_gen = true;
792
969
img_size = sbuf -> st_size ;
793
970
971
+ if (use_mt7621_hdr ) {
972
+ mtk_image_set_mt7621_header (ptr , sbuf -> st_size , params -> addr );
973
+ return ;
974
+ }
975
+
794
976
if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND )
795
977
mtk_image_set_nand_header (ptr , sbuf -> st_size , params -> addr );
796
978
else
0 commit comments