* from https://github.com/khadas/buildroot_buildroot/tree/buildroot/package/aml_image_packer/src
Change-Id: I708523bffc5e3b1152fcf747f48f62c108034efe
--- /dev/null
+#
+# Copyright 2013 The Amlogic Iamge Pack Tool
+#
+# image pack tool
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+SRC_FILES := \
+ crc32.c \
+ sha1.c \
+ amlImage.c \
+ sparse_format.c
+
+ifeq ($(strip $(USE_MINGW)),y)
+#################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_MODULE := libimagepack
+LOCAL_CFLAGS := -DBUILD_LIBRARY -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -DBUILD_WITH_MINGW
+ifeq ($(strip $(USE_MINGW)),y)
+LOCAL_CFLAGS += -DBUILD_DLL
+endif
+
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+
+#################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_CFLAGS := -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -DBUILD_WITH_MINGW
+LOCAL_MODULE := aml_image_packer
+
+include $(BUILD_HOST_EXECUTABLE)
+
+else
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_STATIC_LIBRARIES := libc
+LOCAL_MODULE := libimagepack
+LOCAL_CFLAGS := -DBUILD_LIBRARY -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+
+include $(BUILD_STATIC_LIBRARY)
+#################################
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_SYSTEM_SHARED_LIBRARIES := libc
+LOCAL_MODULE := libimagepack
+LOCAL_CFLAGS := -DBUILD_LIBRARY -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+
+include $(BUILD_SHARED_LIBRARY)
+
+
+#################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SRC_FILES)
+LOCAL_MODULE := aml_image_packer
+LOCAL_CFLAGS := -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+
+include $(BUILD_HOST_EXECUTABLE)
+
+endif
+
--- /dev/null
+
+image_packer: crc32.o sha1.o sparse_format.o amlImage.o
+ g++ --static -o aml_image_v2_packer crc32.o sha1.o sparse_format.o amlImage.o
+
+clean:
+ rm crc32.o sha1.o sparse_format.o amlImage.o
+
--- /dev/null
+/*
+ * \file amlImage.c
+ * \brief Amlogic firmware image interface
+ *
+ * \version 1.0.0
+ * \date 2013/5/21
+ * \author Vinson.Xu <binsheng.xu@amlogic.com>
+ *
+ * Copyright (c) 2013 Amlogic Inc. All Rights Reserved.
+ *
+ */
+#include "image_packer_i.h"
+
+extern "C" {
+int gen_sha1sum_verify(const char* srFile, char* verifyData);
+}
+
+#define COMPILE_TYPE_CHK(expr, t) typedef char t[(expr) ? 1 : -1]
+
+COMPILE_TYPE_CHK(AML_IMG_ITEM_INFO_SZ == sizeof(ItemInfo), aa);
+COMPILE_TYPE_CHK(AML_IMG_HEAD_INFO_SZ == sizeof(AmlFirmwareImg_t), bb);
+
+#define RW_MAX_SIZE 65536
+#define RW_HEAD_SIZE 8192
+#define ITEM_ALGIN 4
+
+#define debugP(...) //printf("dbg:"),printf(__VA_ARGS__)
+#define errorP(...) printf("ERR:"),printf(__VA_ARGS__)
+
+ImageDecoderIf_t *ImageDecoder;
+
+static HIMAGE image_open(const char* imagePath)
+{
+ FILE *fp = NULL;
+ fp = fopen(imagePath,"rb");
+ if(fp == NULL){
+ fprintf(stderr,"image open error! [%s]\n",strerror(errno));
+ }
+ return fp;
+}
+
+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;
+}
+
+static int image_close(HIMAGE hImage)
+{
+ if(hImage)
+ return fclose((FILE*)hImage);
+ return -1;
+}
+
+static HIMAGEITEM image_open_item(HIMAGE hImage, const char* mainType, const char* subType)
+{
+ FILE* fp = (FILE*)hImage;
+ HIMAGEITEM item = NULL;
+ unsigned int i = 0;
+ if(ImageDecoder->AmlFirmwareImg->crc==0){
+ memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+ fseeko(fp,0,SEEK_SET);
+
+ if(fread(ImageDecoder->AmlFirmwareImg,sizeof(AmlFirmwareImg_t),1,fp)!= 1) {
+ fprintf(stderr,"Read error[%s] \n", strerror(errno));
+ return NULL;
+ }
+ }
+
+ if(ImageDecoder->AmlFirmwareImg->magic != IMAGE_MAGIC){
+ fprintf(stderr,"the magic number is not match \n");
+ return NULL;
+ }
+
+ ItemInfo *AmlItem = NULL;
+ AmlItem = (ItemInfo*)malloc(sizeof(ItemInfo)*ImageDecoder->AmlFirmwareImg->itemNum);
+ if(AmlItem == NULL){
+ fprintf(stderr,"malloc %u bytes memmory failed \n", (unsigned)sizeof(ItemInfo));
+ return NULL;
+ }
+
+ fseeko(fp,sizeof(AmlFirmwareImg_t),SEEK_SET);
+ memset(AmlItem,0,sizeof(ItemInfo)*ImageDecoder->AmlFirmwareImg->itemNum);
+ unsigned int read_len = fread(AmlItem,sizeof(ItemInfo), ImageDecoder->AmlFirmwareImg->itemNum,fp);
+
+ if( read_len!= ImageDecoder->AmlFirmwareImg->itemNum) {
+ fprintf(stderr,"cannot read %u bytes [%s] \n", ImageDecoder->AmlFirmwareImg->itemNum,strerror(errno));
+ return NULL;
+ }
+
+ for(;i<ImageDecoder->AmlFirmwareImg->itemNum;i++){
+
+ if(!strncmp((AmlItem+i)->itemMainType,mainType,32)
+ &&!strncmp((AmlItem+i)->itemSubType,subType,32)){
+ item = malloc(sizeof(ItemInfo));
+ memcpy((void*)item,(void*)(AmlItem+i),sizeof(ItemInfo));
+ free(AmlItem);
+ AmlItem = NULL;
+ break;
+ }
+ }
+
+ if(AmlItem){
+ free(AmlItem);
+ }
+ /*
+ do{
+ memset(AmlItem,0,sizeof(ItemInfo));
+ if(fread(AmlItem,1, sizeof(ItemInfo),fp) != sizeof(ItemInfo)) {
+ fprintf(stderr,"cannot read %ud bytes", sizeof(ItemInfo));
+ return NULL;
+ }
+
+ if(!strncmp(AmlItem->itemMainType,mainType,32)
+ &&!strncmp(AmlItem->itemSubType,subType,32)){
+ item = (HIMAGEITEM)AmlItem;
+ break;
+ }
+
+ count ++;
+ if(count == ImageDecoder->AmlFirmwareImg->itemNum){
+ fprintf(stderr,"Item is not found!");
+ break;
+ }
+ }while(1);
+ */
+
+ return item;
+}
+
+
+static int image_close_item(HIMAGEITEM hItem){
+ if(hItem){
+ free(hItem);
+ hItem = NULL;
+ }
+
+ return 0;
+}
+
+//read item data, like standard fread
+static __u32 image_read_item_data(HIMAGE hImage, HIMAGEITEM hItem, void* buff, const __u32 readSz){
+ if(!hImage||!hItem){
+ fprintf(stderr,"invalid param!");
+ }
+ FILE* fp = (FILE*)hImage;
+ size_t readlen = 0 ;
+
+ //static __u32 item_offset = 0;
+ //static __u32 itemId_save = 0;
+ ItemInfo *item = (ItemInfo*)hItem;
+
+ //if(itemId_save!=item->itemId){
+ // item_offset = 0;
+ //}
+
+ if(item->curoffsetInItem >= item->itemSz){
+ //item_offset = 0;
+ //itemId_save = item->itemId;
+ return 0;
+ }
+
+ fseeko(fp,item->offsetInImage+item->curoffsetInItem,SEEK_SET);
+ if(readSz+item->curoffsetInItem >= item->itemSz){
+ readlen = item->itemSz-item->curoffsetInItem;
+ }else{
+ readlen = readSz;
+ }
+ if(fread(buff,readlen,1,fp)!=1){
+ fprintf(stderr,"read item error! [%s] \n",strerror(errno));
+ return 0;
+ }
+ item->curoffsetInItem += readlen;
+ //itemId_save = item->itemId;
+ return readlen;
+}
+
+//relocate the read pointer to read the item data, like standard fseeko
+static int image_seek_item(HIMAGE hImage, HIMAGEITEM hItem, __s64 offset, __u32 fromwhere)
+{
+ if(!hImage||!hItem){
+ fprintf(stderr,"invalid param!");
+ }
+ int ret = 0;
+ FILE* fp = (FILE*)hImage;
+ ItemInfo *item = (ItemInfo*)hItem;
+ fseeko(fp,item->offsetInImage,SEEK_SET);
+ switch(fromwhere){
+ case SEEK_SET:
+ ret = fseeko(fp,offset,SEEK_CUR);
+ item->curoffsetInItem = offset;
+ break;
+ case SEEK_CUR:
+ ret = fseeko(fp,item->curoffsetInItem+offset,SEEK_CUR);
+ item->curoffsetInItem += offset;
+ break;
+ case SEEK_END:
+ ret = fseeko(fp,item->itemSz+offset,SEEK_CUR);
+ item->curoffsetInItem = item->itemSz+offset;
+ break;
+ default:
+ fprintf(stderr,"invalid param for fromwhere!");
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+static __u64 image_get_item_size(HIMAGEITEM hItem)
+{
+ if(!hItem){
+ fprintf(stderr,"invalid param!");
+ return 0;
+ }
+
+ ItemInfo *item = (ItemInfo*)hItem;
+ return item->itemSz;
+}
+
+//is the item source is duplicated with other item
+//i.e, item data is empty
+//return value: 0/1 is ok, <0 is failed
+static int is_item_backup_for_other_item(HIMAGEITEM hItem, int* backItemId)
+{
+ ItemInfo *item = (ItemInfo*)hItem;
+ if(!hItem){
+ errorP("NULL item handle\n");
+ return -1;
+ }
+ *backItemId = item->backUpItemId;
+ return item->isBackUpItem;
+}
+
+static int image_get_item_type(HIMAGEITEM hItem)
+{
+ if(!hItem){
+ fprintf(stderr,"invalid param!");
+ }
+
+ ItemInfo *item = (ItemInfo*)hItem;
+ return item->fileType;
+}
+
+
+static int image_get_item_count(HIMAGE hImage,const char* mainType)
+{
+ int count = 0;
+ unsigned int total = 0;
+ FILE* fp = (FILE*)hImage;
+ if(ImageDecoder->AmlFirmwareImg->crc==0){
+ memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+ fseeko(fp,0,SEEK_SET);
+ if(fread(ImageDecoder->AmlFirmwareImg,sizeof(AmlFirmwareImg_t),1, fp) != 1) {
+ fprintf(stderr,"image_get_item_count : Read Err [%s] \n", strerror(errno));
+ return -1;
+ }
+ }
+
+ if(mainType == NULL){
+ return ImageDecoder->AmlFirmwareImg->itemNum;
+ }
+
+ ItemInfo *AmlItem = NULL;
+ AmlItem = (ItemInfo*)malloc(sizeof(ItemInfo));
+ if(AmlItem == NULL){
+ fprintf(stderr,"not enough memory \n");
+ return -1;
+ }
+ fseeko(fp,sizeof(AmlFirmwareImg_t),SEEK_SET);
+ do{
+ memset(AmlItem,0,sizeof(ItemInfo));
+ if(fread(AmlItem,1, sizeof(ItemInfo),fp) != sizeof(ItemInfo)) {
+ fprintf(stderr,"cannot read %u bytes", (unsigned)sizeof(ItemInfo));
+ return -1;
+ }
+
+ if(!strncmp(AmlItem->itemMainType,mainType,strlen(mainType))){
+ count ++;
+ }
+
+ //fseeko(fp,AmlItem->itemSz,SEEK_CUR);
+ total ++;
+ if(total == ImageDecoder->AmlFirmwareImg->itemNum){
+ break;
+ }
+ }while(1);
+
+ free(AmlItem);
+ return count;
+}
+
+static int image_get_next_item(HIMAGE hImage,unsigned int iItem, char* maintype, char* subtype)
+{
+ FILE* fp = (FILE*)hImage;
+ unsigned int nItem = 0;
+ if(ImageDecoder->AmlFirmwareImg->crc==0){
+ memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+ fseeko(fp,0,SEEK_SET);
+ if(fread(ImageDecoder->AmlFirmwareImg,1, sizeof(AmlFirmwareImg_t),fp) != sizeof(AmlFirmwareImg_t)) {
+ fprintf(stderr,"cannot read %u bytes", (unsigned)sizeof(AmlFirmwareImg_t));
+ return -1;
+ }
+ }
+
+ if(iItem >= ImageDecoder->AmlFirmwareImg->itemNum){
+ errorP("Item index %u > max %u\n", iItem, ImageDecoder->AmlFirmwareImg->itemNum - 1);
+ return -1;
+ }
+
+ fseeko(fp,sizeof(AmlFirmwareImg_t)+iItem*sizeof(ItemInfo),SEEK_SET);
+
+ ItemInfo AmlItem;
+ memset(&AmlItem,0,sizeof(ItemInfo));
+ if(fread(&AmlItem,sizeof(ItemInfo), 1,fp) != 1) {
+ fprintf(stderr,"image_get_next_item:Read Err [%s]", strerror(errno));
+ return -1;
+ }
+
+ strncpy(maintype,AmlItem.itemMainType,32);
+ strncpy(subtype,AmlItem.itemSubType,32);
+ /*debugP("[%s, %s] verify = %d\n", maintype, subtype, AmlItem.verify);*/
+ return 0;
+}
+
+//#define TAG_WORKDIR "work_dir"
+//#define TAG_ARCHIVE "archive_file"
+#define TAG_NORMALLIST "[LIST_NORMAL]"
+#define TAG_VERIFYLIST "[LIST_VERIFY]"
+
+#define TAG_LINE "\r\n"
+#define TAG_LINE_1 "\n"
+
+#define FILE_TAG "file="
+#define MTYPE_TAG "main_type="
+#define STYPE_TAG "sub_type="
+
+static int image_cfg_parse(char *data,int length)
+{
+ int ret = 0;
+
+ char *key_normal, *key_verify;
+ char *proc , *proc_end;
+ FileList *list = NULL ;
+ int verify = 0;
+
+ key_normal = strstr(data,TAG_NORMALLIST);
+ if(key_normal==NULL){
+ printf("image.cfg parse err: miss [LIST_NORMAL] node \n");
+ }
+
+ key_verify = strstr(data,TAG_VERIFYLIST);
+ if(key_verify==NULL){
+ printf("image.cfg parse: no [LIST_VERIFY] node \n");
+ }
+
+ if(!key_normal&&!key_verify){
+ return -1;
+ }
+ const char* tag_line = TAG_LINE;
+ char* token = strtok(data, TAG_LINE);
+ if(token==NULL){
+ token = strtok(data, TAG_LINE_1);
+ tag_line = TAG_LINE_1;
+ }
+ for( ;token != NULL; token = strtok(NULL,tag_line))
+ {
+ if(*token == '#'){
+ debugP("skip line: %s \n",token);
+ continue;
+ }
+ proc = strstr(token,FILE_TAG);
+ if(proc == NULL){
+ continue;
+ }
+
+ if(key_verify > key_normal){
+ if(proc > key_normal && proc < key_verify){
+ verify = 0;
+ }else if(proc > key_verify ){
+ verify = 1;
+ ImageDecoder->gItemCount ++;
+ }else{
+ printf("invalid list\n");
+ continue;
+ }
+ }else{
+ if(proc > key_normal ){
+ verify = 0;
+ }else if(proc > key_verify && proc < key_normal){
+ verify = 1;
+ ImageDecoder->gItemCount ++;
+ }else{
+ printf("invalid list\n");
+ continue;
+ }
+ }
+ if(list == NULL){
+ list = (FileList*)malloc(sizeof(FileList));
+ ImageDecoder->gImageCfg.file_list = list;
+
+ }else{
+ list->next = (FileList*)malloc(sizeof(FileList));
+ list = list->next;
+ }
+
+ memset(list,0,sizeof(FileList));
+ list->verify = verify;
+
+ proc = strchr(proc+strlen(FILE_TAG),'\"');
+ proc_end = strchr(proc+1,'\"');
+ strncpy(list->name,proc+1,proc_end-proc-1);
+ //printf("file: %s ",list->name);
+
+ proc = strstr(token,MTYPE_TAG);
+ if(proc == NULL){
+ continue;
+ }
+
+ proc = strchr(proc+strlen(MTYPE_TAG),'\"');
+ proc_end = strchr(proc+1,'\"');
+ strncpy(list->main_type,proc+1,proc_end-proc-1);
+ //printf("main_type: %s ",list->main_type);
+
+ proc = strstr(token,STYPE_TAG);
+ if(proc == NULL){
+ continue;
+ }
+
+ proc = strchr(proc+strlen(STYPE_TAG),'\"');
+ proc_end = strchr(proc+1,'\"');
+ strncpy(list->sub_type,proc+1,proc_end-proc-1);
+ debugP("sub_type: %s \n",list->sub_type);
+ ImageDecoder->gItemCount ++;
+ }
+
+ list = ImageDecoder->gImageCfg.file_list;
+ FileList *plist = ImageDecoder->gImageCfg.file_list;
+ while(ret==0&&list){
+ for(plist = ImageDecoder->gImageCfg.file_list;plist;plist=plist->next){
+
+ if(plist!=list&&(!strcmp(list->main_type,plist->main_type))&&(!strcmp(list->sub_type,plist->sub_type))){
+ fprintf(stderr,"Error: config file is illegal! \nmain_type:[%s] sub_type:[%s] is reduplicate \n",list->main_type,list->sub_type);
+ ret = -1;
+ break;
+ }
+ }
+ list = list->next;
+ }
+ if(ret < 0){
+ list = ImageDecoder->gImageCfg.file_list;
+ while(list){
+ plist = list->next;
+ free(list);
+ list = plist;
+ }
+ }
+ return ret;
+}
+
+static int image_check_files(const char* src_dir)
+{
+ char path[256]={0};
+ FileList *list = ImageDecoder->gImageCfg.file_list;
+ do{
+ memset(path,0,256);
+ strcpy(path,src_dir);
+ strcat(path,list->name);
+ debugP("path: %s\n", path);
+ //if(access(path,F_OK|R_OK) < 0){
+ if(access(path, 0) < 0){
+ printf("Err:%s is not found! \n",path);
+ return -1;
+ }
+ list = list->next;
+ }while(list!=NULL);
+
+ return 0;
+}
+
+//return the item id, >= 0 if OK
+/*
+ * duplicated item like this, which source is the same file 'boot.PARTITION' but sub_type.main_type are different
+ *file="boot.PARTITION" main_type="PARTITION" sub_type="boot"
+ *file="boot.PARTITION" main_type="PARTITION" sub_type="bootbak"
+ */
+static const ItemInfo* previous_duplicated_item_id(const FileList* headFileList, const FileList* const curFileList,
+ const ItemInfo* headItemInfo, const ItemInfo* curItemInfo)
+{
+ int itemId = -1;
+ int i = 0;
+
+ for(;headFileList != curFileList && headFileList->next; headFileList = headFileList->next)
+ {
+ int rc = strcmp(curFileList->name, headFileList->name);
+ if(!rc)//the file of headFileList is duplicated
+ {
+ for(; headItemInfo < curItemInfo; headItemInfo++)
+ {
+ if(!strcmp(headItemInfo->itemMainType, headFileList->main_type)
+ && !strcmp(headItemInfo->itemSubType, headFileList->sub_type))
+ {
+ return headItemInfo;
+ }
+ }
+ errorP("find duplicated file(%s) but previous item not found\n", curFileList->name);
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+#ifdef BUILD_DLL
+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;
+}
+
+const char* const IMG_CFG_LINE = "file=\"%s.%s\"\t\tmain_type=\"%s\"\t\tsub_type=\"%s\"\r\n";
+
+#ifdef BUILD_DLL
+EXPORT
+#endif
+
+int image_unpack(const char* imagefile,const char *outpath)
+{
+ int ret = 0;
+ unsigned int itemCountTotal = 0;
+ unsigned int nItem = 0;
+ unsigned int write_bytes = 0;
+ char main_type[32] = {0};
+ char sub_type[32] = {0};
+ char outfile[512] = {0};
+ char cfgfile[128] = {0};
+ char buff[256] = {0};
+
+ #ifdef BUILD_DLL
+ if(ImageDecoder->AmlFirmwareImg == NULL){
+ ImageDecoder->AmlFirmwareImg = (AmlFirmwareImg_t*)malloc(sizeof(AmlFirmwareImg_t));
+ if(ImageDecoder->AmlFirmwareImg == NULL){
+ fprintf(stderr,"not enough memory\n");
+ return -1;
+ }
+ }
+ #endif
+
+ if(outpath){
+ strcpy(outfile,outpath);
+ strcat(outfile,"\\");
+ strcpy(cfgfile,outfile);
+ }
+ strcat(cfgfile,"image.cfg");
+
+ HIMAGE hImage = image_open(imagefile);
+ if(image_check(hImage) < 0){
+ fprintf(stderr,"the image check fail!!\n");
+ return -1;
+ }else{
+ printf("the image check ok!\n");
+ }
+
+ itemCountTotal = image_get_item_count(hImage,NULL);
+ const unsigned itemCountVerify = image_get_item_count(hImage, "VERIFY");
+ const unsigned itemCountNormal = itemCountTotal - itemCountVerify * 2;
+ debugP("item cnt:total[%u], normal[%u], verify[%u]\n", itemCountTotal, itemCountNormal, itemCountVerify);
+
+ char *unPackBuf = (char*)malloc(RW_MAX_SIZE);
+ if(unPackBuf==NULL){
+ fprintf(stderr,"allocate memccpy failed at %s %d \n", __FILE__,__LINE__);
+ return __LINE__;
+ }
+
+ FILE *fp_cfg = fopen(cfgfile,"wb+");
+ if(fp_cfg==NULL){
+ fprintf(stderr,"create image.cfg failed ! [%s] \n",strerror(errno));
+ return __LINE__;
+ }
+ fwrite(TAG_NORMALLIST,1,strlen(TAG_NORMALLIST), fp_cfg);
+ fwrite("\r\n", 1, 2, fp_cfg);
+
+ for(nItem = 0; nItem < itemCountTotal; ++nItem)
+ {
+ if(image_get_next_item(hImage,nItem,main_type,sub_type) < 0){
+ ret = -1;
+ break;
+ }
+ if(!strcmp("VERIFY", main_type))
+ {
+ continue;//skip verify item
+ }
+ if(nItem == itemCountNormal)//[List_normal]ends, [List_verify] starts
+ {
+ fwrite("\r\n", 1, 2, fp_cfg);
+ fwrite(TAG_VERIFYLIST,1,strlen(TAG_VERIFYLIST), fp_cfg);
+ fwrite("\r\n", 1, 2, fp_cfg);
+ }
+
+ memset(outfile,0,64);
+ if(outpath){
+ strcpy(outfile,outpath);
+ strcat(outfile,"/");
+ }
+
+ strcat(outfile,sub_type);
+ strcat(outfile,".");
+ strcat(outfile,main_type);
+ debugP("out file: %s \n",outfile);//sub_type.main_type
+
+ HIMAGEITEM hItem = image_open_item(hImage,main_type,sub_type);
+ if(hItem == NULL){
+ fprintf(stderr,"open item[%s, %s] failed!\n", main_type, sub_type);
+ ret = -1;
+ break;
+ }
+
+ int backUpItemId = 0;
+ int itemIsBacked = is_item_backup_for_other_item(hItem, &backUpItemId);
+ if(itemIsBacked < 0){
+ errorP("Fail to in test is_item_backup_for_other_item\n");
+ ret = __LINE__; break;
+ }
+ if(itemIsBacked)//item is back item
+ {
+ char* CfgLine = (char*)unPackBuf;
+ char srcBackItemMainType[32];
+ char srcBackItemSubType[32];
+
+ if(image_get_next_item(hImage, backUpItemId, srcBackItemMainType, srcBackItemSubType)){
+ errorP("Fail to get the backui item head\n");
+ ret = __LINE__; break;
+ }
+ sprintf(CfgLine, IMG_CFG_LINE, srcBackItemSubType, srcBackItemMainType, main_type, sub_type);
+ fwrite(CfgLine,1,strlen(CfgLine), fp_cfg);
+ continue;
+ }
+
+ FILE *fp_out = fopen(outfile,"wb+");
+ if(fp_out == NULL){
+ fprintf(stderr,"failed to create out file : %s \n",outfile);
+ ret = -1;
+ break;
+ }
+
+ while((write_bytes = image_read_item_data(hImage, hItem, unPackBuf, RW_MAX_SIZE))>0)
+ {
+ if(fwrite(unPackBuf,1,write_bytes,fp_out)!=write_bytes){
+ fprintf(stderr,"write to image file fail! [%s] \n",strerror(errno));
+ ret = -1;
+ break;
+ }
+ }
+ fclose(fp_out);
+ image_close_item(hItem);
+
+ char* CfgLine = (char*)unPackBuf;
+ sprintf(CfgLine, IMG_CFG_LINE, sub_type, main_type, main_type, sub_type);
+ fwrite(CfgLine,1,strlen(CfgLine), fp_cfg);
+ }
+ free(unPackBuf);
+ fclose(fp_cfg); fp_cfg = NULL;
+
+ #ifdef BUILD_DLL
+ if(ImageDecoder->AmlFirmwareImg){
+ free(ImageDecoder->AmlFirmwareImg);
+ ImageDecoder->AmlFirmwareImg = NULL;
+ }
+ #endif
+ return ret;
+}
+
+#ifdef BUILD_DLL
+EXPORT
+#endif
+ImageDecoderIf_t* AmlImage_Init(){
+
+ ImageDecoder = (ImageDecoderIf_t*)malloc(sizeof(ImageDecoderIf_t));
+ memset(ImageDecoder,0,sizeof(ImageDecoderIf_t));
+ ImageDecoder->AmlFirmwareImg = (AmlFirmwareImg_t*)malloc(sizeof(AmlFirmwareImg_t));
+ if(ImageDecoder->AmlFirmwareImg == NULL){
+ fprintf(stderr,"not enough memory\n");
+ return NULL;
+ }
+ memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
+
+ ImageDecoder->img_open = image_open;
+ ImageDecoder->img_check = image_check;
+ ImageDecoder->img_close = image_close;
+ ImageDecoder->open_item = image_open_item;
+ ImageDecoder->close_item = image_close_item;
+ ImageDecoder->read_item = image_read_item_data;
+ ImageDecoder->item_seek = image_seek_item;
+ ImageDecoder->item_size = image_get_item_size;
+ ImageDecoder->item_type = image_get_item_type;
+ ImageDecoder->item_count = image_get_item_count;
+ ImageDecoder->get_next_item = image_get_next_item;
+ return ImageDecoder;
+}
+
+#ifdef BUILD_DLL
+EXPORT
+#endif
+void AmlImage_Final(ImageDecoderIf_t* pDecoder){
+
+
+ if(pDecoder){
+ if(pDecoder->AmlFirmwareImg){
+ free(pDecoder->AmlFirmwareImg);
+ pDecoder->AmlFirmwareImg = NULL;
+ }
+ free(pDecoder);
+ };
+}
+
+
+#ifndef BUILD_DLL
+
+static const char * const usage = "%s usage:\n\
+\n\
+ # pack files in directory to the archive\n\
+ %s -r <config file> <src dir> <target file> \n\
+ # unpack files in directory to the archive\n\
+ %s -d <archive> [out dir] \n\
+ # check the image \n\
+ %s -c <archive> \n";
+
+int main(int argc, char * const* argv)
+{
+ int ret = 0;
+ int c = 0;
+ const char* optstring = "d:r:c:";
+
+
+ if(argc < 3||argc > 5) {
+ printf("invalid arguments argc==%d\n", argc);
+ fprintf(stderr,usage,argv[0],argv[0],argv[0],argv[0]);
+ exit(-1);
+ }
+
+ ImageDecoderIf_t* pDecoder = AmlImage_Init();
+
+ //for (int i = 1; i < argc; ++i)
+ {
+ const char* option = argv[1];
+ char* const*optarg = argv + 2;
+
+ if(!strcmp("-d", option))//unpack: argv[0] -d <archive> [out dir]
+ {
+ const char* amlImg = optarg[0];
+ const char* unPackDir = optarg[1];
+ if(access(amlImg,F_OK|R_OK) < 0){
+ printf("Err:%s is not found! \n",amlImg);
+ return __LINE__;
+ }
+ if(argc == 4)
+ ret = image_unpack(amlImg,unPackDir);
+ else
+ ret = image_unpack(amlImg,NULL);
+ }
+ else if(!strcmp("-r", option))//pack: argv[0] -r cfgFile workDir targetFile
+ {
+ if(argc != 5){
+ printf("invalid arguments argc==%d\n", argc);
+ fprintf(stderr,usage,argv[0],argv[0],argv[0],argv[0]);
+ exit(-1);
+ }
+ const char* cfgFile = optarg[0];
+ const char* workdir = optarg[1];
+ const char* targetFile = optarg[2];
+ if(access(cfgFile,F_OK|R_OK) < 0){
+ fprintf(stderr,"Err:%s is not found! \n", cfgFile);
+ }
+ printf("image_pack cfg: %s\n", cfgFile);
+
+ ret = image_pack(cfgFile, workdir, targetFile);
+ }
+ else if(!strcmp("-c", option))//check: argv[0] amlImage
+ {
+ const char* amlImg = optarg[0];
+ if(access(amlImg,F_OK|R_OK) < 0){
+ fprintf(stderr,"Err:%s is not found!\n", amlImg);
+ }
+ FILE *fp = fopen(amlImg,"rb");
+ if(image_check((HIMAGE) fp) < 0){
+ fprintf(stderr,"the image check fail!!\n");
+ }else{
+ printf("the image check ok!\n");
+ }
+ fclose(fp);
+
+ }
+ else if(!strcmp("-?", option))
+ {
+ fprintf(stderr,usage,argv[0],argv[0],argv[0],argv[0]);
+ ret = -1;
+ }
+ else{
+ fprintf(stderr,usage,argv[0],argv[0],argv[0],argv[0]);
+ }
+ }
+
+ AmlImage_Final(pDecoder);
+ return ret;
+}
+#endif// #ifndef BUILD_DLL
--- /dev/null
+/*
+ * \file amlImage_if.h
+ * \brief Amlogic firmware image interface
+ *
+ * \version 1.0.0
+ * \date 2013/5/21
+ * \author Sam.Wu <yihui.wu@Amlogic.com>
+ *
+ * Copyright (c) 2013 Amlogic Inc. All Rights Reserved.
+ *
+ */
+#ifndef __AMLIMAGE_IF_H__
+#define __AMLIMAGE_IF_H__
+
+#include <sys/types.h>
+
+#define AML_FIRMWARE_HEAD_SIZE 4096
+#define IMAGE_MAGIC 0x27b51956 /* Image Magic Number */
+#define VERSION 0x0001
+#define AML_IMG_ITEM_INFO_SZ (128)//Don't never change to keep compatibility
+#define AML_IMG_HEAD_INFO_SZ (64)//Don't never change to keep compatibility
+
+typedef unsigned long long __u64;
+typedef long long __s64;
+typedef unsigned int __u32;
+typedef int __s32;
+typedef unsigned short __u16;
+typedef short __s16;
+
+#pragma pack(push,4)
+typedef struct _AmlFirmwareItem_s
+{
+ __u32 itemId;
+ __u32 fileType; //image file type, sparse and normal
+ __u64 curoffsetInItem; //current offset in the item
+ __u64 offsetInImage; //item offset in the image
+ __u64 itemSz; //item size in the image
+ char itemMainType[32]; //item main type and sub type used to index the item
+ char itemSubType[32]; //item main type and sub type used to index the item
+ __u32 verify;
+ __u16 isBackUpItem; //this item source file is the same as backItemId
+ __u16 backUpItemId; //if 'isBackUpItem', then this is the item id
+ char reserve[24];
+}ItemInfo;
+#pragma pack(pop)
+
+
+#pragma pack(push,4)
+typedef struct _AmlFirmwareImg_s
+{
+ __u32 crc; //check sum of the image
+ __u32 version; //firmware version
+ __u32 magic; //magic No. to say it is Amlogic firmware image
+ __u64 imageSz; //total size of this image file
+ __u32 itemAlginSize; //align size for each item
+ __u32 itemNum; //item number in the image, each item a file
+ char reserve[36];
+}AmlFirmwareImg_t;
+#pragma pack(pop)
+
+
+
+typedef void* HIMAGE;
+typedef void* HIMAGEITEM;
+
+#define IMAGE_ITEM_TYPE_NORMAL 0
+#define IMAGE_ITEM_TYPE_SPARSE 0XFE
+
+
+//open a Amlogic firmware image
+//return value is a handle
+typedef HIMAGE (*func_img_open)(const char* );
+
+//check the image's crc32
+//return 0 when check ok,otherwise return -1
+typedef int (*func_img_check)(HIMAGE );
+
+//close a Amlogic firmware image
+typedef int (*func_img_close)(HIMAGE );
+
+//open a item in the image
+//@hImage: image handle;
+//@mainType, @subType: main type and subtype to index the item, such as ["IMAGE", "SYSTEM"]
+typedef HIMAGEITEM (*func_open_item)(HIMAGE , const char* , const char* );
+
+//close a item
+typedef int (*func_close_item)(HIMAGEITEM );
+
+typedef __u64 (*func_get_item_size)(HIMAGEITEM );
+
+
+//get image item type, current used type is normal or sparse
+typedef int (*func_get_item_type)(HIMAGEITEM );
+
+//get item count of specify main type
+typedef int (*func_get_item_count)(HIMAGE ,const char* );
+
+//read item data, like standard fread
+typedef __u32 (*func_read_item_data)(HIMAGE , HIMAGEITEM , void* , const __u32 );
+
+//relocate the read pointer to read the item data, like standard fseek
+typedef int (*func_item_seek)(HIMAGE , HIMAGEITEM , __s64 , __u32 );
+
+//get item main type and sub type
+typedef int (*func_get_next_item)(HIMAGE ,unsigned int , char* , char* );
+
+
+typedef struct filelist_t{
+ char name[128];
+ char main_type[32];
+ char sub_type[32];
+ int verify;
+ struct filelist_t *next;
+}FileList;
+
+
+typedef struct image_cfg_t{
+ FileList *file_list;
+}ImageCfg;
+
+
+#pragma pack(push, 4)
+typedef struct _ImageDecoder_if
+{
+ int gItemCount;
+ ImageCfg gImageCfg;
+ AmlFirmwareImg_t* AmlFirmwareImg ;
+ func_img_open img_open; //open image
+ func_img_check img_check; //check image
+ func_img_close img_close; //close image
+ func_open_item open_item; //open a item in the image, like c library fopen
+ func_close_item close_item; //close a item, like c library fclose
+
+ func_read_item_data read_item; //read item data, like c library fread
+ func_item_seek item_seek; //seek the item read pointer, like c library fseek
+ func_get_item_size item_size; //get item size in byte
+ func_get_item_type item_type; //get item format, sparse, normal...
+ func_get_item_count item_count; //get item count of specify main type
+ func_get_next_item get_next_item; //
+}ImageDecoderIf_t;
+#pragma pack(pop)
+
+#endif//ifndef __AMLIMAGE_IF_H__
+
--- /dev/null
+/*
+ * crc32.c
+ *
+ * Created on: 2013-5-31
+ * Author: binsheng.xu@amlogic.com
+ */
+#include "image_packer_i.h"
+
+#define BUFSIZE 1024*16
+
+static unsigned int crc_table[256];
+
+
+static void init_crc_table(void)
+{
+ unsigned int c;
+ unsigned int i, j;
+
+ for (i = 0; i < 256; i++) {
+ c = (unsigned int)i;
+ for (j = 0; j < 8; j++) {
+ if (c & 1)
+ c = 0xedb88320L ^ (c >> 1);
+ else
+ c = c >> 1;
+ }
+ crc_table[i] = c;
+ }
+}
+
+/*¼ÆËãbufferµÄcrcУÑéÂë*/
+static unsigned int crc32(unsigned int crc,unsigned char *buffer, unsigned int size)
+{
+ unsigned int i;
+ for (i = 0; i < size; i++) {
+ crc = crc_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8);
+ }
+ return crc ;
+}
+
+/*
+**¼ÆËã´óÎļþµÄCRCУÑéÂë:crc32º¯Êý,ÊǶÔÒ»¸öbuffer½øÐд¦Àí,
+**µ«Èç¹ûÒ»¸öÎļþÏà¶Ô½Ï´ó,ÏÔÈ»²»ÄÜÖ±½Ó¶ÁÈ¡µ½ÄÚ´æµ±ÖÐ
+**ËùÒÔÖ»Äܽ«Îļþ·Ö¶Î¶ÁÈ¡³öÀ´½øÐÐcrcУÑé,
+**È»ºóÑ»·½«ÉÏÒ»´ÎµÄcrcУÑéÂëÔÙ´«µÝ¸øеÄbufferУÑ麯Êý,
+**µ½×îºó£¬Éú³ÉµÄcrcУÑéÂë¾ÍÊǸÃÎļþµÄcrcУÑéÂë
+*/
+int calc_img_crc(FILE* fp, off_t offset)
+{
+
+ int nread;
+ unsigned char buf[BUFSIZE];
+ /*µÚÒ»´Î´«ÈëµÄÖµÐèÒª¹Ì¶¨,Èç¹û·¢ËͶËʹÓøÃÖµ¼ÆËãcrcУÑéÂë,
+ **ÄÇô½ÓÊÕ¶ËҲͬÑùÐèҪʹÓøÃÖµ½øÐмÆËã*/
+ unsigned int crc = 0xffffffff;
+
+ if (fp == NULL) {
+ fprintf(stderr,"bad param!!\n");
+ return -1;
+ }
+
+ init_crc_table();
+ fseeko(fp,offset,SEEK_SET);
+ while ((nread = fread(buf,1, BUFSIZE,fp)) > 0) {
+ crc = crc32(crc, buf, nread);
+ }
+
+ if (nread < 0) {
+ fprintf(stderr,"%d:read %s.\n", __LINE__, strerror(errno));
+ return -1;
+ }
+
+ return crc;
+}
+
+
--- /dev/null
+/*
+ * crc32.h
+ *
+ * Created on: 2013-5-31
+ * Author: binsheng.xu@amlogic.com
+ */
+
+#ifndef CRC32_H_
+#define CRC32_H_
+
+int calc_img_crc(FILE* fd, off_t offset);
+
+#endif /* CRC32_H_ */
--- /dev/null
+/*
+ * dll.h
+ *
+ * Created on: 2013-6-3
+ * Author: binsheng.xu@amlogic.com
+ */
+
+#ifndef DLL_H_
+#define DLL_H_
+
+#ifdef BUILD_DLL
+
+/* DLL export */
+
+#define EXPORT __declspec(dllexport)
+
+#else
+
+/* EXE import */
+
+#define EXPORT __declspec(dllimport)
+
+#endif
+
+#ifdef __cplusplus // If used by C++ code,
+//extern "C" { // we need to export the C interface
+#endif
+
+EXPORT ImageDecoderIf_t* AmlImage_Init();
+EXPORT void AmlImage_Final(ImageDecoderIf_t* pDecoder);
+EXPORT int image_pack(const char* cfg_file,const char *src_dir ,const char* target_file);
+EXPORT int image_unpack(const char* imagefile,const char *outpath);
+
+
+#ifdef __cplusplus
+//}
+#endif
+
+#endif /* DLL_H_ */
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Exe_Debug|Win32">
+ <Configuration>Exe_Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Exe_Release|Win32">
+ <Configuration>Exe_Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{FDC92709-02A2-496F-B62A-23FD0DFBC348}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>image_packer</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions);BUILD_DLL</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions);</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions);BUILD_DLL</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="amlImage.cpp" />
+ <ClCompile Include="crc32.cpp" />
+ <ClCompile Include="sha1.c" />
+ <ClCompile Include="sparse_format.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="amlImage_if.h" />
+ <ClInclude Include="crc32.h" />
+ <ClInclude Include="dll.h" />
+ <ClInclude Include="image_packer_i.h" />
+ <ClInclude Include="sha1.h" />
+ <ClInclude Include="sparse_format.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Android.mk" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="sha1.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="amlImage.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="crc32.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="sparse_format.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="amlImage_if.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="crc32.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="sha1.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="sparse_format.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="dll.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="image_packer_i.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Android.mk" />
+ </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Exe_Debug|Win32'">
+ <LocalDebuggerCommandArguments>-r out/image.cfg out/ out.img</LocalDebuggerCommandArguments>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+/********************************************************************
+ created: 11-10-2013 15:43
+ file : image_packer_i.h
+ author: Sam Wu
+
+ purpose:
+*********************************************************************/
+#ifndef __IMAGE_PACKER_I_H__
+#define __IMAGE_PACKER_I_H__
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#include <dirent.h>
+#ifdef BUILD_WITH_MINGW
+#define stat64 _stati64
+#define fseeko fseeko64
+#define ftello ftello64
+#endif
+#else//win32
+#include <io.h>
+#define stat64 _stati64
+#define fseeko _fseeki64
+#define ftello _ftelli64
+#define F_OK 0x00
+#define W_OK 0x02
+#define R_OK 0x04
+#endif// #ifndef WIN32
+
+#include "amlImage_if.h"
+#include "crc32.h"
+#include "sparse_format.h"
+
+#ifdef BUILD_DLL
+#include "dll.h"
+#endif
+
+#endif // __IMAGE_PACKER_I$_H__
--- /dev/null
+/*
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ * based on:
+ * FIPS-180-1 compliant SHA-1 implementation
+ *
+ * Copyright (C) 2003-2006 Christophe Devine
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+/*
+ * The SHA-1 standard was published by NIST in 1993.
+ *
+ * http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include "image_packer_i.h"
+#include "sha1.h"
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i) { \
+ (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
+ | ( (unsigned long) (b)[(i) + 1] << 16 ) \
+ | ( (unsigned long) (b)[(i) + 2] << 8 ) \
+ | ( (unsigned long) (b)[(i) + 3] ); \
+}
+#endif
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i) { \
+ (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
+ (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
+ (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
+ (b)[(i) + 3] = (unsigned char) ( (n) ); \
+}
+#endif
+
+/*
+ * SHA-1 context setup
+ */
+void sha1_starts (sha1_context * ctx)
+{
+ ctx->total[0] = 0;
+ ctx->total[1] = 0;
+
+ ctx->state[0] = 0x67452301;
+ ctx->state[1] = 0xEFCDAB89;
+ ctx->state[2] = 0x98BADCFE;
+ ctx->state[3] = 0x10325476;
+ ctx->state[4] = 0xC3D2E1F0;
+}
+
+static void sha1_process (sha1_context * ctx, unsigned char data[64])
+{
+ unsigned long temp, W[16], A, B, C, D, E;
+
+ GET_UINT32_BE (W[0], data, 0);
+ GET_UINT32_BE (W[1], data, 4);
+ GET_UINT32_BE (W[2], data, 8);
+ GET_UINT32_BE (W[3], data, 12);
+ GET_UINT32_BE (W[4], data, 16);
+ GET_UINT32_BE (W[5], data, 20);
+ GET_UINT32_BE (W[6], data, 24);
+ GET_UINT32_BE (W[7], data, 28);
+ GET_UINT32_BE (W[8], data, 32);
+ GET_UINT32_BE (W[9], data, 36);
+ GET_UINT32_BE (W[10], data, 40);
+ GET_UINT32_BE (W[11], data, 44);
+ GET_UINT32_BE (W[12], data, 48);
+ GET_UINT32_BE (W[13], data, 52);
+ GET_UINT32_BE (W[14], data, 56);
+ GET_UINT32_BE (W[15], data, 60);
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define R(t) ( \
+ temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
+ W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
+ ( W[t & 0x0F] = S(temp,1) ) \
+)
+
+#define P(a,b,c,d,e,x) { \
+ e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
+}
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+ P (A, B, C, D, E, W[0]);
+ P (E, A, B, C, D, W[1]);
+ P (D, E, A, B, C, W[2]);
+ P (C, D, E, A, B, W[3]);
+ P (B, C, D, E, A, W[4]);
+ P (A, B, C, D, E, W[5]);
+ P (E, A, B, C, D, W[6]);
+ P (D, E, A, B, C, W[7]);
+ P (C, D, E, A, B, W[8]);
+ P (B, C, D, E, A, W[9]);
+ P (A, B, C, D, E, W[10]);
+ P (E, A, B, C, D, W[11]);
+ P (D, E, A, B, C, W[12]);
+ P (C, D, E, A, B, W[13]);
+ P (B, C, D, E, A, W[14]);
+ P (A, B, C, D, E, W[15]);
+ P (E, A, B, C, D, R (16));
+ P (D, E, A, B, C, R (17));
+ P (C, D, E, A, B, R (18));
+ P (B, C, D, E, A, R (19));
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+ P (A, B, C, D, E, R (20));
+ P (E, A, B, C, D, R (21));
+ P (D, E, A, B, C, R (22));
+ P (C, D, E, A, B, R (23));
+ P (B, C, D, E, A, R (24));
+ P (A, B, C, D, E, R (25));
+ P (E, A, B, C, D, R (26));
+ P (D, E, A, B, C, R (27));
+ P (C, D, E, A, B, R (28));
+ P (B, C, D, E, A, R (29));
+ P (A, B, C, D, E, R (30));
+ P (E, A, B, C, D, R (31));
+ P (D, E, A, B, C, R (32));
+ P (C, D, E, A, B, R (33));
+ P (B, C, D, E, A, R (34));
+ P (A, B, C, D, E, R (35));
+ P (E, A, B, C, D, R (36));
+ P (D, E, A, B, C, R (37));
+ P (C, D, E, A, B, R (38));
+ P (B, C, D, E, A, R (39));
+
+#undef K
+#undef F
+
+#define F(x,y,z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+ P (A, B, C, D, E, R (40));
+ P (E, A, B, C, D, R (41));
+ P (D, E, A, B, C, R (42));
+ P (C, D, E, A, B, R (43));
+ P (B, C, D, E, A, R (44));
+ P (A, B, C, D, E, R (45));
+ P (E, A, B, C, D, R (46));
+ P (D, E, A, B, C, R (47));
+ P (C, D, E, A, B, R (48));
+ P (B, C, D, E, A, R (49));
+ P (A, B, C, D, E, R (50));
+ P (E, A, B, C, D, R (51));
+ P (D, E, A, B, C, R (52));
+ P (C, D, E, A, B, R (53));
+ P (B, C, D, E, A, R (54));
+ P (A, B, C, D, E, R (55));
+ P (E, A, B, C, D, R (56));
+ P (D, E, A, B, C, R (57));
+ P (C, D, E, A, B, R (58));
+ P (B, C, D, E, A, R (59));
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+ P (A, B, C, D, E, R (60));
+ P (E, A, B, C, D, R (61));
+ P (D, E, A, B, C, R (62));
+ P (C, D, E, A, B, R (63));
+ P (B, C, D, E, A, R (64));
+ P (A, B, C, D, E, R (65));
+ P (E, A, B, C, D, R (66));
+ P (D, E, A, B, C, R (67));
+ P (C, D, E, A, B, R (68));
+ P (B, C, D, E, A, R (69));
+ P (A, B, C, D, E, R (70));
+ P (E, A, B, C, D, R (71));
+ P (D, E, A, B, C, R (72));
+ P (C, D, E, A, B, R (73));
+ P (B, C, D, E, A, R (74));
+ P (A, B, C, D, E, R (75));
+ P (E, A, B, C, D, R (76));
+ P (D, E, A, B, C, R (77));
+ P (C, D, E, A, B, R (78));
+ P (B, C, D, E, A, R (79));
+
+#undef K
+#undef F
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+void sha1_update (sha1_context * ctx, unsigned char *input, int ilen)
+{
+ int fill;
+ unsigned long left;
+
+ if (ilen <= 0)
+ return;
+
+ left = ctx->total[0] & 0x3F;
+ fill = 64 - left;
+
+ ctx->total[0] += ilen;
+ ctx->total[0] &= 0xFFFFFFFF;
+
+ if (ctx->total[0] < (unsigned long) ilen)
+ ctx->total[1]++;
+
+ if (left && ilen >= fill) {
+ memcpy((void *) (ctx->buffer + left), (void *) input, fill);
+ sha1_process (ctx, ctx->buffer);
+ input += fill;
+ ilen -= fill;
+ left = 0;
+ }
+
+ while (ilen >= 64) {
+ sha1_process (ctx, input);
+ input += 64;
+ ilen -= 64;
+ }
+
+ if (ilen > 0) {
+ memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
+ }
+}
+
+static const unsigned char sha1_padding[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * SHA-1 final digest
+ */
+void sha1_finish (sha1_context * ctx, unsigned char output[20])
+{
+ unsigned long last, padn;
+ unsigned long high, low;
+ unsigned char msglen[8];
+
+ high = (ctx->total[0] >> 29)
+ | (ctx->total[1] << 3);
+ low = (ctx->total[0] << 3);
+
+ PUT_UINT32_BE (high, msglen, 0);
+ PUT_UINT32_BE (low, msglen, 4);
+
+ last = ctx->total[0] & 0x3F;
+ padn = (last < 56) ? (56 - last) : (120 - last);
+
+ sha1_update (ctx, (unsigned char *) sha1_padding, padn);
+ sha1_update (ctx, msglen, 8);
+
+ PUT_UINT32_BE (ctx->state[0], output, 0);
+ PUT_UINT32_BE (ctx->state[1], output, 4);
+ PUT_UINT32_BE (ctx->state[2], output, 8);
+ PUT_UINT32_BE (ctx->state[3], output, 12);
+ PUT_UINT32_BE (ctx->state[4], output, 16);
+}
+
+/*
+ * Output = SHA-1( input buffer )
+ */
+void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
+{
+ sha1_context ctx;
+
+ sha1_starts (&ctx);
+ sha1_update (&ctx, input, ilen);
+ sha1_finish (&ctx, output);
+}
+
+/*
+ * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
+ * bytes of input processed.
+ */
+void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
+ unsigned int chunk_sz)
+{
+ sha1_context ctx;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+ unsigned char *end, *curr;
+ int chunk;
+#endif
+
+ sha1_starts (&ctx);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+ curr = input;
+ end = input + ilen;
+ while (curr < end) {
+ chunk = end - curr;
+ if (chunk > chunk_sz)
+ chunk = chunk_sz;
+ sha1_update (&ctx, curr, chunk);
+ curr += chunk;
+ WATCHDOG_RESET ();
+ }
+#else
+ sha1_update (&ctx, input, ilen);
+#endif
+
+ sha1_finish (&ctx, output);
+}
+
+/*
+ * Output = HMAC-SHA-1( input buffer, hmac key )
+ */
+void sha1_hmac (unsigned char *key, int keylen,
+ unsigned char *input, int ilen, unsigned char output[20])
+{
+ int i;
+ sha1_context ctx;
+ unsigned char k_ipad[64];
+ unsigned char k_opad[64];
+ unsigned char tmpbuf[20];
+
+ memset (k_ipad, 0x36, 64);
+ memset (k_opad, 0x5C, 64);
+
+ for (i = 0; i < keylen; i++) {
+ if (i >= 64)
+ break;
+
+ k_ipad[i] ^= key[i];
+ k_opad[i] ^= key[i];
+ }
+
+ sha1_starts (&ctx);
+ sha1_update (&ctx, k_ipad, 64);
+ sha1_update (&ctx, input, ilen);
+ sha1_finish (&ctx, tmpbuf);
+
+ sha1_starts (&ctx);
+ sha1_update (&ctx, k_opad, 64);
+ sha1_update (&ctx, tmpbuf, 20);
+ sha1_finish (&ctx, output);
+
+ memset (k_ipad, 0, 64);
+ memset (k_opad, 0, 64);
+ memset (tmpbuf, 0, 20);
+ memset (&ctx, 0, sizeof (sha1_context));
+}
+
+//static const char _sha1_src[] = "_sha1_src";
+
+#ifdef SELF_TEST
+/*
+ * FIPS-180-1 test vectors
+ */
+static const char sha1_test_str[3][57] = {
+ {"abc"},
+ {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
+ {""}
+};
+
+static const unsigned char sha1_test_sum[3][20] = {
+ {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
+ 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
+ {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
+ 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
+ {0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
+ 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
+};
+
+/*
+ * Checkup routine
+ */
+int sha1_self_test (void)
+{
+ int i, j;
+ unsigned char buf[1000];
+ unsigned char sha1sum[20];
+ sha1_context ctx;
+
+ for (i = 0; i < 3; i++) {
+ printf (" SHA-1 test #%d: ", i + 1);
+
+ sha1_starts (&ctx);
+
+ if (i < 2)
+ sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
+ strlen (sha1_test_str[i]));
+ else {
+ memset (buf, 'a', 1000);
+ for (j = 0; j < 1000; j++)
+ sha1_update (&ctx, buf, 1000);
+ }
+
+ sha1_finish (&ctx, sha1sum);
+
+ if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
+ printf ("failed\n");
+ return (1);
+ }
+
+ printf ("passed\n");
+ }
+
+ printf ("\n");
+ return (0);
+}
+#else
+int sha1_self_test (void)
+{
+ return (0);
+}
+#endif
+
+#define Sha1Len 40
+
+int gen_sha1sum_verify(const char* srFile, char* verifyData)
+{
+ const int BufSz = 2U<<20;//2M
+ int ret = 0;
+ unsigned char* pBuf = NULL;
+ FILE* pSrcFile = 0;
+ //FILE* pDestFile = 0;
+ //unsigned wrLen = 0;
+ //const char prefix[] = "sha1sum ";
+ //const unsigned prefixLen = sizeof(prefix) - 1;
+ unsigned char genSumVal[Sha1Len/2 + 1] = {0};
+ //char sha1Result[Sha1Len + 1] = {0};
+ off_t SrcFileSz = 0;
+ sha1_context ctx;
+ off_t totalReadSz = 0;
+ off_t thisReadSz = 0;
+ struct stat s;
+ int i = 1;
+
+ if(stat(srFile, &s)){
+ printf("could not stat '%s'\n", srFile);
+ return -1;
+ }
+ SrcFileSz = s.st_size;
+ if(!SrcFileSz){
+ printf("Fail to get file size for file %s, is file path right??\n", srFile);
+ return __LINE__;
+ }
+
+
+ pSrcFile = fopen(srFile, "rb");
+ if(!pSrcFile){
+ printf("Fail to open src file\n");
+ return __LINE__;
+ }
+
+ pBuf = (unsigned char*)malloc(BufSz); //new unsigned char[BufSz];
+ if (!pBuf) {
+ printf("Fail to alloc buf\n");
+ fclose(pSrcFile);
+ return __LINE__;
+ }
+
+ sha1_starts(&ctx);
+
+ for(; totalReadSz < SrcFileSz; totalReadSz += thisReadSz)
+ {
+ unsigned readSz = 0;
+ off_t leftSz = SrcFileSz - totalReadSz;
+
+ thisReadSz = leftSz > BufSz ? BufSz : (unsigned)leftSz;
+
+ readSz = fread(pBuf, 1, thisReadSz, pSrcFile);
+ if(readSz != thisReadSz){
+ printf("Want to read 0x%ul, but 0x%ul \n", thisReadSz, readSz);
+ ret = __LINE__;
+ goto _finish;
+ }
+
+ sha1_update(&ctx, pBuf, thisReadSz);
+ }
+
+ free(pBuf);
+ pBuf = NULL;
+ fclose(pSrcFile);
+ pSrcFile = NULL;
+
+ sha1_finish(&ctx, genSumVal);
+ genSumVal[Sha1Len/2] = 0;
+ //printf("Gen sun raw value is \"%s\"\n", genSumVal);
+
+ sprintf(verifyData, "sha1sum %02x", genSumVal[0]);
+ for(; i < 20; ++i)
+ {
+ sprintf(verifyData, "%s%02x", verifyData, genSumVal[i]);
+ }
+
+ printf("gen sum for file %s is [%s]\n", srFile, verifyData);
+
+_finish:
+ if(pBuf)
+ free(pBuf);
+ if(pSrcFile)
+ fclose(pSrcFile);
+ return ret;
+}
+
+
+
--- /dev/null
+/**
+ * \file sha1.h
+ * based from http://xyssl.org/code/source/sha1/
+ * FIPS-180-1 compliant SHA-1 implementation
+ *
+ * Copyright (C) 2003-2006 Christophe Devine
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+/*
+ * The SHA-1 standard was published by NIST in 1993.
+ *
+ * http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+#ifndef _SHA1_H
+#define _SHA1_H
+
+#define SHA1_SUM_POS -0x20
+#define SHA1_SUM_LEN 20
+
+/**
+ * \brief SHA-1 context structure
+ */
+typedef struct
+{
+ unsigned long total[2]; /*!< number of bytes processed */
+ unsigned long state[5]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+}
+sha1_context;
+
+/**
+ * \brief SHA-1 context setup
+ *
+ * \param ctx SHA-1 context to be initialized
+ */
+void sha1_starts( sha1_context *ctx );
+
+/**
+ * \brief SHA-1 process buffer
+ *
+ * \param ctx SHA-1 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-1 final digest
+ *
+ * \param ctx SHA-1 context
+ * \param output SHA-1 checksum result
+ */
+void sha1_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief Output = SHA-1( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output SHA-1 checksum result
+ */
+void sha1_csum( unsigned char *input, int ilen,
+ unsigned char output[20] );
+
+/**
+ * \brief Output = SHA-1( input buffer ), with watchdog triggering
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output SHA-1 checksum result
+ * \param chunk_sz watchdog triggering period (in bytes of input processed)
+ */
+void sha1_csum_wd (unsigned char *input, int ilen,
+ unsigned char output[20], unsigned int chunk_sz);
+
+/**
+ * \brief Output = SHA-1( file contents )
+ *
+ * \param path input file name
+ * \param output SHA-1 checksum result
+ * \return 0 if successful, or 1 if fopen failed
+ */
+int sha1_file( char *path, unsigned char output[20] );
+
+/**
+ * \brief Output = HMAC-SHA-1( input buffer, hmac key )
+ *
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output HMAC-SHA-1 result
+ */
+void sha1_hmac( unsigned char *key, int keylen,
+ unsigned char *input, int ilen,
+ unsigned char output[20] );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int sha1_self_test( void );
+
+#endif /* sha1.h */
--- /dev/null
+/*
+ * sparse_format.c
+ *
+ * Created on: 2013-6-3
+ * Author: binsheng.xu@amlogic.com
+ */
+
+//ÅжÏÎļþ¸ñʽÊÇ·ñΪsparse
+#include <stdio.h>
+#include "sparse_format.h"
+
+//0 is not sparse packet header, else is sparse packet_header
+int optimus_simg_probe(const char* source, const __u32 length)
+{
+ sparse_header_t *header = (sparse_header_t*) source;
+
+ if(length < sizeof(sparse_header_t)) {
+ fprintf(stderr,"length %d < sparse_header_t len %d\n", length, FILE_HEAD_SIZE);
+ return 0;
+ }
+ if (header->magic != SPARSE_HEADER_MAGIC) {
+ //fprintf(stderr,"sparse bad magic, expect 0x%x but 0x%x\n", SPARSE_HEADER_MAGIC, header->magic);
+ return 0;
+ }
+
+ if(!(SPARSE_HEADER_MAJOR_VER == header->major_version
+ && FILE_HEAD_SIZE == header->file_hdr_sz
+ && CHUNK_HEAD_SIZE == header->chunk_hdr_sz))
+ {
+ fprintf(stderr,"want 0x [%x, %x, %x], but [%x, %x, %x]\n",
+ SPARSE_HEADER_MAJOR_VER, FILE_HEAD_SIZE, CHUNK_HEAD_SIZE,
+ header->major_version, header->file_hdr_sz, header->chunk_hdr_sz);
+ return 0;
+ }
+ return 1;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "amlImage_if.h"
+
+typedef struct sparse_header {
+ __u32 magic; /* 0xed26ff3a */
+ __u16 major_version; /* (0x1) - reject images with higher major versions */
+ __u16 minor_version; /* (0x0) - allow images with higer minor versions */
+ __u16 file_hdr_sz; /* 28 bytes for first revision of the file format */
+ __u16 chunk_hdr_sz; /* 12 bytes for first revision of the file format */
+ __u32 blk_sz; /* block size in bytes, must be a multiple of 4 (4096) */
+ __u32 total_blks; /* total blocks in the non-sparse output image */
+ __u32 total_chunks; /* total chunks in the sparse input image */
+ __u32 image_checksum; /* CRC32 checksum of the original data, counting "don't care" */
+ /* as 0. Standard 802.3 polynomial, use a Public Domain */
+ /* table implementation */
+} sparse_header_t;
+
+#define SPARSE_HEADER_MAGIC 0xed26ff3a
+
+#define CHUNK_TYPE_RAW 0xCAC1
+#define CHUNK_TYPE_FILL 0xCAC2
+#define CHUNK_TYPE_DONT_CARE 0xCAC3
+#define CHUNK_TYPE_CRC32 0xCAC4
+
+typedef struct chunk_header {
+ __u16 chunk_type; /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */
+ __u16 reserved1;
+ __u32 chunk_sz; /* in blocks in output image */
+ __u32 total_sz; /* in bytes of chunk input file including chunk header and data */
+} chunk_header_t;
+
+/* Following a Raw or Fill or CRC32 chunk is data.
+ * For a Raw chunk, it's the data in chunk_sz * blk_sz.
+ * For a Fill chunk, it's 4 bytes of the fill data.
+ * For a CRC32 chunk, it's 4 bytes of CRC32
+ */
+
+#define SPARSE_HEADER_MAJOR_VER 1
+#define CHUNK_HEAD_SIZE sizeof(chunk_header_t)
+#define FILE_HEAD_SIZE sizeof(sparse_header_t)
+
+int optimus_simg_probe(const char* source, const __u32 length);
+
+
+