Пример #1
0
static int image_check(HIMAGE hImage)
{
	FILE* fp = (FILE*)hImage;
	unsigned int crc32 = 0;
	
	if(ImageDecoder->AmlFirmwareImg->crc==0){
		fseeko(fp,0,SEEK_SET);
		memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
		if(fread(ImageDecoder->AmlFirmwareImg,sizeof(AmlFirmwareImg_t),1, fp) != 1) {
			fprintf(stderr,"cannot read %u bytes  [%s]\n", (unsigned)sizeof(AmlFirmwareImg_t),strerror(errno));
			return -1;
		}
	}

	if(ImageDecoder->AmlFirmwareImg->magic != IMAGE_MAGIC){
    	fprintf(stderr,"the magic number is not match \n");
    	return -1;
	}

	crc32 = calc_img_crc(fp, ImageDecoder->AmlFirmwareImg->itemAlginSize);
	printf("crc32==0x%x\n",crc32);
	printf("ImageDecoder->AmlFirmwareImg->crc==0x%x\n",ImageDecoder->AmlFirmwareImg->crc);
	if(crc32!=ImageDecoder->AmlFirmwareImg->crc){
    	fprintf(stderr,"crc check fail !!! \n");
    	return -1;
	}
	return 0;
}
Пример #2
0
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;
}
Пример #3
0
/*
 * 1,
 */
static int _img_pack(const char** const path_src, const char* const packedImg, 
        pFunc_getFile getFile, const int totalFileNum)
{
        FILE *fd_src = NULL;
        FILE *fd_dest = NULL;
        unsigned int pos = 0;
        char file_path[MAX_PATH];
        const char *filename = NULL;
        unsigned imageSz = 0;
        const unsigned BufSz = ITEM_READ_BUF_SZ;
        char* itemBuf = NULL;
        unsigned thisWriteLen = 0;
        unsigned actualWriteLen = 0;
        int ret = 0;
        __hdle hDir = NULL;
        const unsigned   itemAlignSz  = AML_RES_IMG_ITEM_ALIGN_SZ;
        const unsigned   itemAlignMod = itemAlignSz - 1;
        const unsigned   itemSzAlignMask = ~itemAlignMod;
        const unsigned   totalItemNum = totalFileNum ? totalFileNum : get_dir_filenums(*path_src);
        const unsigned   HeadLen    = IMG_HEAD_SZ + ITEM_HEAD_SZ * totalItemNum;

        if(HeadLen > BufSz){
                errorP("head size 0x%x > max(0x%x)\n", HeadLen, BufSz); return __LINE__;
        }
        fd_dest = fopen(packedImg, "wb+");
        if(NULL == fd_dest)	{
                fprintf(stderr,"open %s failed: %s\n", packedImg, strerror(errno));
                return __LINE__;
        }

        itemBuf = new char[BufSz * 2];
        if(!itemBuf){
                errorP("Exception: fail to alloc buuffer\n");
                fclose(fd_dest); return __LINE__;
        }
        memset(itemBuf, 0, BufSz*2);
        AmlResImgHead_t* const aAmlResImgHead = (AmlResImgHead_t*)(itemBuf + BufSz);

        actualWriteLen = fwrite(aAmlResImgHead, 1, HeadLen, fd_dest);
        if(actualWriteLen != HeadLen){
                errorP("fail to write head, want 0x%x, but 0x%x\n", HeadLen, actualWriteLen);
                fclose(fd_dest); delete[] itemBuf;
                return __LINE__;
        }
        imageSz += HeadLen; //Increase imageSz after pack each item
        AmlResItemHead_t*       pItemHeadInfo           = (AmlResItemHead_t*)(aAmlResImgHead + 1);
        AmlResItemHead_t* const pFirstItemHeadInfo      = pItemHeadInfo;

        debugP("item num %d\n", totalItemNum);
        //for each loop: first create item header and pack it, second pack the item data
        //Fill the item head, 1) magic, 2)data offset, 3)next head start offset
        for(unsigned itemIndex = 0; itemIndex < totalItemNum; ++itemIndex)
        {
                char filePath[MAX_PATH*2];

                if(totalFileNum)//File list mode
                {
                        if((*getFile)(path_src, (__hdle*)itemIndex, filePath)) {
                                break;
                        }
                }
                else
                {//file directory mode
                        if((*getFile)(path_src, &hDir, filePath)) {
                                break;
                        }
                }
                const size_t itemSz = get_filesize(filePath);
                const char*  itemName = get_filename(filePath);
                const unsigned itemBodyOccupySz =  (itemSz & itemSzAlignMask) + itemAlignSz;
                const unsigned itemStuffSz      = itemBodyOccupySz - itemSz;

                if(IH_NMLEN - 1 < strlen(itemName)){
                        errorP("Item name %s len %d > max(%d)\n", itemName, (int)strlen(itemName), IH_NMLEN - 1);
                        ret = __LINE__; goto _exit;
                }
                pItemHeadInfo->magic = IH_MAGIC;
                pItemHeadInfo->size = itemSz;
                //imageSz += ITEM_HEAD_SZ;//not needed yet as all item_head moves to image header
                pItemHeadInfo->start = imageSz;
                pItemHeadInfo->next  =  (char*)(pItemHeadInfo + 1) - (char*)aAmlResImgHead;
                pItemHeadInfo->index = itemIndex;
                imageSz   += itemBodyOccupySz;
                pItemHeadInfo->nums   = totalItemNum;
                memcpy(pItemHeadInfo->name, itemName, strlen(itemName));
                debugP("pack item [%s]\n", itemName);
                ++pItemHeadInfo;//prepare for next item 

                fd_src = fopen(filePath, "rb");
                if(!fd_src){
                        errorP("Fail to open file [%s], strerror[%s]\n", filePath, strerror(errno));
                        ret = __LINE__; goto _exit;
                }
                for(size_t itemWriteLen = 0; itemWriteLen < itemSz; itemWriteLen += thisWriteLen)
                {
                        size_t leftLen = itemSz - itemWriteLen;

                        thisWriteLen = leftLen > BufSz ? BufSz : leftLen;
                        actualWriteLen = fread(itemBuf, 1, thisWriteLen, fd_src);
                        if(actualWriteLen != thisWriteLen){
                                errorP("Want to read 0x%x but actual 0x%x, at itemWriteLen 0x%x, leftLen 0x%x\n", 
                                                thisWriteLen, actualWriteLen, (unsigned)itemWriteLen, (unsigned)leftLen);
                                ret = __LINE__; goto _exit;
                        }
                        actualWriteLen = fwrite(itemBuf, 1, thisWriteLen, fd_dest);
                        if(actualWriteLen != thisWriteLen){
                                errorP("Want to write 0x%x but actual 0x%x\n", thisWriteLen, actualWriteLen);
                                ret = __LINE__; goto _exit;
                        }
                }
                fclose(fd_src), fd_src = NULL;
                memset(itemBuf, 0, itemStuffSz);
                thisWriteLen = itemStuffSz;
                actualWriteLen = fwrite(itemBuf, 1, thisWriteLen, fd_dest);
                if(actualWriteLen != thisWriteLen){
                        errorP("Want to write 0x%x, but 0x%x\n", thisWriteLen, actualWriteLen);
                        ret = __LINE__; goto _exit;
                }
        }
        (--pItemHeadInfo)->next = 0;

        //Create the header 
        aAmlResImgHead->version = AML_RES_IMG_VERSION_V2;
        memcpy(&aAmlResImgHead->magic[0], AML_RES_IMG_V1_MAGIC, AML_RES_IMG_V1_MAGIC_LEN);
        aAmlResImgHead->imgSz       = imageSz;
        aAmlResImgHead->imgItemNum  = totalItemNum;
        aAmlResImgHead->alignSz     = itemAlignSz;
        aAmlResImgHead->crc         = 0;
        //
        //Seek to file header to correct the header
        fseek(fd_dest, 0, SEEK_SET);
        actualWriteLen = fwrite(aAmlResImgHead, 1, HeadLen, fd_dest);
        if(actualWriteLen != HeadLen){
                errorP("Want to write 0x%x, but 0x%x\n", HeadLen, actualWriteLen);
                ret = __LINE__; goto _exit;
        }

        aAmlResImgHead->crc = calc_img_crc(fd_dest, 4);//Gen crc32
        fseek(fd_dest, 0, SEEK_SET);
        actualWriteLen = fwrite(&aAmlResImgHead->crc, 1, 4, fd_dest);
        if(4 != actualWriteLen){
                errorP("Want to write 4, but %d\n", actualWriteLen);
                ret = __LINE__; goto _exit;
        }

_exit:
        if(itemBuf) delete[] itemBuf, itemBuf = NULL;
        if(fd_src) fclose(fd_src), fd_src = NULL;
        if(fd_dest) fclose(fd_dest), fd_dest = NULL;
        return ret;
}