#include #include #include #include #include #include #include #include "sha256.h" #include "iot_img_hdr.h" char default_hash_iv[]={0x12,0x34,0x56,0x78,0x87,0x65,0x43,0x21,0x5A,0x5A,0x5A,0x5A,0x00,0x7E,0xC3,0x00}; #define NEW_LINE "\r\n" #define OK 0 #define ERROR (-1) #define FUNC_CONSTRUCT "-c" #define FUNC_SHOWHEADER "-s" #define PK_NAME_KEY_WORD "iot_flash" #define PK_SINGLE_FILE_SIZE 0x1000000 /* sigle file size keeped under 16MB */ #define MAX_IMAGE_NUM 20 #define imgHeaderSize HEADER_TOLTAL_SIZE char * global_buffer = NULL; unsigned int CRC32_Update(unsigned int crc, char *buff, int len); typedef unsigned short UINT16; typedef unsigned int UINT32; typedef struct { char *pName; int ver; int devType; int imgType; }ftype; enum{ RET_OK, RET_ENV_FAILED, RET_BAD_PARA, RET_IMAGE_WRONG, }; #define GET_BYTE1(i) ((i)&0xFF) #define GET_BYTE2(i) (((i)>>8)&0xFF) #define GET_BYTE3(i) (((i)>>16)&0xFF) #define GET_BYTE4(i) (((i)>>24)&0xFF) #define PATH_LENGTH 128 #define KEYWRD_LENGTH (PATH_LENGTH - 12) /* "20170901.bin" -> 12 bytes */ typedef struct ah_image_config_ { int image_type; int version; int offset; int length; // int pad_enable; // int pad; char path[PATH_LENGTH]; char fwpath[PATH_LENGTH]; }ah_img_cfg; typedef struct ah_device_config_ { int device_type; int encrypt_mode; int encrypt_pattern; int image_num; int version; int top_header_enable; int package_type; int img_size; int layout_index; int lzma_type; int fw2_load; int img_type; int vendor_id; int magic_no; int crc; char key_word[PATH_LENGTH]; ah_img_cfg image[MAX_IMAGE_NUM]; }ah_cfg; #define CH_SPC 0x20 #define CH_TAB 0x09 int ah_funShowHeader(char argc, char *argv[]); int ah_atoi(char * str) { int value = 0; int sign = 1; int radix; if(*str == '-') { sign = -1; str++; } if(*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X')) { radix = 16; str += 2; } else if(*str == '0') { radix = 8; str++; } else { radix = 10; } while(*str) { if(radix == 16) { if(*str >= '0' && *str <= '9') { value = value * radix + *str - '0'; } else if(*str >= 'A' && *str <= 'F') { value = value * radix + *str - 'A' + 10; } else if(*str >= 'a' && *str <= 'f') { value = value * radix + *str - 'a' + 10; } else { break; } } else if(radix == 8) { if(*str >= '0' && *str <= '7') { value = value * radix + *str - '0'; } else { break; } } else { if(*str >= '0' && *str <= '9') { value = value * radix + *str - '0'; } else { break; } } str ++; } return sign*value; } static int ah_isSpace(int c) { switch (c) { case 0x20: case 0xD: case 0xA: case 0x9: return 1; } return 0; } #define ISSPACE(c) ah_isSpace(c) /* skip white space */ char *ah_GetValidString(char *str) { char *start, *end; start = str; end = str+strlen(str)-1; while((start<=end) && ISSPACE(*start)) start++; while((start<=end) && ISSPACE(*end)) end--; if(start > end) return NULL; *(end+1) = 0x0; return start; } char *ah_GetKeyString(FILE *fp, char *title, char *key) { #define LINE_LENGTH 1024 int start=0; char *pt; static char sLine[LINE_LENGTH]; fseek(fp, 0, SEEK_SET); while (NULL != fgets(sLine, LINE_LENGTH, fp)) { if (('#' ==sLine[0]) ||(';' ==sLine[0])) continue; if('[' ==sLine[0]) { start =0; } if(start) { if((NULL != (pt = strchr(sLine, '='))) &&(0 == strncmp(key, sLine, pt-sLine))) { sLine[LINE_LENGTH-1] = 0x0; pt = ah_GetValidString(pt + 1);; return pt; } } else { if(0 == strncmp(title, sLine, strlen(title)-1)) { start =1; } } } return NULL; } void ah_help(void) { printf(NEW_LINE"--Usage of ah:"NEW_LINE); printf(NEW_LINE"ah -c config-file"); printf(NEW_LINE" e.g. ah -c ./ah_config.cfg"); printf(NEW_LINE"ah -s file"); printf(NEW_LINE" Show the header(s) of a package."NEW_LINE); printf(NEW_LINE); return ; } static void ah_Sha256(unsigned char* img, int len, unsigned char* sha256) { sha256_context ctx; sha256_init( &ctx ); sha256_starts( &ctx ); sha256_update( &ctx, img, len ); sha256_update( &ctx, (unsigned char*)default_hash_iv, 16); sha256_finish( &ctx, sha256 ); sha256_free( &ctx ); } #define DEVICE_STR "[DEVICE]" #define DEVICE_STR_TYPE "device_type" #define DEVICE_STR_IMGNUM "image_num" #define DEVICE_STR_KEYWRD "key_word" #define DEVICE_STR_TOPHDRENA "top_header_enable" #define DEVICE_STR_TOPHDRENC "encrypt_mode" #define DEVICE_STR_TOPHDRPTN "encrypt_pattern" #define DEVICE_STR_TOPHDRVER "version" #define DEVICE_STR_PACKAGE_TYPE "package_type" #define DEVICE_STR_MAGIC_NO "magic_no" #define DEVICE_STR_IMAGE_SIZE "img_size" #define DEVICE_STR_LAYOUT_INDEX "layout_index" #define DEVICE_STR_LZMA_TYPE "lzma_type" #define DEVICE_STR_FW2_LOAD "fw2_load" #define DEVICE_STR_IMAGE_TYPE "img_type" #define DEVICE_STR_VENDOR_ID "vendor_id" #define IMAGE_STR "[IMAGE_%02d]" //#define IMAGE_STR_PADENA "pad_enable" //#define IMAGE_STR_PAD "pad" #define IMAGE_STR_TYPE "image_type" #define IMAGE_STR_VERSION "version" #define IMAGE_STR_PATH "path" #define IMAGE_STR_OFFSET "offset" #define IMAGE_STR_LENGTH "length" int ah_GetConfig(char *pcfgName, ah_cfg *pcfg) { FILE *fconfig; char *pkey; char imageName[64]; ah_cfg *cfg=pcfg; int tmp0,tmp1,tmp2,tmp3,i; if(NULL == (fconfig=fopen(pcfgName, "r"))) { printf("\r\n Can not open config: %s!\r\n", pcfgName); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_TYPE))) { cfg->device_type = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_TYPE, DEVICE_STR); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_IMGNUM))) { cfg->image_num = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_IMGNUM, DEVICE_STR); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_KEYWRD))) { if(strlen(pkey) <= KEYWRD_LENGTH) { strcpy(cfg->key_word, pkey); } else { printf("\r\n Keywords over length: %s !\r\n", pkey); return -1; } } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_KEYWRD, DEVICE_STR); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_TOPHDRENA))) { cfg->top_header_enable = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_TOPHDRENA, DEVICE_STR); return -1; } if(cfg->top_header_enable) { if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_TOPHDRENC))) { cfg->encrypt_mode = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_TOPHDRENC, DEVICE_STR); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_TOPHDRPTN))) { cfg->encrypt_pattern = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_TOPHDRPTN, DEVICE_STR); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_TOPHDRVER))) { sscanf(pkey, "%d.%d.%d.%d", &tmp0, &tmp1, &tmp2, &tmp3); cfg->version = ((tmp0&0x1F)<<27)|((tmp1&0x7F)<<20)|((tmp2&0xF)<<16)|(tmp3&0xFFFF); } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_TOPHDRVER, DEVICE_STR); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_IMAGE_SIZE))) { cfg->img_size = ah_atoi(pkey); } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_LAYOUT_INDEX))) { cfg->layout_index = ah_atoi(pkey); } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_PACKAGE_TYPE))) { cfg->package_type = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_PACKAGE_TYPE, DEVICE_STR); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_MAGIC_NO))) { cfg->magic_no = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", DEVICE_STR_MAGIC_NO, DEVICE_STR); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_LZMA_TYPE))) { cfg->lzma_type = ah_atoi(pkey); } if (NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_FW2_LOAD))) { cfg->fw2_load = ah_atoi(pkey); } if (NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_IMAGE_TYPE))) { cfg->img_type = ah_atoi(pkey); } if(NULL != (pkey = ah_GetKeyString(fconfig, DEVICE_STR, DEVICE_STR_VENDOR_ID))) { cfg->vendor_id = ah_atoi(pkey); } } for(i = 0; i < cfg->image_num; i++) { sprintf(imageName, IMAGE_STR, i+1); if(NULL != (pkey = ah_GetKeyString(fconfig, imageName, IMAGE_STR_TYPE))) { cfg->image[i].image_type = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", IMAGE_STR_TYPE, imageName); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, imageName, IMAGE_STR_VERSION))) { sscanf(pkey, "%d.%d.%d", &tmp0, &tmp1, &tmp2); cfg->image[i].version = ((tmp0&0xF)<<12)|((tmp1&0xF)<<8)|(tmp2&0xFF); } else { printf("\r\n Can not find %s in %s !\r\n", IMAGE_STR_VERSION, imageName); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, imageName, IMAGE_STR_PATH))) { if(strlen(pkey) <= PATH_LENGTH) { strcpy(cfg->image[i].path, pkey); strcpy(cfg->image[i].fwpath, pkey); strcat(cfg->image[i].fwpath, ".fw"); } else { printf("\r\n Path over length: %s !\r\n", pkey); return -1; } } else { printf("\r\n Can not find %s in %s !\r\n", IMAGE_STR_PATH, imageName); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, imageName, IMAGE_STR_OFFSET))) { cfg->image[i].offset = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", IMAGE_STR_OFFSET, imageName); return -1; } if(NULL != (pkey = ah_GetKeyString(fconfig, imageName, IMAGE_STR_LENGTH))) { cfg->image[i].length = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", IMAGE_STR_LENGTH, imageName); return -1; } #if 0 if(NULL != (pkey = ah_GetKeyString(fconfig, imageName, IMAGE_STR_PADENA))) { cfg->image[i].pad_enable = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", IMAGE_STR_PADENA, DEVICE_STR); return -1; } if(cfg->image[i].pad_enable) { if(NULL != (pkey = ah_GetKeyString(fconfig, imageName, IMAGE_STR_PAD))) { cfg->image[i].pad = ah_atoi(pkey); } else { printf("\r\n Can not find %s in %s !\r\n", IMAGE_STR_PAD, DEVICE_STR); return -1; } } #endif } return 0; } #define PACKAGE_HEADER_SIZE 96 int ah_funConstruct(char argc, char *argv[]) { FILE *fps = NULL, *fpd = NULL; int cnt, _CRC, fileSize, crcSize, ret =RET_OK, i; char pkName[256]; time_t rawtime; struct tm *timeinfo; ah_cfg cfg; unsigned char sha[32]; struct stat st; char *sh_argv[3]; char *p_buf = NULL; char *p_saved_buf = NULL; iot_pkg_hdr_t *hdr = NULL; char *payload = NULL; int pad_len = 0; int len = 0; int offset = 0; int total_size = 0; char *fw_buffer = NULL; uint32_t fw_crc = 0; uint32_t fw_size = 0; char psram_size = sizeType_max; char new_header_version = 0; char *psram_str = NULL; if(argc < 3) { return RET_BAD_PARA; } if (argc >= 4) { psram_str = (char*)argv[3]; if ((psram_str[0] == 'p') || (psram_str[0] == 'P')) { psram_size = atoi(++psram_str); } if ((psram_size == sizeType_0MB) || (psram_size == sizeType_2MB) || (psram_size == sizeType_4MB) || (psram_size == sizeType_8MB)) { new_header_version = 1; } } memset(&cfg, 0x0, sizeof(ah_cfg)); /* Get local time */ time ( &rawtime ); timeinfo = localtime ( &rawtime ); /* Get information from input */ if(NULL == (global_buffer = (char*)malloc(PK_SINGLE_FILE_SIZE))) { ret = RET_ENV_FAILED; goto ERROR_HANDLE; } if(NULL == (fw_buffer = (char*)malloc(PK_SINGLE_FILE_SIZE))) { ret = RET_ENV_FAILED; goto ERROR_HANDLE; } if(0 != ah_GetConfig(argv[2], &cfg)) { ret = RET_ENV_FAILED; goto ERROR_HANDLE; } if(cfg.image_num>MAX_IMAGE_NUM || cfg.image_num<0) { printf(NEW_LINE"Invalid config file(%s)."NEW_LINE, argv[2]); ret = RET_ENV_FAILED; goto ERROR_HANDLE; } /* make package name */ sprintf(pkName, "./%s%04d%02d%02d.bin", cfg.key_word,\ timeinfo->tm_year+1900, timeinfo->tm_mon+1, timeinfo->tm_mday); memset(global_buffer, 0x0, PK_SINGLE_FILE_SIZE); if(cfg.top_header_enable) { /*image header*/ hdr = (iot_pkg_hdr_t*)global_buffer; hdr->enctype = cfg.encrypt_mode; hdr->pattern = cfg.encrypt_pattern; hdr->dev_type = htons(cfg.package_type); hdr->magic_no = htonl(cfg.magic_no); hdr->version = htonl(cfg.version); hdr->vendor_id = htons(cfg.vendor_id); hdr->img_flag = (cfg.img_size) << 4 | (cfg.lzma_type)<< 2 | (cfg.fw2_load)<< 3; hdr->img_type = cfg.img_type; /*image payload*/ payload = global_buffer + sizeof(iot_pkg_hdr_t); } else { /*image payload*/ payload = global_buffer; } p_buf = payload; /* 2400 aligned */ if((cfg.image_num > 0) && ((cfg.image[0].image_type == imgCFG) ||(cfg.image[0].image_type == imgFRW) ||(cfg.image[0].image_type == imgCFRW) ||(cfg.image[0].image_type == imgCFRW1) ||(cfg.image[0].image_type == imgCFRW4F) ||(cfg.image[0].image_type == imgCFRW4P))) { len = p_buf - global_buffer; if(len%2400) { len = 2400 - (len%2400); for(i=0; icfg.image[cnt].length || (crcSize+imgHeaderSize) > PK_SINGLE_FILE_SIZE) { printf(NEW_LINE"Image oversize(%s, size:%d, limited:%d)."NEW_LINE, cfg.image[cnt].path, crcSize, cfg.image[cnt].length - imgHeaderSize); ret = RET_IMAGE_WRONG; goto ERROR_HANDLE; } /* for CRC */ _CRC= 0xFFFFFFFF^CRC32_Update(0xFFFFFFFF, p_buf + imgHeaderSize, crcSize); ah_Sha256((unsigned char*)(p_buf + imgHeaderSize), fileSize, sha); if ((cfg.image[cnt].image_type == imgCFRW) ||(cfg.image[cnt].image_type == imgCFRW1) ||(cfg.image[cnt].image_type == imgCFRW4F) ||(cfg.image[cnt].image_type == imgCFRW4P)){ if((0 == stat(cfg.image[cnt].fwpath, &st)) &&(NULL != (fps=fopen(cfg.image[cnt].fwpath, "r")))){ /* Get file size */ fseek(fps, 0, SEEK_END); fw_size = ftell(fps); fseek(fps, 0, SEEK_SET); /* Read file into buffer */ fread(fw_buffer, 1, fw_size, fps); fclose(fps); fps = NULL; fw_crc = 0xFFFFFFFF^CRC32_Update(0xFFFFFFFF, fw_buffer, fw_size); } } /* Fill header structure */ /* device type */ p_buf[0] = (char)GET_BYTE2(cfg.device_type); p_buf[1] = (char)GET_BYTE1(cfg.device_type); /* image type */ p_buf[2] = (char)GET_BYTE2(cfg.image[cnt].image_type); p_buf[3] = (char)GET_BYTE1(cfg.image[cnt].image_type); /* image size */ p_buf[4] = (char)GET_BYTE4(fileSize); p_buf[5] = (char)GET_BYTE3(fileSize); p_buf[6] = (char)GET_BYTE2(fileSize); p_buf[7] = (char)GET_BYTE1(fileSize); /* image version */ p_buf[8] = (char)GET_BYTE2(cfg.image[cnt].version); p_buf[9] = (char)GET_BYTE1(cfg.image[cnt].version); if (new_header_version) { /* psram size */ p_buf[10] = psram_size; /* hdr version */ p_buf[11] = hdrVer_02; } else { /* psram size */ p_buf[10] = 0; /* hdr version */ p_buf[11] = 0; } /* FW SZIE */ p_buf[12] = (char)GET_BYTE4(fw_size); p_buf[13] = (char)GET_BYTE3(fw_size); p_buf[14] = (char)GET_BYTE2(fw_size); p_buf[15] = (char)GET_BYTE1(fw_size); /* CRC */ p_buf[16] = (char)GET_BYTE4(_CRC); p_buf[17] = (char)GET_BYTE3(_CRC); p_buf[18] = (char)GET_BYTE2(_CRC); p_buf[19] = (char)GET_BYTE1(_CRC); /* Guard */ p_buf[20] = (char)GET_BYTE4(IMAGE_GUARD); p_buf[21] = (char)GET_BYTE3(IMAGE_GUARD); p_buf[22] = (char)GET_BYTE2(IMAGE_GUARD); p_buf[23] = (char)GET_BYTE1(IMAGE_GUARD); /* flash layout index */ p_buf[24] = cfg.layout_index; /* reserved, default 0 */ p_buf[25] = 0; p_buf[26] = 0; p_buf[27] = 0; p_buf[28] = (char)GET_BYTE4(fw_crc); p_buf[29] = (char)GET_BYTE3(fw_crc); p_buf[30] = (char)GET_BYTE2(fw_crc); p_buf[31] = (char)GET_BYTE1(fw_crc); /* SHA256 */ for(i=32; i<64; i++) { p_buf[i] = sha[i-32]; } /* write image */ len = crcSize + imgHeaderSize; /*update buffer pointer*/ p_buf += len; /*new bin file's size*/ len = p_buf - p_saved_buf; total_size += len; if(cfg.top_header_enable) { /*update image header*/ offset = p_saved_buf - global_buffer; if(cfg.image[cnt].image_type == imgSP) { hdr->sp_start = htonl(offset); hdr->sp_len = htonl(crcSize+imgHeaderSize); } if(cfg.image[cnt].image_type == imgSBL) { hdr->sbl_start = htonl(offset); hdr->sbl_len = htonl(crcSize+imgHeaderSize); } if(cfg.image[cnt].image_type == imgOEM) { hdr->oem_start = htonl(offset); hdr->oem_len = htonl(crcSize+imgHeaderSize); } if(cfg.image[cnt].image_type == imgCFG) { hdr->pib_start = htonl(offset); hdr->pib_len = htonl(crcSize+imgHeaderSize); } if((cfg.image[cnt].image_type == imgFRW) ||(cfg.image[cnt].image_type == imgCFRW) ||(cfg.image[cnt].image_type == imgCFRW1) ||(cfg.image[cnt].image_type == imgCFRW4F) ||(cfg.image[cnt].image_type == imgCFRW4P)) { static uint8_t fw_packed = 0; if(!fw_packed){ hdr->fw_start = htonl(offset); hdr->fw_len = htonl(crcSize+imgHeaderSize); fw_packed = 1; }else { hdr->fw2_start = htonl(offset); hdr->fw2_len = htonl(crcSize+imgHeaderSize); } } if (cfg.image[cnt].image_type == imgFRW2) { if (cfg.fw2_load) { // fw2 load enable hdr->fw2_start = htonl(offset); hdr->fw2_len = htonl(crcSize + imgHeaderSize); } } if(cfg.image[cnt].image_type == imgEFUSE) { hdr->efuse_start = htonl(offset); hdr->efuse_len = htonl(crcSize+imgHeaderSize); } /* pack reference info */ if (cfg.image[cnt].image_type == imgREF) { hdr->ref_start = htonl(offset); hdr->ref_len = htonl(crcSize+imgHeaderSize); } /* pack custom info */ if (cfg.image[cnt].image_type == imgCUS) { hdr->cus_start = htonl(offset); hdr->cus_len = htonl(crcSize+imgHeaderSize); } } /* 2400 aligned */ if((cnt+1 < cfg.image_num) &&((cfg.image[cnt+1].image_type == imgCFG) ||(cfg.image[cnt+1].image_type == imgFRW) ||(cfg.image[cnt+1].image_type == imgCFRW) ||(cfg.image[cnt+1].image_type == imgCFRW1) ||(cfg.image[cnt+1].image_type == imgCFRW4F) ||(cfg.image[cnt+1].image_type == imgCFRW4P))) { len = p_buf - global_buffer; if(len%2400) { len = 2400 - (len%2400); for(i=0; ifile_len = htonl(total_size); /*calculate payload's CRC*/ cfg.crc = 0xFFFFFFFF^CRC32_Update(0xFFFFFFFF, payload , total_size); hdr->file_crc = htonl(cfg.crc); if(1 == cfg.encrypt_mode) { st = payload; end = payload + total_size; ptn = (cfg.encrypt_pattern&0xFF); while(st <= end){ *(st) += ptn; st++; } } else if(2 == cfg.encrypt_mode) { st = payload; end = payload + total_size; ptn = (cfg.encrypt_pattern&0xFF); while(st <= end){ *(st) -= ptn; st++; } } else if(3 == cfg.encrypt_mode) { st = global_buffer; end = payload + total_size; ptn = (cfg.encrypt_pattern&0xFF); while(st <= end) { *(st) ^= ptn; st++; } } } /*write buffer into file*/ if(NULL == (fpd=fopen(pkName, "w+"))) { printf(NEW_LINE"Cannot open package file(%s)."NEW_LINE, pkName); goto ERROR_HANDLE; } if(cfg.top_header_enable) { fwrite(global_buffer, 1, total_size + PACKAGE_HEADER_SIZE, fpd); } else { fwrite(global_buffer, 1, total_size, fpd); } fclose(fpd); fpd = NULL; /* show info */ sh_argv[2] = pkName; ah_funShowHeader(3, sh_argv); printf(NEW_LINE"Package created - %s"NEW_LINE, pkName); ret = RET_OK; ERROR_HANDLE: if(global_buffer) { free(global_buffer); global_buffer = NULL; } if(fpd) { fclose(fpd); if(RET_OK != ret) remove(pkName); fpd = NULL; } if(fps) { fclose(fps); fps = NULL; } return ret; } int ah_funShowHeader(char argc, char *argv[]) { FILE *fps = NULL; char pbuf[imgHeaderSize]; int imgNo=0, tmp1, tmp2, tmp3, offset, start, device; if(argc < 3) { return RET_BAD_PARA; } if(NULL == (fps=fopen(argv[2], "r"))) { printf(NEW_LINE"Cannot open package file(%s)."NEW_LINE, argv[2]); return RET_BAD_PARA; } do { imgNo++; while(32 == (tmp1 = fread(pbuf, 1, 32, fps))) { if(1==imgNo) { tmp3 = IMGHDR_GET_GUARD(pbuf); if(tmp3 == (((int)IMAGE_GUARD)&0xFFFFFFFF)) { device = IMGHDR_GET_DEVTYPE(pbuf); if((((int)devKunlun)&0xFFFF) == device) { break; } } } else { tmp2 = IMGHDR_GET_DEVTYPE(pbuf); tmp3 = IMGHDR_GET_GUARD(pbuf); if((tmp2 == device) &&(tmp3 == (((int)IMAGE_GUARD)&0xFFFFFFFF))) break; } } if(32 != tmp1) { fclose(fps); return RET_OK; } tmp1 = fread(pbuf+32, 1, 32, fps); if(32 != tmp1) { fclose(fps); printf(NEW_LINE"Maybe the package is damaged."NEW_LINE NEW_LINE); return RET_OK; } /* Print headers */ start = ftell(fps) - imgHeaderSize; printf(NEW_LINE"Image NO.%02d @ 0x%08x:", imgNo, start); tmp1 = IMGHDR_GET_DEVTYPE(pbuf); printf(NEW_LINE" device:0x%04x", tmp1&0xFFFF); tmp1 = IMGHDR_GET_IMGTYPE(pbuf); printf(NEW_LINE" image:0x%04x", tmp1&0xFFFF); tmp1 = IMGHDR_GET_IMGSIZE(pbuf); offset = IMAGE_LEN_FOR_CRC(tmp1); printf(NEW_LINE" size:%d Bytes", tmp1); tmp1 = IMGHDR_GET_IMGVER(pbuf); printf(NEW_LINE" version:%d.%d.%d", (tmp1>>12)&0xF, (tmp1>>8)&0xF, tmp1&0xFF); tmp1 = IMGHDR_GET_PSRAMSIZE(pbuf); printf(NEW_LINE" psram size:%dM", tmp1); tmp1 = IMGHDR_GET_HDRVER(pbuf); printf(NEW_LINE" hdr version:0x%02X", tmp1&0xFF); tmp1 = IMGHDR_GET_FWSIZE(pbuf); printf(NEW_LINE" FW Size:0x%08x", tmp1); tmp1 = IMGHDR_GET_LAYOUTIDX(pbuf); printf(NEW_LINE" flash layout index:0x%02x", tmp1); tmp1 = IMGHDR_GET_CRC(pbuf); printf(NEW_LINE" CRC:0x%08x", tmp1); tmp1 = IMGHDR_GET_FWCRC(pbuf); printf(NEW_LINE" FW CRC:0x%08x", tmp1); printf(NEW_LINE" SHA256:"); for(tmp1 = 32; tmp1 < 64; tmp1++) { tmp2 = ((int)pbuf[tmp1])&0xFF; printf("%02x", tmp2); } printf(NEW_LINE); /* skip size */ if(fseek(fps, offset, SEEK_CUR)) { fclose(fps); return RET_OK; } }while(1); return RET_OK; } int main(int argc, char *argv[]) { int ret = RET_BAD_PARA; if(argc <= 1) { ah_help(); goto err_out; } if(0 == strcmp(FUNC_CONSTRUCT, argv[1])) { ret =ah_funConstruct(argc, argv); } else if(0 == strcmp(FUNC_SHOWHEADER, argv[1])) { ret =ah_funShowHeader(argc, argv); } if(RET_OK == ret) { return 0; } err_out: printf(NEW_LINE"Something wrong !"NEW_LINE NEW_LINE); return ret; }