//------------------------------------------------------------------------------- #include "mergeToBin.h" #include "loadBasicPacket.h" #include "generateOutput.h" #include #include //------------------------------------------------------------------------------- u8 *codeTmpMem = NULL; u8 *dataTmpMem = NULL; //------------------------------------------------------------------------------- static inline u32 getNorFlashOffset( u32 flashAddr ) { return flashAddr & 0x00ffffff; } u32 getNorFlashID( u32 flashAddr ) { flashAddr = flashAddr & 0xff000000; if( flashAddr == SPI_CODEFLASH_BASEADDR ) return 0; else if( flashAddr == SPI_DATAFLASH_BASEADDR ) { #if( CONFIG_DATA_FLASH_SIZE != 0 ) return 1; #else errMsg( "No support data-flash address (0x%08x)\n", flashAddr ); return 9; #endif } else { errMsg( "This address (0x%08x) is not a flash address.\n", flashAddr); return 9; } } //------------------------------------------------------------------------------- static bool moveFileContent( u8 *memOut, FILE *fpIn, int cpySize ) { int i; int readSize; u8 readBuf[TMP_BUFFER_SIZE] = {0}; for( i = 0; i < cpySize; i+= TMP_BUFFER_SIZE ) { readSize = fread( readBuf, 1, TMP_BUFFER_SIZE, fpIn ); if( readSize < 0 ) { errMsg( "fread() error\n" ); return false; } memcpy( memOut+i, readBuf, readSize ); } return true; } bool copyFileToMemory( u8 *memOut, const char *fileName, int maxSize ) { bool ret; FILE *fpIn; int fileSize = getFileSize( fileName ); if( fileSize > maxSize ) { errMsg( "fileSize(%d) > maxSize(%d) (%s)\n", fileSize, maxSize, fileName); exit(-1); return false; } fpIn = fopen( fileName, "rb" ); if( fpIn == NULL ) { errMsg( "Open file failed (%s)\n", fileName ); return false; } ret = moveFileContent( memOut, fpIn, fileSize ); fclose( fpIn ); return ret; } //------------------------------------------------------------------------------- unsigned char G_FLASH_ENCODE_FFFF_4DW[16] = { 0xac, 0xea, 0x6b, 0xcf, 0xac, 0x59, 0x4d, 0x35, 0x28, 0xab, 0x54, 0xe3, 0xa5, 0xaa, 0x0b, 0x37, }; bool loadBasicImageToFlashTempMem( u8 *memOut, const char *fileName) { FILE *fpIn; int fileSize; bool ret; if( !isLoadBasicPacket() ) return true; dbgMsg( "[loadBasicImageToFlashTempMem] %s\n", fileName ); fileSize = getFileSize( fileName ); if( fileSize <= 0 ) { errMsg( "[loadBasicImageToFlashTempMem] %s\n", fileName ); } fpIn = fopen( fileName, "rb" ); if( fpIn == NULL ) return false; ret = moveFileContent ( memOut, fpIn, fileSize ); fclose(fpIn); return ret; } u8* initFlashTempMem( u32 Id, u32 fileSizeKB ) { int i; u8 *tmpMem; u32 flashSize = fileSizeKB * 1024; // original is KB dbgMsg( "[initFlashTempMem] Flash%d : %dKB\n", Id, fileSizeKB ); tmpMem = (u8*) malloc( flashSize ); if( tmpMem == NULL ) { errMsg( " malloc flashTempMem failed!\n" ); return NULL; } for( i = 0; i < flashSize; i += 16 ) memcpy ( tmpMem+i , G_FLASH_ENCODE_FFFF_4DW, 16 ); return tmpMem; } bool mallocFlashTempMem() { codeTmpMem = initFlashTempMem( 0, (CONFIG_CODE_FLASH_SIZE > 8192)?CONFIG_CODE_FLASH_SIZE:8192 ); if( codeTmpMem == NULL ) return false; if( !loadBasicImageToFlashTempMem( codeTmpMem, BASEIMAGE_CODEBIN ) ) return false; #if( CONFIG_DATA_FLASH_SIZE != 0 ) dataTmpMem = initFlashTempMem( 1, CONFIG_DATA_FLASH_SIZE ); if( dataTmpMem == NULL ) return false; if( !loadBasicImageToFlashTempMem( dataTmpMem, BASEIMAGE_DATABIN ) ) return false; #else dataTmpMem = 0; #endif return true; } #if 0 static u8* getMergeFlashTempMem( unsigned long flashAddr ) { u8 *memTmp = NULL; u32 id = getNorFlashID( flashAddr ); if( id == 0 ) memTmp = codeTmpMem; else if( id == 1 ) memTmp = dataTmpMem; if( memTmp ) memTmp += getNorFlashOffset( flashAddr ); return memTmp; } #endif void writeToFlashTempFile( const char *fileName, u8 *memOut, u32 memSize ) { FILE *fp; dbgMsg( "[writeToFlashTempFile] %s\n", fileName ); fp = fopen( fileName, "wb" ); if (fp == NULL) return; fwrite( memOut, 1, memSize, fp ); fclose( fp ); } //------------------------------------------------------------------------------- int getFileSize( const char* fileName ) { FILE *fp = fopen( fileName, "rb" ); if( fp == NULL ) return -1; fseek( fp, 0, SEEK_END ); u32 fileSize = ftell( fp ); fclose( fp ); return fileSize; } static inline FILE* openMergeSource( const char *fileName, bool isAllowSkip ) { FILE *fp = fopen( fileName, "rb" ); if( fp != NULL ) return fp; if( isAllowSkip ) showMsg( "[Skip] File (%s) is not exist!\n", fileName ); else errMsg( "openMergeSource failed (%s)\n", fileName ); return NULL; } static inline int checkMergeSourceSize( const char* sourceFile, int fileSize, int flashSize ) { if( (flashSize != 0) && (fileSize > flashSize) ) { if( flashSize >= 1024 ) { flashSize = ROUND_KB(flashSize); fileSize = ROUND_KB(fileSize); } errMsg( "File's(%s) size Over flashSize limit!! ( %d > %d )\n", sourceFile, fileSize, flashSize ); return -1; } if( fileSize == 0 ) showMsg( "[Skip] File's (%s) size is zero\n", sourceFile ); return fileSize; } //------------------------------------------------------------------------------- typedef struct _MergeInfoOut { bool skip; // for DBG_SKIP_NOT_EXIST or fileSize = 0 FILE *fpIn; u8 *memIn; /* If (fpIn) not point to *.bin */ u8 *memOut; u8 *memOut2; int cpySize; int cpySize2; } MergeInfoOut; //------------------------------------------------------------------------------- // transfer *.ini to memory //------------------------------------------------------------------------------- #include "pnlset2bin.h" bool checkFileNameExtension( const char *fileName, const char *wildcard ) { int i ; bool ret = true; int FileNameLength = strlen(fileName); int WildcardLength = strlen(wildcard); const char *extension = fileName + FileNameLength - WildcardLength; if( FileNameLength <= WildcardLength ) ret = false; for( i = 0; ret && (i < WildcardLength) ; i++ ) { char c = tolower( extension[i] ); if( c != wildcard[i] ) ret = false; } if( !ret ) { dbgMsg( "checkFileNameExtension failed : %s, wildcard: %s\n", fileName, wildcard ); return false; } return true; } bool transferPanelSetFileToMemory( u8* memOut, NorFlashModuleInfo *info ) { int ret = false; u32 flashSize = info->flashSize1 + info->flashSize2; if( checkFileNameExtension( info->fileName, ".ini" ) ) { showMsg( "[transferPanelSetFileToMemory] %s\n", info->fileName ); ret = ini2binmem( info->fileName, (char*) memOut , flashSize); if(ret > 0) ret = true; } return ret; } int syscmd( const char * format, ... ) { char cmd[256]; va_list arg; va_start( arg, format ); vsprintf( cmd, format, arg ); va_end( arg ); showMsg("[CMD]: %s \n",cmd); return system(cmd); } int JPG2Bin( const char *szFileIn, const char *szFileOut ) { bool ret; u32 fileSize = getFileSize( szFileIn ); FILE *fpOut = fopen( szFileOut, "wb" ); if (fpOut == NULL) return 0; fwrite( &fileSize, 1, sizeof(u32), fpOut ); ret = copyFileContent( fpOut, szFileIn, fileSize ); fclose( fpOut ); return ret; } bool transferLogoFileToMemory( u8* memOut, NorFlashModuleInfo *info ) { int ret = false; u32 fileSize=0; u32 flashSize = info->flashSize1 + info->flashSize2; if( checkFileNameExtension( info->fileName, ".bmp" ) ) { showMsg( "[transferLogoFileToMemory] %s\n", info->fileName ); ret = BMP2Bin( info->fileName, FILENAME_LOGOTMP ); if( syscmd( "gzip %s", FILENAME_LOGOTMP ) ) ret = false; } else if( checkFileNameExtension( info->fileName, ".jpg" ) ) { showMsg( "[transferLogoFileToMemory] %s\n", info->fileName ); ret = JPG2Bin( info->fileName, FILENAME_LOGOGZTMP ); } if( ret ) { ret = copyFileToMemory( memOut, FILENAME_LOGOGZTMP, flashSize ); if( !ret ) errMsg( "[transferLogoFileToMemory] Size is too large after transfer!!! ( %d KB > %d KB )\n", fileSize, flashSize ); } removeTempFile( FILENAME_LOGOTMP ); removeTempFile( FILENAME_LOGOGZTMP ); return ret; } #ifdef CONFIG_MULTITABLE //2012.11.27 for multiable included, gaia int mt_main(char* filename, char* output_mtname, char* output_flagname); bool transferMultiTableToMemory( u8* memOut, NorFlashModuleInfo *info ) { int ret = false; // char cmd[256]; u32 flashSize = info->flashSize1 + info->flashSize2; if( checkFileNameExtension( info->fileName, ".ini" ) ) { showMsg( "[transferMultiTableToMemory] %s\n", info->fileName ); //sprintf( cmd, "./MULTITABLE/multitable ./%s", info->fileName ); //syscmd( cmd ); if(mt_main( info->fileName, FILENAME_MULTITABLETMP, FILENAME_MULTIFLAGTMP)==0) { //set MODULENAME_MT_FLAG is valid NorFlashModuleInfo *moduleInfo = searchModuleInfo( MODULENAME_MT_FLAG ); moduleInfo->isValid = true; strcpy( moduleInfo->fileName, FILENAME_MULTIFLAGTMP); ret = true; } } if( ret ) { ret = copyFileToMemory( memOut, FILENAME_MULTITABLETMP, flashSize ); if( !ret ) errMsg( "[transferMultiTableToMemory] Size is too large after transfer!!! ( > %d KB )\n", flashSize ); } removeTempFile( FILENAME_MULTITABLETMP ); return ret; } bool copyMultiFlagToMemory( u8* memOut, NorFlashModuleInfo *info ) { int ret = false; // char cmd[256]; u32 flashSize = info->flashSize1 + info->flashSize2; showMsg( "[copyMultiFlagToMemory] %s\n", info->fileName ); ret = copyFileToMemory( memOut, FILENAME_MULTIFLAGTMP, flashSize ); if( !ret ) errMsg( "[transferLogoFileToMemory] Size is too large after transfer!!! ( > %d KB )\n", flashSize ); removeTempFile( FILENAME_MULTIFLAGTMP ); return ret; } #endif #if 0 u8* transferFileToMemory ( NorFlashModuleInfo *info ) { int ret = 0; u32 flashSize = info->flashSize1 + info->flashSize2; u8 *mem = malloc( flashSize ); if( mem == NULL ) { errMsg( "[transferFileToMemory] allocate memory failed\n" ); return NULL; } if( !strcmp( info->moduleName, MODULENAME_PANELSET) ) { ret = transferPanelSetFileToMemory( mem, info ); } else if( !strcmp( info->moduleName, MODULENAME_EXTRAPANELSET1) ) { ret = transferPanelSetFileToMemory( mem, info ); } else if( !strcmp( info->moduleName, MODULENAME_EXTRAPANELSET2) ) { ret = transferPanelSetFileToMemory( mem, info ); } else if( !strcmp( info->moduleName, MODULENAME_EXTRAPANELSET3) ) { ret = transferPanelSetFileToMemory( mem, info ); } else if( !strcmp( info->moduleName, MODULENAME_LOGO) ) { ret = transferLogoFileToMemory( mem, info ); } #ifdef CONFIG_MULTITABLE//2012.11.27 for multiable included, gaia else if( !strcmp( info->moduleName, MODULENAME_MULTITABLE) ) { ret = transferMultiTableToMemory( mem, info ); } else if( !strcmp( info->moduleName, MODULENAME_MT_FLAG) ) { ret = copyMultiFlagToMemory( mem, info ); } #endif if( ret == false ) { free(mem); mem = NULL; errMsg( "[%s] can't not support this file format: %s", info->moduleName, info->fileName ); } return mem; } //------------------------------------------------------------------------------- #endif static inline void releaseMergeInfoOut( MergeInfoOut *out ) { if( out->fpIn ) fclose( out->fpIn ); if( out->memIn ) free( out->memIn ); } static inline void showFlashInfo( u32 flashAddr, u32 flashSize ) { dbgMsg( " =>[Flash%d] Offset: 0x%08x, Size: %d KB\n", getNorFlashID( flashAddr ) ,getNorFlashOffset( flashAddr ), ROUND_KB( flashSize ) ); } #if 0 bool getMergeInfo( MergeInfoOut *out, NorFlashModuleInfo *info ) { bool ret = true; bool isAllowSkip = DBG_SKIP_NOT_EXIST; int fileSize = getFileSize( info->fileName ); u32 flashSize = info->flashSize1 + info->flashSize2; dbgMsg( "[%s] getMergeInfo\n", info->moduleName ); dbgMsg( " =>FileName: %s (%d KB)\n", info->fileName, ROUND_KB( fileSize ) ); showFlashInfo( info->flashAddr1, info->flashSize1 ); if( info->flashAddr2 ) showFlashInfo( info->flashAddr2, info->flashSize2 ); if( !info->isValid ) return false; out->skip = false; out->fpIn = NULL; out->memIn = NULL; if( checkFileNameExtension( info->fileName, ".bin" ) || checkFileNameExtension( info->fileName, ".dsc" ) ) { out->fpIn = openMergeSource( info->fileName, isAllowSkip ); if( out->fpIn == NULL ) { ret = false; out->skip = isAllowSkip; } out->cpySize = checkMergeSourceSize( info->fileName, fileSize, flashSize ); if( out->cpySize <= 0 ) { ret = false; if( out->cpySize == 0 ) out->skip = true; } } else { out->cpySize = info->flashSize1 + info->flashSize2; out->memIn = transferFileToMemory( info ); if( out->memIn == NULL ) ret = false; } out->memOut = getMergeFlashTempMem( info->flashAddr1 ); if( out->memOut == NULL ) ret = false; if( info->flashAddr2) { if( out->cpySize > info->flashSize1 ) { out->cpySize2 = out->cpySize - info->flashSize1; out->cpySize = info->flashSize1; } out->memOut2 = getMergeFlashTempMem( info->flashAddr2 ); if(out->memOut2 == NULL) ret = false; } else { out->cpySize2 = 0; out->memOut2 = NULL; } if( out->skip ) ret = true; if( !ret ) releaseMergeInfoOut( out ); return ret; } #endif #if 0 bool mergeToBinCrossFlash( NorFlashModuleInfo *moduleInfo ) { bool ret = true; MergeInfoOut infoOut; ret = getMergeInfo( &infoOut, moduleInfo ); if( !ret ) return false; if( !infoOut.skip ) { if( infoOut.memIn != NULL ) { memcpy( infoOut.memOut, infoOut.memIn, infoOut.cpySize ); memcpy( infoOut.memOut2, infoOut.memIn + infoOut.cpySize, infoOut.cpySize2 ); } else { ret = moveFileContent( infoOut.memOut, infoOut.fpIn, infoOut.cpySize ); if( ret && infoOut.cpySize2 ) ret = moveFileContent( infoOut.memOut2, infoOut.fpIn, infoOut.cpySize2 ); } } releaseMergeInfoOut( &infoOut ); return ret; } #endif //------------------------------------------------------------------------------- #if 0 bool calculateImageValidSize( u32 *codeValidSizeKB, u32 *dataValidSizeKB ) { int action = 0; bool ret = true; MergeInfoOut infoOut; NorFlashModuleInfo *moduleInfo = &flashModuleInfo[MODULE_KERNEL];//searchModuleInfo(MODULE_KERNEL); if( moduleInfo == NULL ) return false; if( SPI_IS_WITH_NANDFLASH ) /* don't do that for Nand-flash case ... */ { *codeValidSizeKB = CONFIG_CODE_FLASH_SIZE; *dataValidSizeKB = CONFIG_DATA_FLASH_SIZE; return true; } /* action = 0 : Effective flash size. ( Specified kernel module reference file) action = 1 : totally flash size without kernel. ( kernel content is protected or reference invalid file ) action = 2 : basic image's flash size. ( kernel module will refer to basic image. ) */ if( moduleInfo->isProtected ) action = 1; else if( !moduleInfo->isValid ) action = isLoadBasicPacket() ? 2 : 1; if( action ) { u32 removeKernelSize; dbgMsg( "calculateImageValidSize: skip Kernel\n"); removeKernelSize= ROUND_KB( moduleInfo->flashAddr1 - SPI_CODEFLASH_BASEADDR ); if( action == 2 ) { int basicDataImageSize = ROUND_KB( getFileSize(BASEIMAGE_DATABIN) ); *codeValidSizeKB = ROUND_KB( getFileSize(BASEIMAGE_CODEBIN) ); *dataValidSizeKB = ( basicDataImageSize > 0 ) ? basicDataImageSize : 0; } else if( action == 1 ) { *codeValidSizeKB = removeKernelSize; *dataValidSizeKB = 0; } if( *codeValidSizeKB <= removeKernelSize ) moduleInfo->isProtected = true; return true; } ret = getMergeInfo( &infoOut, moduleInfo ); if( !ret ) return false; if( infoOut.cpySize2 ) { *codeValidSizeKB = CONFIG_CODE_FLASH_SIZE; *dataValidSizeKB = ROUND_KB( infoOut.cpySize2 ); } else { *codeValidSizeKB = ROUND_KB( moduleInfo->flashAddr1 + infoOut.cpySize - SPI_CODEFLASH_BASEADDR ); *dataValidSizeKB = 0; } releaseMergeInfoOut( &infoOut ); return true; } #endif //------------------------------------------------------------------------------- #define BACKUP_CHECK_MAGIC (0xA110C001) #define BACKUP_MAGIC_LENGTH (4) #if 0 //gaia, remove featrue 2013.04.23 bool mergeToBin_Backup64K() { u8 *memOut; u8 *memIn; u32 magicNumber = BACKUP_CHECK_MAGIC; u32 sourceFlashAddr = SPI_MEMALLOCINFO_FLASHADDR; u32 targetFlashAddr = SPI_MEMALLOCBACKUP_FLASHADDR; dbgMsg( "[CreateBackup64K] 0x%08x => 0x%08x\n", sourceFlashAddr, targetFlashAddr ); memIn = getMergeFlashTempMem( sourceFlashAddr ); memOut = getMergeFlashTempMem( targetFlashAddr ); if( (memIn == NULL) || (memOut == NULL) ) return false; memcpy( memIn+0xfffc, &magicNumber, BACKUP_MAGIC_LENGTH ); memcpy( memOut, memIn, 64*1024 ); return true; } bool mergeToBin_BackupRRT() { #if( SPI_RRTTABLE2_FLASHSIZE != 0 ) u8 *memOut; u8 *memIn; u32 sourceFlashAddr = ALIGNMENT( SPI_RRTTABLE_FLASHADDR, 64*1024 ); u32 targetFlashAddr = SPI_RRTTABLE2_FLASHADDR; dbgMsg( "[CreateBackupRRT] 0x%08x => 0x%08x\n", sourceFlashAddr, targetFlashAddr ); memIn = getMergeFlashTempMem( sourceFlashAddr ); memOut = getMergeFlashTempMem( targetFlashAddr ); if( (memIn == NULL) || (memOut == NULL) ) return false; memcpy( memOut, memIn, SPI_RRTTABLE2_FLASHSIZE ); #endif return true; } #endif //------------------------------------------------------------------------------- bool mergeToBin_GenerateOption(char *output_name) { #if defined(OP_IRCommandType) u32 memSize = sizeof(CUSTIMIZATION_TABLE); //u8 *memIn = (u8*) &OptionData; //u8 *memOut = getMergeFlashTempMem( SPI_OPTIONDATA_FLASHADDR ); showMsg( "[GenerateOption] \n" ); #if 0 if( SPI_OPTIONDATA_FLASHSIZE < memSize ) { errMsg( "Option (%x Bytes) > %x Bytes\n", memSize, SPI_OPTIONDATA_FLASHSIZE); return false; } #endif if( GetOptionData() != 0 ) // generate OptionData content { errMsg( "GetOptionData failed\n"); return false; } FILE *fpOut = fopen( output_name, "wb" ); fwrite( &OptionData, 1, memSize, fpOut ); fclose( fpOut ); //memcpy( memOut, memIn, memSize ); #endif return true; } //------------------------------------------------------------------------------- bool mergeToBin_GenerateUMFDefaultSetting() { bool ret = true; #if defined(CONFIG_UMFSWMERGE) u8 *memOut1 = getMergeFlashTempMem( SPI_MENUDEFAULT_FLASHADDR ); syscmd( "./umfSWMergeAP" ); // TODO: parsing multiTable data, and write it to memory if( ret ) ret = copyFileToMemory( memOut1 , FILENAME_MENUDFTTMP, SPI_MENUDEFAULT_FLASHSIZE ); removeTempFile( FILENAME_MENUDFTTMP ); #ifndef CONFIG_MULTITABLE /*copy PQ defaul data to flash*/ u8 *memOut_PQ_DF = getMergeFlashTempMem(SPI_PICTUREDEFAULT_FLASHADDR); if( ret ) ret &= copyFileToMemory(memOut_PQ_DF , FILENAME_PQDFTTMP, SPI_PICTUREDEFAULT_FLASHSIZE ); removeTempFile(FILENAME_PQDFTTMP); /*copy AQ defaul data to flash*/ u8 *memOut_AQ_DF = getMergeFlashTempMem(SPI_AUDIODEFAULT_FLASHADDR); if( ret ) ret &= copyFileToMemory(memOut_AQ_DF , FILENAME_AQDFTTMP, SPI_AUDIODEFAULT_FLASHSIZE ); removeTempFile(FILENAME_AQDFTTMP); /*copy Color Temp defaul data to flash*/ u8 *memOut_ColorTemp_DF = getMergeFlashTempMem(SPI_COLORTEMP_FLASHADDR); if( ret ) ret &= copyFileToMemory(memOut_ColorTemp_DF , FILENAME_ColorTempDFTTMP, SPI_COLORTEMPDEFAULT_FLASHSIZE ); removeTempFile(FILENAME_ColorTempDFTTMP); #endif #endif return ret; }