From 447475e056f81e1937811f3ac41ccba332678af2 Mon Sep 17 00:00:00 2001 From: Jan Altensen Date: Mon, 21 Jun 2021 23:44:47 +0200 Subject: [PATCH] import aml_image_packer * from https://github.com/khadas/buildroot_buildroot/tree/buildroot/package/aml_image_packer/src Change-Id: I708523bffc5e3b1152fcf747f48f62c108034efe --- Android.mk | 72 +++ Makefile | 7 + amlImage.cpp | 1066 ++++++++++++++++++++++++++++++++++ amlImage_if.h | 144 +++++ crc32.cpp | 76 +++ crc32.h | 13 + dll.h | 39 ++ image_packer.vcxproj | 157 +++++ image_packer.vcxproj.filters | 54 ++ image_packer.vcxproj.user | 7 + image_packer_i.h | 45 ++ sha1.c | 537 +++++++++++++++++ sha1.h | 118 ++++ sparse_format.cpp | 37 ++ sparse_format.h | 60 ++ 15 files changed, 2432 insertions(+) create mode 100644 Android.mk create mode 100644 Makefile create mode 100644 amlImage.cpp create mode 100644 amlImage_if.h create mode 100644 crc32.cpp create mode 100644 crc32.h create mode 100644 dll.h create mode 100644 image_packer.vcxproj create mode 100644 image_packer.vcxproj.filters create mode 100644 image_packer.vcxproj.user create mode 100644 image_packer_i.h create mode 100644 sha1.c create mode 100644 sha1.h create mode 100644 sparse_format.cpp create mode 100644 sparse_format.h diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..b576b47 --- /dev/null +++ b/Android.mk @@ -0,0 +1,72 @@ +# +# 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 + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eb3ac78 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ + +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 + diff --git a/amlImage.cpp b/amlImage.cpp new file mode 100644 index 0000000..7a1b13b --- /dev/null +++ b/amlImage.cpp @@ -0,0 +1,1066 @@ +/* + * \file amlImage.c + * \brief Amlogic firmware image interface + * + * \version 1.0.0 + * \date 2013/5/21 + * \author Vinson.Xu + * + * 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(;iAmlFirmwareImg->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 \n\ + # unpack files in directory to the archive\n\ + %s -d [out dir] \n\ + # check the image \n\ + %s -c \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 [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 diff --git a/amlImage_if.h b/amlImage_if.h new file mode 100644 index 0000000..504cf31 --- /dev/null +++ b/amlImage_if.h @@ -0,0 +1,144 @@ +/* + * \file amlImage_if.h + * \brief Amlogic firmware image interface + * + * \version 1.0.0 + * \date 2013/5/21 + * \author Sam.Wu + * + * Copyright (c) 2013 Amlogic Inc. All Rights Reserved. + * + */ +#ifndef __AMLIMAGE_IF_H__ +#define __AMLIMAGE_IF_H__ + +#include + +#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__ + diff --git a/crc32.cpp b/crc32.cpp new file mode 100644 index 0000000..6827881 --- /dev/null +++ b/crc32.cpp @@ -0,0 +1,76 @@ +/* + * 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; +} + + diff --git a/crc32.h b/crc32.h new file mode 100644 index 0000000..a609bc8 --- /dev/null +++ b/crc32.h @@ -0,0 +1,13 @@ +/* + * 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_ */ diff --git a/dll.h b/dll.h new file mode 100644 index 0000000..9a24ae7 --- /dev/null +++ b/dll.h @@ -0,0 +1,39 @@ +/* + * 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_ */ diff --git a/image_packer.vcxproj b/image_packer.vcxproj new file mode 100644 index 0000000..ddd6c1b --- /dev/null +++ b/image_packer.vcxproj @@ -0,0 +1,157 @@ + + + + + Debug + Win32 + + + Exe_Debug + Win32 + + + Exe_Release + Win32 + + + Release + Win32 + + + + {FDC92709-02A2-496F-B62A-23FD0DFBC348} + Win32Proj + image_packer + + + + DynamicLibrary + true + MultiByte + + + Application + true + MultiByte + + + DynamicLibrary + false + true + Unicode + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions);BUILD_DLL + + + Console + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions); + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions);BUILD_DLL + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;IMAGE_PACKER_EXPORTS;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/image_packer.vcxproj.filters b/image_packer.vcxproj.filters new file mode 100644 index 0000000..5a6bac6 --- /dev/null +++ b/image_packer.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + \ No newline at end of file diff --git a/image_packer.vcxproj.user b/image_packer.vcxproj.user new file mode 100644 index 0000000..a91c912 --- /dev/null +++ b/image_packer.vcxproj.user @@ -0,0 +1,7 @@ + + + + -r out/image.cfg out/ out.img + WindowsLocalDebugger + + \ No newline at end of file diff --git a/image_packer_i.h b/image_packer_i.h new file mode 100644 index 0000000..00388c5 --- /dev/null +++ b/image_packer_i.h @@ -0,0 +1,45 @@ +/******************************************************************** + 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 +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#ifdef BUILD_WITH_MINGW +#define stat64 _stati64 +#define fseeko fseeko64 +#define ftello ftello64 +#endif +#else//win32 +#include +#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__ diff --git a/sha1.c b/sha1.c new file mode 100644 index 0000000..c148be2 --- /dev/null +++ b/sha1.c @@ -0,0 +1,537 @@ +/* + * 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; +} + + + diff --git a/sha1.h b/sha1.h new file mode 100644 index 0000000..08727f1 --- /dev/null +++ b/sha1.h @@ -0,0 +1,118 @@ +/** + * \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 */ diff --git a/sparse_format.cpp b/sparse_format.cpp new file mode 100644 index 0000000..b2fa098 --- /dev/null +++ b/sparse_format.cpp @@ -0,0 +1,37 @@ +/* + * sparse_format.c + * + * Created on: 2013-6-3 + * Author: binsheng.xu@amlogic.com + */ + +//ÅжÏÎļþ¸ñʽÊÇ·ñΪsparse +#include +#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; +} + diff --git a/sparse_format.h b/sparse_format.h new file mode 100644 index 0000000..20137cd --- /dev/null +++ b/sparse_format.h @@ -0,0 +1,60 @@ +/* + * 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); + + + -- 2.20.1