static int optimus_storage_open(struct ImgBurnInfo* pDownInfo, const u8* data, const u32 dataSz) { int ret = OPT_DOWN_OK; const char* partName = (const char*)pDownInfo->partName; const int imgType = pDownInfo->imgType; const int MediaType = pDownInfo->storageMediaType; if(!pDownInfo->imgSzDisposed && OPTIMUS_IMG_STA_PRE_BURN == pDownInfo->imgBurnSta) { DWN_MSG("Burn Start...\n"); pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_BURN_ING; } else if(pDownInfo->imgSzDisposed == pDownInfo->imgPktSz && OPTIMUS_IMG_STA_BURN_COMPLETE == pDownInfo->imgBurnSta) { DWN_MSG("Verify Start...\n"); pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_VERIFY_ING; } switch(MediaType) { case OPTIMUS_MEDIA_TYPE_NAND: case OPTIMUS_MEDIA_TYPE_SDMMC: case OPTIMUS_MEDIA_TYPE_STORE: { if(IMG_TYPE_BOOTLOADER != pDownInfo->imgType && !pDownInfo->devHdle)//if not bootloader and device not open { /*pDownInfo->devHdle = aml_nftl_get_dev(partName);*/ pDownInfo->devHdle = (void*)1; if(!pDownInfo->devHdle) { DWN_ERR("Fail to open nand part %s\n", partName); return OPT_DOWN_FAIL; } if(IMG_TYPE_SPARSE == imgType) { ret = optimus_simg_probe(data, dataSz); if(!ret){ DWN_ERR("Fail in sparse format probe,ret=%d\n", ret); return OPT_DOWN_FAIL; } return optimus_simg_parser_init(data); } } else//is bootloader, than do nothing { return OPT_DOWN_OK; } } break; case OPTIMUS_MEDIA_TYPE_KEY_UNIFY: break; case OPTIMUS_MEDIA_TYPE_MEM: break; default: DWN_MSG("Error MediaType %d\n", MediaType); return OPT_DOWN_FAIL; } return ret; }
EXPORT #endif int image_pack(const char* cfg_file, const char* src_dir ,const char* target_file) { struct stat64 s; FILE* fp_read = NULL; FILE* fp_write = NULL; char *tmp; int count = 0; size_t write_bytes = 0; ItemInfo* totalItemInfo = NULL; char *buff = NULL; int ret = 0; ItemInfo* AmlItem = NULL; if(!cfg_file||!src_dir||!target_file){ fprintf(stderr,"invalid param! \n"); return -1; } if(stat64(cfg_file, &s)){ fprintf(stderr,"could not stat '%s'\n", cfg_file); return -1; } fp_read = fopen(cfg_file, "rb"); if (fp_read == NULL){ fprintf(stderr,"failed to open canned file \n"); return -1; } tmp = (char*) malloc(s.st_size); if(tmp == NULL) { fprintf(stderr,"allocate memccpy failed at %s %d \n", __FILE__,__LINE__); free(tmp); return -1; } if(fread(tmp,1, s.st_size,fp_read) != s.st_size) { fprintf(stderr,"file read error [%s] \n", strerror(errno)); fclose(fp_read); free(tmp); return -1; } fclose(fp_read); if(image_cfg_parse(tmp,s.st_size) < 0){ fprintf(stderr,"image_cfg_parse error! \n"); free(tmp); return -1; } free(tmp); tmp = NULL; if(image_check_files(src_dir)<0){ fprintf(stderr,"image check file error! \n"); return -1; } fp_write = fopen(target_file, "wb+"); if (fp_write == NULL){ fprintf(stderr,"failed to create target file! \n"); return -1; } AmlFirmwareImg_t aAmlImage; AmlFirmwareImg_t *FirmwareImg = &aAmlImage; memset(FirmwareImg,0,sizeof(AmlFirmwareImg_t)); if(fwrite(FirmwareImg,1, sizeof(AmlFirmwareImg_t),fp_write) != sizeof(AmlFirmwareImg_t)) { fprintf(stderr,"cannot write %u bytes\n", (unsigned)sizeof(AmlFirmwareImg_t)); fclose(fp_write); return -1; } const int TotalItemCnt = ImageDecoder->gItemCount; debugP("TotalItemCnt %d\n", TotalItemCnt); totalItemInfo = new ItemInfo[TotalItemCnt]; memset(totalItemInfo,0,sizeof(ItemInfo) * TotalItemCnt); write_bytes = fwrite(totalItemInfo,1, sizeof(ItemInfo) * TotalItemCnt, fp_write); if(write_bytes != sizeof(ItemInfo)* TotalItemCnt){ fprintf(stderr,"cannot write %d bytes \n", (int)sizeof(ItemInfo)); ret = __LINE__; goto _exit; } buff = new char[RW_MAX_SIZE]; if(buff==NULL){ fprintf(stderr,"allocate memccpy failed at %s %d \n", __FILE__,__LINE__); ret = __LINE__; goto _exit; } //For each list: //1, create item info; 2,pack the item data; 3, crate verify item info; 4, pack verify data AmlItem = totalItemInfo; for(const FileList *list = ImageDecoder->gImageCfg.file_list; list; list = list->next, AmlItem++, count++) { struct stat64 info; char path[256]={0}; memset(path,0,256); strcpy(path,src_dir); strcat(path,list->name); printf("pack [%-12s, %16s] from (%s)\n", list->main_type, list->sub_type, path); fp_read = fopen(path,"rb"); if(fp_read == NULL){ fprintf(stderr,"failed to open source file : %s \n",path); ret = -1; break; } if(stat64(path,&info)<0){ fprintf(stderr,"stat %s failed!\n",path); ret = -1; break; } AmlItem->itemSz = info.st_size; AmlItem->itemId = count; AmlItem->verify = 0;//1 if a verify item strcpy(AmlItem->itemMainType,list->main_type); strcpy(AmlItem->itemSubType,list->sub_type); const ItemInfo* foundSamFileItemInfo = previous_duplicated_item_id(ImageDecoder->gImageCfg.file_list, list, totalItemInfo, AmlItem); if(foundSamFileItemInfo)//this item is source from a duplicated file item { AmlItem->offsetInImage = foundSamFileItemInfo->offsetInImage; AmlItem->fileType = foundSamFileItemInfo->fileType; AmlItem->isBackUpItem = 1; AmlItem->backUpItemId = foundSamFileItemInfo->itemId; } else { AmlItem->offsetInImage = ftello(fp_write); if(AmlItem->offsetInImage % ITEM_ALGIN){ AmlItem->offsetInImage += ITEM_ALGIN - AmlItem->offsetInImage % ITEM_ALGIN; } fseeko(fp_read,0,SEEK_SET); write_bytes = fread(buff,1,RW_MAX_SIZE,fp_read); if(optimus_simg_probe(buff,RW_HEAD_SIZE) == 0){ AmlItem->fileType = IMAGE_ITEM_TYPE_NORMAL; }else{ AmlItem->fileType = IMAGE_ITEM_TYPE_SPARSE; } //Following create the item data // fseeko(fp_write,AmlItem->offsetInImage,SEEK_SET); fseeko(fp_read,0,SEEK_SET); while((write_bytes = fread(buff,1,RW_MAX_SIZE,fp_read))>0) { if(fwrite(buff,1,write_bytes,fp_write)!=write_bytes){ fprintf(stderr,"write to image file fail! [%s] \n",strerror(errno)); ret = -1; break; } } fclose(fp_read); if(ret < 0) break; } if(list->verify) { ++count; ++AmlItem; AmlItem->itemSz = 48; AmlItem->itemId = count; strcpy(AmlItem->itemMainType,"VERIFY"); strcpy(AmlItem->itemSubType,list->sub_type); AmlItem->fileType = IMAGE_ITEM_TYPE_NORMAL; AmlItem->verify = 1; if(foundSamFileItemInfo)//the source file is already packed { const ItemInfo* verfiyItem4_foundItem = foundSamFileItemInfo + 1; //test if the next item following foundSamFileItemInfo is verify item if(!strcmp(foundSamFileItemInfo->itemSubType, verfiyItem4_foundItem->itemSubType) && !strcmp(verfiyItem4_foundItem->itemMainType, AmlItem->itemMainType))//"VERIFY" { AmlItem->offsetInImage = verfiyItem4_foundItem->offsetInImage; AmlItem->isBackUpItem = 1; AmlItem->backUpItemId = verfiyItem4_foundItem->itemId; continue;//skip followings } } AmlItem->offsetInImage = ftello(fp_write); if(AmlItem->offsetInImage % ITEM_ALGIN){ AmlItem->offsetInImage += ITEM_ALGIN - AmlItem->offsetInImage % ITEM_ALGIN; } memset(buff,0,48); gen_sha1sum_verify(path, buff); fseeko(fp_write,AmlItem->offsetInImage,SEEK_SET); if(fwrite(buff,1,48,fp_write)!=48){ fprintf(stderr,"write verify data to image file fail! [%s] \n",strerror(errno)); ret = -1; break; } } } free(buff); buff = 0; FirmwareImg->magic = IMAGE_MAGIC; FirmwareImg->version = VERSION; FirmwareImg->itemNum = count; fseeko(fp_write, 0L, SEEK_END); FirmwareImg->imageSz = ftello(fp_write); FirmwareImg->itemAlginSize = 4; fseeko(fp_write,0L,SEEK_SET); if(fwrite(FirmwareImg,1, sizeof(AmlFirmwareImg_t),fp_write) != sizeof(AmlFirmwareImg_t)) { fprintf(stderr,"cannot write %u bytes [%s] [0x%p]\n", (unsigned)sizeof(AmlFirmwareImg_t), strerror(errno), fp_write); ret = -1; } write_bytes = fwrite(totalItemInfo, 1, sizeof(ItemInfo) * TotalItemCnt, fp_write); if(write_bytes != sizeof(ItemInfo) * TotalItemCnt){ errorP("fail to update item info\n"); ret = __LINE__; goto _exit; } FirmwareImg->crc = calc_img_crc(fp_write,FirmwareImg->itemAlginSize); fseeko(fp_write,0L,SEEK_SET); if(fwrite(&(FirmwareImg->crc),1,FirmwareImg->itemAlginSize,fp_write) != FirmwareImg->itemAlginSize) { fprintf(stderr,"cannot write crc32 [0x%x] [%s] \n",FirmwareImg->crc ,strerror(errno)); ret = -1; } printf("Size=0x%llxB[%lluM], crc=0x%x, Install image[%s] OK\n", FirmwareImg->imageSz, (FirmwareImg->imageSz>>20), FirmwareImg->crc, target_file); _exit: if(fp_write)fclose(fp_write), fp_write = NULL; if(totalItemInfo)delete[] totalItemInfo, totalItemInfo = NULL; if(buff) delete[] buff, buff = NULL; return ret; }