1*23ba6841SJoseph Chen /* 2*23ba6841SJoseph Chen * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd 3*23ba6841SJoseph Chen * 4*23ba6841SJoseph Chen * SPDX-License-Identifier: GPL-2.0+ 5*23ba6841SJoseph Chen */ 6*23ba6841SJoseph Chen #include "boot_merger.h" 7*23ba6841SJoseph Chen #include <time.h> 8*23ba6841SJoseph Chen #include <sys/stat.h> 9*23ba6841SJoseph Chen #include <version.h> 10*23ba6841SJoseph Chen 11*23ba6841SJoseph Chen /* #define USE_P_RC4 */ 12*23ba6841SJoseph Chen 13*23ba6841SJoseph Chen bool gDebug = 14*23ba6841SJoseph Chen #ifdef DEBUG 15*23ba6841SJoseph Chen true; 16*23ba6841SJoseph Chen #else 17*23ba6841SJoseph Chen false; 18*23ba6841SJoseph Chen #endif /* DEBUG */ 19*23ba6841SJoseph Chen 20*23ba6841SJoseph Chen #define ENTRY_ALIGN (2048) 21*23ba6841SJoseph Chen options gOpts; 22*23ba6841SJoseph Chen char gLegacyPath[MAX_LINE_LEN] = { 0 }; 23*23ba6841SJoseph Chen char gNewPath[MAX_LINE_LEN] = { 0 }; 24*23ba6841SJoseph Chen char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 25*23ba6841SJoseph Chen char gEat[MAX_LINE_LEN]; 26*23ba6841SJoseph Chen char *gConfigPath; 27*23ba6841SJoseph Chen uint8_t *gBuf; 28*23ba6841SJoseph Chen 29*23ba6841SJoseph Chen static uint32_t g_merge_max_size = MAX_MERGE_SIZE; 30*23ba6841SJoseph Chen 31*23ba6841SJoseph Chen uint32_t gTable_Crc32[256] = { 32*23ba6841SJoseph Chen 0x00000000, 0x04c10db7, 0x09821b6e, 0x0d4316d9, 0x130436dc, 0x17c53b6b, 33*23ba6841SJoseph Chen 0x1a862db2, 0x1e472005, 0x26086db8, 0x22c9600f, 0x2f8a76d6, 0x2b4b7b61, 34*23ba6841SJoseph Chen 0x350c5b64, 0x31cd56d3, 0x3c8e400a, 0x384f4dbd, 0x4c10db70, 0x48d1d6c7, 35*23ba6841SJoseph Chen 0x4592c01e, 0x4153cda9, 0x5f14edac, 0x5bd5e01b, 0x5696f6c2, 0x5257fb75, 36*23ba6841SJoseph Chen 0x6a18b6c8, 0x6ed9bb7f, 0x639aada6, 0x675ba011, 0x791c8014, 0x7ddd8da3, 37*23ba6841SJoseph Chen 0x709e9b7a, 0x745f96cd, 0x9821b6e0, 0x9ce0bb57, 0x91a3ad8e, 0x9562a039, 38*23ba6841SJoseph Chen 0x8b25803c, 0x8fe48d8b, 0x82a79b52, 0x866696e5, 0xbe29db58, 0xbae8d6ef, 39*23ba6841SJoseph Chen 0xb7abc036, 0xb36acd81, 0xad2ded84, 0xa9ece033, 0xa4aff6ea, 0xa06efb5d, 40*23ba6841SJoseph Chen 0xd4316d90, 0xd0f06027, 0xddb376fe, 0xd9727b49, 0xc7355b4c, 0xc3f456fb, 41*23ba6841SJoseph Chen 0xceb74022, 0xca764d95, 0xf2390028, 0xf6f80d9f, 0xfbbb1b46, 0xff7a16f1, 42*23ba6841SJoseph Chen 0xe13d36f4, 0xe5fc3b43, 0xe8bf2d9a, 0xec7e202d, 0x34826077, 0x30436dc0, 43*23ba6841SJoseph Chen 0x3d007b19, 0x39c176ae, 0x278656ab, 0x23475b1c, 0x2e044dc5, 0x2ac54072, 44*23ba6841SJoseph Chen 0x128a0dcf, 0x164b0078, 0x1b0816a1, 0x1fc91b16, 0x018e3b13, 0x054f36a4, 45*23ba6841SJoseph Chen 0x080c207d, 0x0ccd2dca, 0x7892bb07, 0x7c53b6b0, 0x7110a069, 0x75d1adde, 46*23ba6841SJoseph Chen 0x6b968ddb, 0x6f57806c, 0x621496b5, 0x66d59b02, 0x5e9ad6bf, 0x5a5bdb08, 47*23ba6841SJoseph Chen 0x5718cdd1, 0x53d9c066, 0x4d9ee063, 0x495fedd4, 0x441cfb0d, 0x40ddf6ba, 48*23ba6841SJoseph Chen 0xaca3d697, 0xa862db20, 0xa521cdf9, 0xa1e0c04e, 0xbfa7e04b, 0xbb66edfc, 49*23ba6841SJoseph Chen 0xb625fb25, 0xb2e4f692, 0x8aabbb2f, 0x8e6ab698, 0x8329a041, 0x87e8adf6, 50*23ba6841SJoseph Chen 0x99af8df3, 0x9d6e8044, 0x902d969d, 0x94ec9b2a, 0xe0b30de7, 0xe4720050, 51*23ba6841SJoseph Chen 0xe9311689, 0xedf01b3e, 0xf3b73b3b, 0xf776368c, 0xfa352055, 0xfef42de2, 52*23ba6841SJoseph Chen 0xc6bb605f, 0xc27a6de8, 0xcf397b31, 0xcbf87686, 0xd5bf5683, 0xd17e5b34, 53*23ba6841SJoseph Chen 0xdc3d4ded, 0xd8fc405a, 0x6904c0ee, 0x6dc5cd59, 0x6086db80, 0x6447d637, 54*23ba6841SJoseph Chen 0x7a00f632, 0x7ec1fb85, 0x7382ed5c, 0x7743e0eb, 0x4f0cad56, 0x4bcda0e1, 55*23ba6841SJoseph Chen 0x468eb638, 0x424fbb8f, 0x5c089b8a, 0x58c9963d, 0x558a80e4, 0x514b8d53, 56*23ba6841SJoseph Chen 0x25141b9e, 0x21d51629, 0x2c9600f0, 0x28570d47, 0x36102d42, 0x32d120f5, 57*23ba6841SJoseph Chen 0x3f92362c, 0x3b533b9b, 0x031c7626, 0x07dd7b91, 0x0a9e6d48, 0x0e5f60ff, 58*23ba6841SJoseph Chen 0x101840fa, 0x14d94d4d, 0x199a5b94, 0x1d5b5623, 0xf125760e, 0xf5e47bb9, 59*23ba6841SJoseph Chen 0xf8a76d60, 0xfc6660d7, 0xe22140d2, 0xe6e04d65, 0xeba35bbc, 0xef62560b, 60*23ba6841SJoseph Chen 0xd72d1bb6, 0xd3ec1601, 0xdeaf00d8, 0xda6e0d6f, 0xc4292d6a, 0xc0e820dd, 61*23ba6841SJoseph Chen 0xcdab3604, 0xc96a3bb3, 0xbd35ad7e, 0xb9f4a0c9, 0xb4b7b610, 0xb076bba7, 62*23ba6841SJoseph Chen 0xae319ba2, 0xaaf09615, 0xa7b380cc, 0xa3728d7b, 0x9b3dc0c6, 0x9ffccd71, 63*23ba6841SJoseph Chen 0x92bfdba8, 0x967ed61f, 0x8839f61a, 0x8cf8fbad, 0x81bbed74, 0x857ae0c3, 64*23ba6841SJoseph Chen 0x5d86a099, 0x5947ad2e, 0x5404bbf7, 0x50c5b640, 0x4e829645, 0x4a439bf2, 65*23ba6841SJoseph Chen 0x47008d2b, 0x43c1809c, 0x7b8ecd21, 0x7f4fc096, 0x720cd64f, 0x76cddbf8, 66*23ba6841SJoseph Chen 0x688afbfd, 0x6c4bf64a, 0x6108e093, 0x65c9ed24, 0x11967be9, 0x1557765e, 67*23ba6841SJoseph Chen 0x18146087, 0x1cd56d30, 0x02924d35, 0x06534082, 0x0b10565b, 0x0fd15bec, 68*23ba6841SJoseph Chen 0x379e1651, 0x335f1be6, 0x3e1c0d3f, 0x3add0088, 0x249a208d, 0x205b2d3a, 69*23ba6841SJoseph Chen 0x2d183be3, 0x29d93654, 0xc5a71679, 0xc1661bce, 0xcc250d17, 0xc8e400a0, 70*23ba6841SJoseph Chen 0xd6a320a5, 0xd2622d12, 0xdf213bcb, 0xdbe0367c, 0xe3af7bc1, 0xe76e7676, 71*23ba6841SJoseph Chen 0xea2d60af, 0xeeec6d18, 0xf0ab4d1d, 0xf46a40aa, 0xf9295673, 0xfde85bc4, 72*23ba6841SJoseph Chen 0x89b7cd09, 0x8d76c0be, 0x8035d667, 0x84f4dbd0, 0x9ab3fbd5, 0x9e72f662, 73*23ba6841SJoseph Chen 0x9331e0bb, 0x97f0ed0c, 0xafbfa0b1, 0xab7ead06, 0xa63dbbdf, 0xa2fcb668, 74*23ba6841SJoseph Chen 0xbcbb966d, 0xb87a9bda, 0xb5398d03, 0xb1f880b4, 75*23ba6841SJoseph Chen }; 76*23ba6841SJoseph Chen 77*23ba6841SJoseph Chen uint32_t CRC_32(uint8_t *pData, uint32_t ulSize) 78*23ba6841SJoseph Chen { 79*23ba6841SJoseph Chen uint32_t i; 80*23ba6841SJoseph Chen uint32_t nAccum = 0; 81*23ba6841SJoseph Chen for (i = 0; i < ulSize; i++) { 82*23ba6841SJoseph Chen nAccum = (nAccum << 8) ^ gTable_Crc32[(nAccum >> 24) ^ (*pData++)]; 83*23ba6841SJoseph Chen } 84*23ba6841SJoseph Chen return nAccum; 85*23ba6841SJoseph Chen } 86*23ba6841SJoseph Chen 87*23ba6841SJoseph Chen void P_RC4(uint8_t *buf, uint32_t len) 88*23ba6841SJoseph Chen { 89*23ba6841SJoseph Chen uint8_t S[256], K[256], temp; 90*23ba6841SJoseph Chen uint32_t i, j, t, x; 91*23ba6841SJoseph Chen uint8_t key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 92*23ba6841SJoseph Chen 17 93*23ba6841SJoseph Chen }; 94*23ba6841SJoseph Chen 95*23ba6841SJoseph Chen j = 0; 96*23ba6841SJoseph Chen for (i = 0; i < 256; i++) { 97*23ba6841SJoseph Chen S[i] = (uint8_t) i; 98*23ba6841SJoseph Chen j &= 0x0f; 99*23ba6841SJoseph Chen K[i] = key[j]; 100*23ba6841SJoseph Chen j++; 101*23ba6841SJoseph Chen } 102*23ba6841SJoseph Chen 103*23ba6841SJoseph Chen j = 0; 104*23ba6841SJoseph Chen for (i = 0; i < 256; i++) { 105*23ba6841SJoseph Chen j = (j + S[i] + K[i]) % 256; 106*23ba6841SJoseph Chen temp = S[i]; 107*23ba6841SJoseph Chen S[i] = S[j]; 108*23ba6841SJoseph Chen S[j] = temp; 109*23ba6841SJoseph Chen } 110*23ba6841SJoseph Chen 111*23ba6841SJoseph Chen i = j = 0; 112*23ba6841SJoseph Chen for (x = 0; x < len; x++) { 113*23ba6841SJoseph Chen i = (i + 1) % 256; 114*23ba6841SJoseph Chen j = (j + S[i]) % 256; 115*23ba6841SJoseph Chen temp = S[i]; 116*23ba6841SJoseph Chen S[i] = S[j]; 117*23ba6841SJoseph Chen S[j] = temp; 118*23ba6841SJoseph Chen t = (S[i] + (S[j] % 256)) % 256; 119*23ba6841SJoseph Chen buf[x] = buf[x] ^ S[t]; 120*23ba6841SJoseph Chen } 121*23ba6841SJoseph Chen } 122*23ba6841SJoseph Chen 123*23ba6841SJoseph Chen static inline void fixPath(char *path) 124*23ba6841SJoseph Chen { 125*23ba6841SJoseph Chen int i, len = strlen(path); 126*23ba6841SJoseph Chen char tmp[MAX_LINE_LEN]; 127*23ba6841SJoseph Chen char *start, *end; 128*23ba6841SJoseph Chen 129*23ba6841SJoseph Chen for (i = 0; i < len; i++) { 130*23ba6841SJoseph Chen if (path[i] == '\\') 131*23ba6841SJoseph Chen path[i] = '/'; 132*23ba6841SJoseph Chen else if (path[i] == '\r' || path[i] == '\n') 133*23ba6841SJoseph Chen path[i] = '\0'; 134*23ba6841SJoseph Chen } 135*23ba6841SJoseph Chen 136*23ba6841SJoseph Chen if (strlen(gLegacyPath) && strlen(gNewPath)) { 137*23ba6841SJoseph Chen start = strstr(path, gLegacyPath); 138*23ba6841SJoseph Chen if (start) { 139*23ba6841SJoseph Chen end = start + strlen(gLegacyPath); 140*23ba6841SJoseph Chen /* Backup, so tmp can be src for strcat() */ 141*23ba6841SJoseph Chen strcpy(tmp, end); 142*23ba6841SJoseph Chen /* Terminate, so path can be dest for strcat() */ 143*23ba6841SJoseph Chen *start = '\0'; 144*23ba6841SJoseph Chen strcat(path, tmp); 145*23ba6841SJoseph Chen } 146*23ba6841SJoseph Chen } 147*23ba6841SJoseph Chen } 148*23ba6841SJoseph Chen 149*23ba6841SJoseph Chen static bool parseChip(FILE *file) 150*23ba6841SJoseph Chen { 151*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 152*23ba6841SJoseph Chen return false; 153*23ba6841SJoseph Chen } 154*23ba6841SJoseph Chen if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 155*23ba6841SJoseph Chen return false; 156*23ba6841SJoseph Chen } 157*23ba6841SJoseph Chen LOGD("chip:%s\n", gOpts.chip); 158*23ba6841SJoseph Chen return true; 159*23ba6841SJoseph Chen } 160*23ba6841SJoseph Chen 161*23ba6841SJoseph Chen static bool parseVersion(FILE *file) 162*23ba6841SJoseph Chen { 163*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 164*23ba6841SJoseph Chen return false; 165*23ba6841SJoseph Chen } 166*23ba6841SJoseph Chen if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 167*23ba6841SJoseph Chen return false; 168*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 169*23ba6841SJoseph Chen return false; 170*23ba6841SJoseph Chen } 171*23ba6841SJoseph Chen if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 172*23ba6841SJoseph Chen return false; 173*23ba6841SJoseph Chen LOGD("major:%d, minor:%d\n", gOpts.major, gOpts.minor); 174*23ba6841SJoseph Chen return true; 175*23ba6841SJoseph Chen } 176*23ba6841SJoseph Chen 177*23ba6841SJoseph Chen static bool parse471(FILE *file) 178*23ba6841SJoseph Chen { 179*23ba6841SJoseph Chen int i, index, pos; 180*23ba6841SJoseph Chen char buf[MAX_LINE_LEN]; 181*23ba6841SJoseph Chen 182*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 183*23ba6841SJoseph Chen return false; 184*23ba6841SJoseph Chen } 185*23ba6841SJoseph Chen if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 186*23ba6841SJoseph Chen return false; 187*23ba6841SJoseph Chen LOGD("num:%d\n", gOpts.code471Num); 188*23ba6841SJoseph Chen if (!gOpts.code471Num) 189*23ba6841SJoseph Chen return true; 190*23ba6841SJoseph Chen if (gOpts.code471Num < 0) 191*23ba6841SJoseph Chen return false; 192*23ba6841SJoseph Chen gOpts.code471Path = (line_t *)malloc(sizeof(line_t) * gOpts.code471Num); 193*23ba6841SJoseph Chen for (i = 0; i < gOpts.code471Num; i++) { 194*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 195*23ba6841SJoseph Chen return false; 196*23ba6841SJoseph Chen } 197*23ba6841SJoseph Chen if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) != 2) 198*23ba6841SJoseph Chen return false; 199*23ba6841SJoseph Chen index--; 200*23ba6841SJoseph Chen fixPath(buf); 201*23ba6841SJoseph Chen strcpy((char *)gOpts.code471Path[index], buf); 202*23ba6841SJoseph Chen LOGD("path%i:%s\n", index, gOpts.code471Path[index]); 203*23ba6841SJoseph Chen } 204*23ba6841SJoseph Chen pos = ftell(file); 205*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 206*23ba6841SJoseph Chen return false; 207*23ba6841SJoseph Chen } 208*23ba6841SJoseph Chen if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 209*23ba6841SJoseph Chen fseek(file, pos, SEEK_SET); 210*23ba6841SJoseph Chen LOGD("sleep:%d\n", gOpts.code471Sleep); 211*23ba6841SJoseph Chen return true; 212*23ba6841SJoseph Chen } 213*23ba6841SJoseph Chen 214*23ba6841SJoseph Chen static bool parse472(FILE *file) 215*23ba6841SJoseph Chen { 216*23ba6841SJoseph Chen int i, index, pos; 217*23ba6841SJoseph Chen char buf[MAX_LINE_LEN]; 218*23ba6841SJoseph Chen 219*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 220*23ba6841SJoseph Chen return false; 221*23ba6841SJoseph Chen } 222*23ba6841SJoseph Chen if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 223*23ba6841SJoseph Chen return false; 224*23ba6841SJoseph Chen LOGD("num:%d\n", gOpts.code472Num); 225*23ba6841SJoseph Chen if (!gOpts.code472Num) 226*23ba6841SJoseph Chen return true; 227*23ba6841SJoseph Chen if (gOpts.code472Num < 0) 228*23ba6841SJoseph Chen return false; 229*23ba6841SJoseph Chen gOpts.code472Path = (line_t *)malloc(sizeof(line_t) * gOpts.code472Num); 230*23ba6841SJoseph Chen for (i = 0; i < gOpts.code472Num; i++) { 231*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 232*23ba6841SJoseph Chen return false; 233*23ba6841SJoseph Chen } 234*23ba6841SJoseph Chen if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) != 2) 235*23ba6841SJoseph Chen return false; 236*23ba6841SJoseph Chen fixPath(buf); 237*23ba6841SJoseph Chen index--; 238*23ba6841SJoseph Chen strcpy((char *)gOpts.code472Path[index], buf); 239*23ba6841SJoseph Chen LOGD("path%i:%s\n", index, gOpts.code472Path[index]); 240*23ba6841SJoseph Chen } 241*23ba6841SJoseph Chen pos = ftell(file); 242*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 243*23ba6841SJoseph Chen return false; 244*23ba6841SJoseph Chen } 245*23ba6841SJoseph Chen if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 246*23ba6841SJoseph Chen fseek(file, pos, SEEK_SET); 247*23ba6841SJoseph Chen LOGD("sleep:%d\n", gOpts.code472Sleep); 248*23ba6841SJoseph Chen return true; 249*23ba6841SJoseph Chen } 250*23ba6841SJoseph Chen 251*23ba6841SJoseph Chen static bool parseLoader(FILE *file) 252*23ba6841SJoseph Chen { 253*23ba6841SJoseph Chen int i, j, index, pos; 254*23ba6841SJoseph Chen char buf[MAX_LINE_LEN]; 255*23ba6841SJoseph Chen char buf2[MAX_LINE_LEN]; 256*23ba6841SJoseph Chen 257*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 258*23ba6841SJoseph Chen return false; 259*23ba6841SJoseph Chen } 260*23ba6841SJoseph Chen pos = ftell(file); 261*23ba6841SJoseph Chen if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 262*23ba6841SJoseph Chen fseek(file, pos, SEEK_SET); 263*23ba6841SJoseph Chen if (fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 264*23ba6841SJoseph Chen return false; 265*23ba6841SJoseph Chen } 266*23ba6841SJoseph Chen } 267*23ba6841SJoseph Chen LOGD("num:%d\n", gOpts.loaderNum); 268*23ba6841SJoseph Chen if (!gOpts.loaderNum) 269*23ba6841SJoseph Chen return false; 270*23ba6841SJoseph Chen if (gOpts.loaderNum < 0) 271*23ba6841SJoseph Chen return false; 272*23ba6841SJoseph Chen gOpts.loader = (name_entry *)malloc(sizeof(name_entry) * gOpts.loaderNum); 273*23ba6841SJoseph Chen for (i = 0; i < gOpts.loaderNum; i++) { 274*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 275*23ba6841SJoseph Chen return false; 276*23ba6841SJoseph Chen } 277*23ba6841SJoseph Chen if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) != 2) 278*23ba6841SJoseph Chen return false; 279*23ba6841SJoseph Chen index--; 280*23ba6841SJoseph Chen strcpy(gOpts.loader[index].name, buf); 281*23ba6841SJoseph Chen LOGD("name%d:%s\n", index, gOpts.loader[index].name); 282*23ba6841SJoseph Chen } 283*23ba6841SJoseph Chen for (i = 0; i < gOpts.loaderNum; i++) { 284*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 285*23ba6841SJoseph Chen return false; 286*23ba6841SJoseph Chen } 287*23ba6841SJoseph Chen if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) != 2) 288*23ba6841SJoseph Chen return false; 289*23ba6841SJoseph Chen for (j = 0; j < gOpts.loaderNum; j++) { 290*23ba6841SJoseph Chen if (!strcmp(gOpts.loader[j].name, buf)) { 291*23ba6841SJoseph Chen fixPath(buf2); 292*23ba6841SJoseph Chen strcpy(gOpts.loader[j].path, buf2); 293*23ba6841SJoseph Chen LOGD("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 294*23ba6841SJoseph Chen break; 295*23ba6841SJoseph Chen } 296*23ba6841SJoseph Chen } 297*23ba6841SJoseph Chen if (j >= gOpts.loaderNum) { 298*23ba6841SJoseph Chen return false; 299*23ba6841SJoseph Chen } 300*23ba6841SJoseph Chen } 301*23ba6841SJoseph Chen return true; 302*23ba6841SJoseph Chen } 303*23ba6841SJoseph Chen 304*23ba6841SJoseph Chen static bool parseOut(FILE *file) 305*23ba6841SJoseph Chen { 306*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 307*23ba6841SJoseph Chen return false; 308*23ba6841SJoseph Chen } 309*23ba6841SJoseph Chen if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 310*23ba6841SJoseph Chen return false; 311*23ba6841SJoseph Chen fixPath(gOpts.outPath); 312*23ba6841SJoseph Chen printf("out:%s\n", gOpts.outPath); 313*23ba6841SJoseph Chen return true; 314*23ba6841SJoseph Chen } 315*23ba6841SJoseph Chen 316*23ba6841SJoseph Chen void printOpts(FILE *out) 317*23ba6841SJoseph Chen { 318*23ba6841SJoseph Chen uint32_t i; 319*23ba6841SJoseph Chen fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 320*23ba6841SJoseph Chen fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR "=%d\n", 321*23ba6841SJoseph Chen gOpts.major, gOpts.minor); 322*23ba6841SJoseph Chen 323*23ba6841SJoseph Chen fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 324*23ba6841SJoseph Chen for (i = 0; i < gOpts.code471Num; i++) { 325*23ba6841SJoseph Chen fprintf(out, OPT_PATH "%d=%s\n", i + 1, gOpts.code471Path[i]); 326*23ba6841SJoseph Chen } 327*23ba6841SJoseph Chen if (gOpts.code471Sleep > 0) 328*23ba6841SJoseph Chen fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 329*23ba6841SJoseph Chen 330*23ba6841SJoseph Chen fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 331*23ba6841SJoseph Chen for (i = 0; i < gOpts.code472Num; i++) { 332*23ba6841SJoseph Chen fprintf(out, OPT_PATH "%d=%s\n", i + 1, gOpts.code472Path[i]); 333*23ba6841SJoseph Chen } 334*23ba6841SJoseph Chen if (gOpts.code472Sleep > 0) 335*23ba6841SJoseph Chen fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 336*23ba6841SJoseph Chen 337*23ba6841SJoseph Chen fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 338*23ba6841SJoseph Chen for (i = 0; i < gOpts.loaderNum; i++) { 339*23ba6841SJoseph Chen fprintf(out, OPT_LOADER_NAME "%d=%s\n", i + 1, gOpts.loader[i].name); 340*23ba6841SJoseph Chen } 341*23ba6841SJoseph Chen for (i = 0; i < gOpts.loaderNum; i++) { 342*23ba6841SJoseph Chen fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 343*23ba6841SJoseph Chen } 344*23ba6841SJoseph Chen 345*23ba6841SJoseph Chen fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 346*23ba6841SJoseph Chen } 347*23ba6841SJoseph Chen 348*23ba6841SJoseph Chen static bool parseOpts_from_file(void) 349*23ba6841SJoseph Chen { 350*23ba6841SJoseph Chen bool ret = false; 351*23ba6841SJoseph Chen bool chipOk = false; 352*23ba6841SJoseph Chen bool versionOk = false; 353*23ba6841SJoseph Chen bool code471Ok = true; 354*23ba6841SJoseph Chen bool code472Ok = true; 355*23ba6841SJoseph Chen bool loaderOk = false; 356*23ba6841SJoseph Chen bool outOk = false; 357*23ba6841SJoseph Chen char buf[MAX_LINE_LEN]; 358*23ba6841SJoseph Chen 359*23ba6841SJoseph Chen char *configPath = (gConfigPath == NULL) ? DEF_CONFIG_FILE : gConfigPath; 360*23ba6841SJoseph Chen FILE *file; 361*23ba6841SJoseph Chen file = fopen(configPath, "r"); 362*23ba6841SJoseph Chen if (!file) { 363*23ba6841SJoseph Chen fprintf(stderr, "config(%s) not found!\n", configPath); 364*23ba6841SJoseph Chen if (configPath == (char *)DEF_CONFIG_FILE) { 365*23ba6841SJoseph Chen file = fopen(DEF_CONFIG_FILE, "w"); 366*23ba6841SJoseph Chen if (file) { 367*23ba6841SJoseph Chen fprintf(stderr, "create defconfig\n"); 368*23ba6841SJoseph Chen printOpts(file); 369*23ba6841SJoseph Chen } 370*23ba6841SJoseph Chen } 371*23ba6841SJoseph Chen goto end; 372*23ba6841SJoseph Chen } 373*23ba6841SJoseph Chen 374*23ba6841SJoseph Chen LOGD("start parse\n"); 375*23ba6841SJoseph Chen 376*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 377*23ba6841SJoseph Chen goto end; 378*23ba6841SJoseph Chen } 379*23ba6841SJoseph Chen while (fscanf(file, "%s", buf) == 1) { 380*23ba6841SJoseph Chen if (!strcmp(buf, SEC_CHIP)) { 381*23ba6841SJoseph Chen chipOk = parseChip(file); 382*23ba6841SJoseph Chen if (!chipOk) { 383*23ba6841SJoseph Chen LOGE("parseChip failed!\n"); 384*23ba6841SJoseph Chen goto end; 385*23ba6841SJoseph Chen } 386*23ba6841SJoseph Chen } else if (!strcmp(buf, SEC_VERSION)) { 387*23ba6841SJoseph Chen versionOk = parseVersion(file); 388*23ba6841SJoseph Chen if (!versionOk) { 389*23ba6841SJoseph Chen LOGE("parseVersion failed!\n"); 390*23ba6841SJoseph Chen goto end; 391*23ba6841SJoseph Chen } 392*23ba6841SJoseph Chen } else if (!strcmp(buf, SEC_471)) { 393*23ba6841SJoseph Chen code471Ok = parse471(file); 394*23ba6841SJoseph Chen if (!code471Ok) { 395*23ba6841SJoseph Chen LOGE("parse471 failed!\n"); 396*23ba6841SJoseph Chen goto end; 397*23ba6841SJoseph Chen } 398*23ba6841SJoseph Chen } else if (!strcmp(buf, SEC_472)) { 399*23ba6841SJoseph Chen code472Ok = parse472(file); 400*23ba6841SJoseph Chen if (!code472Ok) { 401*23ba6841SJoseph Chen LOGE("parse472 failed!\n"); 402*23ba6841SJoseph Chen goto end; 403*23ba6841SJoseph Chen } 404*23ba6841SJoseph Chen } else if (!strcmp(buf, SEC_LOADER)) { 405*23ba6841SJoseph Chen loaderOk = parseLoader(file); 406*23ba6841SJoseph Chen if (!loaderOk) { 407*23ba6841SJoseph Chen LOGE("parseLoader failed!\n"); 408*23ba6841SJoseph Chen goto end; 409*23ba6841SJoseph Chen } 410*23ba6841SJoseph Chen } else if (!strcmp(buf, SEC_OUT)) { 411*23ba6841SJoseph Chen outOk = parseOut(file); 412*23ba6841SJoseph Chen if (!outOk) { 413*23ba6841SJoseph Chen LOGE("parseOut failed!\n"); 414*23ba6841SJoseph Chen goto end; 415*23ba6841SJoseph Chen } 416*23ba6841SJoseph Chen } else if (buf[0] == '#') { 417*23ba6841SJoseph Chen continue; 418*23ba6841SJoseph Chen } else { 419*23ba6841SJoseph Chen LOGE("unknown sec: %s!\n", buf); 420*23ba6841SJoseph Chen goto end; 421*23ba6841SJoseph Chen } 422*23ba6841SJoseph Chen if (SCANF_EAT(file) != 0) { 423*23ba6841SJoseph Chen goto end; 424*23ba6841SJoseph Chen } 425*23ba6841SJoseph Chen } 426*23ba6841SJoseph Chen 427*23ba6841SJoseph Chen if (chipOk && versionOk && code471Ok && code472Ok && loaderOk && outOk) 428*23ba6841SJoseph Chen ret = true; 429*23ba6841SJoseph Chen end: 430*23ba6841SJoseph Chen if (file) 431*23ba6841SJoseph Chen fclose(file); 432*23ba6841SJoseph Chen return ret; 433*23ba6841SJoseph Chen } 434*23ba6841SJoseph Chen 435*23ba6841SJoseph Chen static bool parseOpts_from_cmdline(int argc, char **argv) 436*23ba6841SJoseph Chen { 437*23ba6841SJoseph Chen int i; 438*23ba6841SJoseph Chen int tag = 0; 439*23ba6841SJoseph Chen int v0, v1, v2, v3; 440*23ba6841SJoseph Chen 441*23ba6841SJoseph Chen for (i = 2; i < argc; i++) { 442*23ba6841SJoseph Chen if (!strcmp(OPT_471, argv[i])) { 443*23ba6841SJoseph Chen i++; 444*23ba6841SJoseph Chen snprintf(gOpts.code471Path[0], sizeof(gOpts.code471Path[0]), "%s", 445*23ba6841SJoseph Chen argv[i]); 446*23ba6841SJoseph Chen tag |= 1; 447*23ba6841SJoseph Chen } else if (!strcmp(OPT_472, argv[i])) { 448*23ba6841SJoseph Chen i++; 449*23ba6841SJoseph Chen snprintf(gOpts.code472Path[0], sizeof(gOpts.code472Path[0]), "%s", 450*23ba6841SJoseph Chen argv[i]); 451*23ba6841SJoseph Chen tag |= 2; 452*23ba6841SJoseph Chen } else if (!strcmp(OPT_DATA, argv[i])) { 453*23ba6841SJoseph Chen i++; 454*23ba6841SJoseph Chen snprintf(gOpts.loader[0].path, sizeof(gOpts.loader[0].path), "%s", 455*23ba6841SJoseph Chen argv[i]); 456*23ba6841SJoseph Chen tag |= 4; 457*23ba6841SJoseph Chen } else if (!strcmp(OPT_BOOT, argv[i])) { 458*23ba6841SJoseph Chen i++; 459*23ba6841SJoseph Chen snprintf(gOpts.loader[1].path, sizeof(gOpts.loader[1].path), "%s", 460*23ba6841SJoseph Chen argv[i]); 461*23ba6841SJoseph Chen tag |= 8; 462*23ba6841SJoseph Chen } else if (!strcmp(OPT_OUT, argv[i])) { 463*23ba6841SJoseph Chen i++; 464*23ba6841SJoseph Chen snprintf(gOpts.outPath, sizeof(gOpts.outPath), "%s", argv[i]); 465*23ba6841SJoseph Chen tag |= 0x10; 466*23ba6841SJoseph Chen } else if (!strcmp(OPT_CHIP, argv[i])) { 467*23ba6841SJoseph Chen i++; 468*23ba6841SJoseph Chen snprintf(gOpts.chip, sizeof(gOpts.chip), "%s", argv[i]); 469*23ba6841SJoseph Chen tag |= 0x20; 470*23ba6841SJoseph Chen } else if (!strcmp(OPT_VERSION, argv[i])) { 471*23ba6841SJoseph Chen } 472*23ba6841SJoseph Chen } 473*23ba6841SJoseph Chen 474*23ba6841SJoseph Chen sscanf(gOpts.loader[0].path, "%*[^v]v%d.%d.bin", &v0, &v1); 475*23ba6841SJoseph Chen sscanf(gOpts.loader[1].path, "%*[^v]v%d.%d.bin", &v2, &v3); 476*23ba6841SJoseph Chen gOpts.major = v2; 477*23ba6841SJoseph Chen gOpts.minor = v3; 478*23ba6841SJoseph Chen snprintf(gOpts.outPath, sizeof(gOpts.outPath), 479*23ba6841SJoseph Chen "%s_loader_v%d.%02d.%d%02d.bin", gOpts.chip, v0, v1, v2, v3); 480*23ba6841SJoseph Chen return ((tag & 0x0f) == 0x0f) ? true : false; 481*23ba6841SJoseph Chen } 482*23ba6841SJoseph Chen 483*23ba6841SJoseph Chen bool initOpts(int argc, char **argv) 484*23ba6841SJoseph Chen { 485*23ba6841SJoseph Chen bool ret; 486*23ba6841SJoseph Chen 487*23ba6841SJoseph Chen /* set default opts */ 488*23ba6841SJoseph Chen gOpts.major = DEF_MAJOR; 489*23ba6841SJoseph Chen gOpts.minor = DEF_MINOR; 490*23ba6841SJoseph Chen strcpy(gOpts.chip, DEF_CHIP); 491*23ba6841SJoseph Chen gOpts.code471Sleep = DEF_CODE471_SLEEP; 492*23ba6841SJoseph Chen gOpts.code472Sleep = DEF_CODE472_SLEEP; 493*23ba6841SJoseph Chen gOpts.code471Num = DEF_CODE471_NUM; 494*23ba6841SJoseph Chen gOpts.code471Path = (line_t *)malloc(sizeof(line_t) * gOpts.code471Num); 495*23ba6841SJoseph Chen strcpy((char *)gOpts.code471Path[0], DEF_CODE471_PATH); 496*23ba6841SJoseph Chen gOpts.code472Num = DEF_CODE472_NUM; 497*23ba6841SJoseph Chen gOpts.code472Path = (line_t *)malloc(sizeof(line_t) * gOpts.code472Num); 498*23ba6841SJoseph Chen strcpy((char *)gOpts.code472Path[0], DEF_CODE472_PATH); 499*23ba6841SJoseph Chen gOpts.loaderNum = DEF_LOADER_NUM; 500*23ba6841SJoseph Chen gOpts.loader = (name_entry *)malloc(sizeof(name_entry) * gOpts.loaderNum); 501*23ba6841SJoseph Chen strcpy(gOpts.loader[0].name, DEF_LOADER0); 502*23ba6841SJoseph Chen strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 503*23ba6841SJoseph Chen strcpy(gOpts.loader[1].name, DEF_LOADER1); 504*23ba6841SJoseph Chen strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 505*23ba6841SJoseph Chen strcpy(gOpts.outPath, DEF_OUT_PATH); 506*23ba6841SJoseph Chen 507*23ba6841SJoseph Chen if (argc > 10) 508*23ba6841SJoseph Chen ret = parseOpts_from_cmdline(argc, argv); 509*23ba6841SJoseph Chen else 510*23ba6841SJoseph Chen ret = parseOpts_from_file(); 511*23ba6841SJoseph Chen 512*23ba6841SJoseph Chen return ret; 513*23ba6841SJoseph Chen } 514*23ba6841SJoseph Chen 515*23ba6841SJoseph Chen /************merge code****************/ 516*23ba6841SJoseph Chen 517*23ba6841SJoseph Chen static inline uint32_t getBCD(unsigned short value) 518*23ba6841SJoseph Chen { 519*23ba6841SJoseph Chen uint8_t tmp[2] = { 0 }; 520*23ba6841SJoseph Chen int i; 521*23ba6841SJoseph Chen uint32_t ret; 522*23ba6841SJoseph Chen if (value > 0xFFFF) { 523*23ba6841SJoseph Chen return 0; 524*23ba6841SJoseph Chen } 525*23ba6841SJoseph Chen for (i = 0; i < 2; i++) { 526*23ba6841SJoseph Chen tmp[i] = (((value / 10) % 10) << 4) | (value % 10); 527*23ba6841SJoseph Chen value /= 100; 528*23ba6841SJoseph Chen } 529*23ba6841SJoseph Chen ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 530*23ba6841SJoseph Chen 531*23ba6841SJoseph Chen LOGD("ret:%x\n", ret); 532*23ba6841SJoseph Chen return ret & 0xFF; 533*23ba6841SJoseph Chen } 534*23ba6841SJoseph Chen 535*23ba6841SJoseph Chen static inline void str2wide(const char *str, uint16_t *wide, int len) 536*23ba6841SJoseph Chen { 537*23ba6841SJoseph Chen int i; 538*23ba6841SJoseph Chen for (i = 0; i < len; i++) { 539*23ba6841SJoseph Chen wide[i] = (uint16_t) str[i]; 540*23ba6841SJoseph Chen } 541*23ba6841SJoseph Chen wide[len] = 0; 542*23ba6841SJoseph Chen } 543*23ba6841SJoseph Chen 544*23ba6841SJoseph Chen static inline void getName(char *path, uint16_t *dst) 545*23ba6841SJoseph Chen { 546*23ba6841SJoseph Chen char *end; 547*23ba6841SJoseph Chen char *start; 548*23ba6841SJoseph Chen int len; 549*23ba6841SJoseph Chen if (!path || !dst) 550*23ba6841SJoseph Chen return; 551*23ba6841SJoseph Chen start = strrchr(path, '/'); 552*23ba6841SJoseph Chen if (!start) 553*23ba6841SJoseph Chen start = path; 554*23ba6841SJoseph Chen else 555*23ba6841SJoseph Chen start++; 556*23ba6841SJoseph Chen end = strrchr(path, '.'); 557*23ba6841SJoseph Chen if (!end) 558*23ba6841SJoseph Chen end = path + strlen(path); 559*23ba6841SJoseph Chen len = end - start; 560*23ba6841SJoseph Chen if (len >= MAX_NAME_LEN) 561*23ba6841SJoseph Chen len = MAX_NAME_LEN - 1; 562*23ba6841SJoseph Chen str2wide(start, dst, len); 563*23ba6841SJoseph Chen 564*23ba6841SJoseph Chen if (gDebug) { 565*23ba6841SJoseph Chen char name[MAX_NAME_LEN]; 566*23ba6841SJoseph Chen memset(name, 0, sizeof(name)); 567*23ba6841SJoseph Chen memcpy(name, start, len); 568*23ba6841SJoseph Chen LOGD("path:%s, name:%s\n", path, name); 569*23ba6841SJoseph Chen } 570*23ba6841SJoseph Chen } 571*23ba6841SJoseph Chen 572*23ba6841SJoseph Chen static inline bool getFileSize(const char *path, uint32_t *size) 573*23ba6841SJoseph Chen { 574*23ba6841SJoseph Chen struct stat st; 575*23ba6841SJoseph Chen if (stat(path, &st) < 0) 576*23ba6841SJoseph Chen return false; 577*23ba6841SJoseph Chen *size = st.st_size; 578*23ba6841SJoseph Chen LOGD("path:%s, size:%d\n", path, *size); 579*23ba6841SJoseph Chen return true; 580*23ba6841SJoseph Chen } 581*23ba6841SJoseph Chen 582*23ba6841SJoseph Chen static inline rk_time getTime(void) 583*23ba6841SJoseph Chen { 584*23ba6841SJoseph Chen rk_time rkTime; 585*23ba6841SJoseph Chen 586*23ba6841SJoseph Chen struct tm *tm; 587*23ba6841SJoseph Chen time_t tt = time(NULL); 588*23ba6841SJoseph Chen tm = localtime(&tt); 589*23ba6841SJoseph Chen rkTime.year = tm->tm_year + 1900; 590*23ba6841SJoseph Chen rkTime.month = tm->tm_mon + 1; 591*23ba6841SJoseph Chen rkTime.day = tm->tm_mday; 592*23ba6841SJoseph Chen rkTime.hour = tm->tm_hour; 593*23ba6841SJoseph Chen rkTime.minute = tm->tm_min; 594*23ba6841SJoseph Chen rkTime.second = tm->tm_sec; 595*23ba6841SJoseph Chen LOGD("%d-%d-%d %02d:%02d:%02d\n", rkTime.year, rkTime.month, rkTime.day, 596*23ba6841SJoseph Chen rkTime.hour, rkTime.minute, rkTime.second); 597*23ba6841SJoseph Chen return rkTime; 598*23ba6841SJoseph Chen } 599*23ba6841SJoseph Chen 600*23ba6841SJoseph Chen static bool writeFile(FILE *outFile, const char *path, bool fix) 601*23ba6841SJoseph Chen { 602*23ba6841SJoseph Chen bool ret = false; 603*23ba6841SJoseph Chen uint32_t size = 0, fixSize = 0; 604*23ba6841SJoseph Chen uint8_t *buf; 605*23ba6841SJoseph Chen 606*23ba6841SJoseph Chen FILE *inFile = fopen(path, "rb"); 607*23ba6841SJoseph Chen if (!inFile) 608*23ba6841SJoseph Chen goto end; 609*23ba6841SJoseph Chen 610*23ba6841SJoseph Chen if (!getFileSize(path, &size)) 611*23ba6841SJoseph Chen goto end; 612*23ba6841SJoseph Chen if (fix) { 613*23ba6841SJoseph Chen fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 614*23ba6841SJoseph Chen uint32_t tmp = fixSize % ENTRY_ALIGN; 615*23ba6841SJoseph Chen tmp = tmp ? (ENTRY_ALIGN - tmp) : 0; 616*23ba6841SJoseph Chen fixSize += tmp; 617*23ba6841SJoseph Chen memset(gBuf, 0, fixSize); 618*23ba6841SJoseph Chen } else { 619*23ba6841SJoseph Chen memset(gBuf, 0, size + ENTRY_ALIGN); 620*23ba6841SJoseph Chen } 621*23ba6841SJoseph Chen if (!fread(gBuf, size, 1, inFile)) 622*23ba6841SJoseph Chen goto end; 623*23ba6841SJoseph Chen 624*23ba6841SJoseph Chen if (fix) { 625*23ba6841SJoseph Chen 626*23ba6841SJoseph Chen buf = gBuf; 627*23ba6841SJoseph Chen size = fixSize; 628*23ba6841SJoseph Chen while (1) { 629*23ba6841SJoseph Chen P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 630*23ba6841SJoseph Chen buf += SMALL_PACKET; 631*23ba6841SJoseph Chen if (fixSize <= SMALL_PACKET) 632*23ba6841SJoseph Chen break; 633*23ba6841SJoseph Chen fixSize -= SMALL_PACKET; 634*23ba6841SJoseph Chen } 635*23ba6841SJoseph Chen } else { 636*23ba6841SJoseph Chen uint32_t tmp = size % ENTRY_ALIGN; 637*23ba6841SJoseph Chen tmp = tmp ? (ENTRY_ALIGN - tmp) : 0; 638*23ba6841SJoseph Chen size += tmp; 639*23ba6841SJoseph Chen P_RC4(gBuf, size); 640*23ba6841SJoseph Chen } 641*23ba6841SJoseph Chen 642*23ba6841SJoseph Chen if (!fwrite(gBuf, size, 1, outFile)) 643*23ba6841SJoseph Chen goto end; 644*23ba6841SJoseph Chen ret = true; 645*23ba6841SJoseph Chen end: 646*23ba6841SJoseph Chen if (inFile) 647*23ba6841SJoseph Chen fclose(inFile); 648*23ba6841SJoseph Chen if (!ret) 649*23ba6841SJoseph Chen LOGE("write entry(%s) failed\n", path); 650*23ba6841SJoseph Chen return ret; 651*23ba6841SJoseph Chen } 652*23ba6841SJoseph Chen 653*23ba6841SJoseph Chen static bool saveEntry(FILE *outFile, char *path, rk_entry_type type, 654*23ba6841SJoseph Chen uint16_t delay, uint32_t *offset, char *fixName, 655*23ba6841SJoseph Chen bool fix) 656*23ba6841SJoseph Chen { 657*23ba6841SJoseph Chen LOGD("write:%s\n", path); 658*23ba6841SJoseph Chen uint32_t size; 659*23ba6841SJoseph Chen rk_boot_entry entry; 660*23ba6841SJoseph Chen memset(&entry, 0, sizeof(rk_boot_entry)); 661*23ba6841SJoseph Chen 662*23ba6841SJoseph Chen LOGD("write:%s\n", path); 663*23ba6841SJoseph Chen 664*23ba6841SJoseph Chen getName(fixName ? fixName : path, entry.name); 665*23ba6841SJoseph Chen entry.size = sizeof(rk_boot_entry); 666*23ba6841SJoseph Chen entry.type = type; 667*23ba6841SJoseph Chen entry.dataOffset = *offset; 668*23ba6841SJoseph Chen if (!getFileSize(path, &size)) { 669*23ba6841SJoseph Chen LOGE("save entry(%s) failed:\n\tcannot get file size.\n", path); 670*23ba6841SJoseph Chen return false; 671*23ba6841SJoseph Chen } 672*23ba6841SJoseph Chen if (fix) 673*23ba6841SJoseph Chen size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 674*23ba6841SJoseph Chen uint32_t tmp = size % ENTRY_ALIGN; 675*23ba6841SJoseph Chen size += tmp ? (ENTRY_ALIGN - tmp) : 0; 676*23ba6841SJoseph Chen LOGD("align size:%d\n", size); 677*23ba6841SJoseph Chen entry.dataSize = size; 678*23ba6841SJoseph Chen entry.dataDelay = delay; 679*23ba6841SJoseph Chen *offset += size; 680*23ba6841SJoseph Chen fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 681*23ba6841SJoseph Chen return true; 682*23ba6841SJoseph Chen } 683*23ba6841SJoseph Chen 684*23ba6841SJoseph Chen static inline uint32_t convertChipType(const char *chip) 685*23ba6841SJoseph Chen { 686*23ba6841SJoseph Chen char buffer[5]; 687*23ba6841SJoseph Chen memset(buffer, 0, sizeof(buffer)); 688*23ba6841SJoseph Chen snprintf(buffer, sizeof(buffer), "%s", chip); 689*23ba6841SJoseph Chen return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 690*23ba6841SJoseph Chen } 691*23ba6841SJoseph Chen 692*23ba6841SJoseph Chen static inline uint32_t getChipType(const char *chip) 693*23ba6841SJoseph Chen { 694*23ba6841SJoseph Chen LOGD("chip:%s\n", chip); 695*23ba6841SJoseph Chen int chipType = RKNONE_DEVICE; 696*23ba6841SJoseph Chen if (!chip) { 697*23ba6841SJoseph Chen goto end; 698*23ba6841SJoseph Chen } 699*23ba6841SJoseph Chen if (!strcmp(chip, CHIP_RK28)) { 700*23ba6841SJoseph Chen chipType = RK28_DEVICE; 701*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK28)) { 702*23ba6841SJoseph Chen chipType = RK28_DEVICE; 703*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK281X)) { 704*23ba6841SJoseph Chen chipType = RK281X_DEVICE; 705*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RKPANDA)) { 706*23ba6841SJoseph Chen chipType = RKPANDA_DEVICE; 707*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK27)) { 708*23ba6841SJoseph Chen chipType = RK27_DEVICE; 709*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RKNANO)) { 710*23ba6841SJoseph Chen chipType = RKNANO_DEVICE; 711*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RKSMART)) { 712*23ba6841SJoseph Chen chipType = RKSMART_DEVICE; 713*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RKCROWN)) { 714*23ba6841SJoseph Chen chipType = RKCROWN_DEVICE; 715*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 716*23ba6841SJoseph Chen chipType = RKCAYMAN_DEVICE; 717*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK29)) { 718*23ba6841SJoseph Chen chipType = RK29_DEVICE; 719*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK292X)) { 720*23ba6841SJoseph Chen chipType = RK292X_DEVICE; 721*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK30)) { 722*23ba6841SJoseph Chen chipType = RK30_DEVICE; 723*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK30B)) { 724*23ba6841SJoseph Chen chipType = RK30B_DEVICE; 725*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK31)) { 726*23ba6841SJoseph Chen chipType = RK31_DEVICE; 727*23ba6841SJoseph Chen } else if (!strcmp(chip, CHIP_RK32)) { 728*23ba6841SJoseph Chen chipType = RK32_DEVICE; 729*23ba6841SJoseph Chen } else { 730*23ba6841SJoseph Chen chipType = convertChipType(chip + 2); 731*23ba6841SJoseph Chen } 732*23ba6841SJoseph Chen 733*23ba6841SJoseph Chen end: 734*23ba6841SJoseph Chen LOGD("type:0x%x\n", chipType); 735*23ba6841SJoseph Chen if (chipType == RKNONE_DEVICE) { 736*23ba6841SJoseph Chen LOGE("chip type not support!\n"); 737*23ba6841SJoseph Chen } 738*23ba6841SJoseph Chen return chipType; 739*23ba6841SJoseph Chen } 740*23ba6841SJoseph Chen 741*23ba6841SJoseph Chen static inline void getBoothdr(rk_boot_header *hdr) 742*23ba6841SJoseph Chen { 743*23ba6841SJoseph Chen memset(hdr, 0, sizeof(rk_boot_header)); 744*23ba6841SJoseph Chen hdr->tag = TAG; 745*23ba6841SJoseph Chen hdr->size = sizeof(rk_boot_header); 746*23ba6841SJoseph Chen hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 747*23ba6841SJoseph Chen hdr->mergerVersion = MERGER_VERSION; 748*23ba6841SJoseph Chen hdr->releaseTime = getTime(); 749*23ba6841SJoseph Chen hdr->chipType = getChipType(gOpts.chip); 750*23ba6841SJoseph Chen 751*23ba6841SJoseph Chen hdr->code471Num = gOpts.code471Num; 752*23ba6841SJoseph Chen hdr->code471Offset = sizeof(rk_boot_header); 753*23ba6841SJoseph Chen hdr->code471Size = sizeof(rk_boot_entry); 754*23ba6841SJoseph Chen 755*23ba6841SJoseph Chen hdr->code472Num = gOpts.code472Num; 756*23ba6841SJoseph Chen hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 757*23ba6841SJoseph Chen hdr->code472Size = sizeof(rk_boot_entry); 758*23ba6841SJoseph Chen 759*23ba6841SJoseph Chen hdr->loaderNum = gOpts.loaderNum; 760*23ba6841SJoseph Chen hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 761*23ba6841SJoseph Chen hdr->loaderSize = sizeof(rk_boot_entry); 762*23ba6841SJoseph Chen #ifndef USE_P_RC4 763*23ba6841SJoseph Chen hdr->rc4Flag = 1; 764*23ba6841SJoseph Chen #endif 765*23ba6841SJoseph Chen } 766*23ba6841SJoseph Chen 767*23ba6841SJoseph Chen static inline uint32_t getCrc(const char *path) 768*23ba6841SJoseph Chen { 769*23ba6841SJoseph Chen uint32_t size = 0; 770*23ba6841SJoseph Chen uint32_t crc = 0; 771*23ba6841SJoseph Chen FILE *file = fopen(path, "rb"); 772*23ba6841SJoseph Chen getFileSize(path, &size); 773*23ba6841SJoseph Chen if (!file) 774*23ba6841SJoseph Chen goto end; 775*23ba6841SJoseph Chen if (!fread(gBuf, size, 1, file)) 776*23ba6841SJoseph Chen goto end; 777*23ba6841SJoseph Chen crc = CRC_32(gBuf, size); 778*23ba6841SJoseph Chen LOGD("crc:0x%08x\n", crc); 779*23ba6841SJoseph Chen end: 780*23ba6841SJoseph Chen if (file) 781*23ba6841SJoseph Chen fclose(file); 782*23ba6841SJoseph Chen return crc; 783*23ba6841SJoseph Chen } 784*23ba6841SJoseph Chen 785*23ba6841SJoseph Chen static bool mergeBoot(int argc, char **argv) 786*23ba6841SJoseph Chen { 787*23ba6841SJoseph Chen uint32_t dataOffset; 788*23ba6841SJoseph Chen bool ret = false; 789*23ba6841SJoseph Chen int i; 790*23ba6841SJoseph Chen FILE *outFile; 791*23ba6841SJoseph Chen uint32_t crc; 792*23ba6841SJoseph Chen rk_boot_header hdr; 793*23ba6841SJoseph Chen 794*23ba6841SJoseph Chen if (!initOpts(argc, argv)) 795*23ba6841SJoseph Chen return false; 796*23ba6841SJoseph Chen { 797*23ba6841SJoseph Chen char *subfix = strstr(gOpts.outPath, OUT_SUBFIX); 798*23ba6841SJoseph Chen char version[MAX_LINE_LEN]; 799*23ba6841SJoseph Chen snprintf(version, sizeof(version), "%s", gSubfix); 800*23ba6841SJoseph Chen if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 801*23ba6841SJoseph Chen subfix[0] = '\0'; 802*23ba6841SJoseph Chen } 803*23ba6841SJoseph Chen strcat(gOpts.outPath, version); 804*23ba6841SJoseph Chen printf("fix opt:%s\n", gOpts.outPath); 805*23ba6841SJoseph Chen } 806*23ba6841SJoseph Chen 807*23ba6841SJoseph Chen if (gDebug) { 808*23ba6841SJoseph Chen printf("---------------\nUSING CONFIG:\n"); 809*23ba6841SJoseph Chen printOpts(stdout); 810*23ba6841SJoseph Chen printf("---------------\n\n"); 811*23ba6841SJoseph Chen } 812*23ba6841SJoseph Chen 813*23ba6841SJoseph Chen outFile = fopen(gOpts.outPath, "wb+"); 814*23ba6841SJoseph Chen if (!outFile) { 815*23ba6841SJoseph Chen LOGE("open out file(%s) failed\n", gOpts.outPath); 816*23ba6841SJoseph Chen goto end; 817*23ba6841SJoseph Chen } 818*23ba6841SJoseph Chen 819*23ba6841SJoseph Chen getBoothdr(&hdr); 820*23ba6841SJoseph Chen LOGD("write hdr\n"); 821*23ba6841SJoseph Chen fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 822*23ba6841SJoseph Chen 823*23ba6841SJoseph Chen dataOffset = sizeof(rk_boot_header) + 824*23ba6841SJoseph Chen (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 825*23ba6841SJoseph Chen sizeof(rk_boot_entry); 826*23ba6841SJoseph Chen 827*23ba6841SJoseph Chen LOGD("write code 471 entry\n"); 828*23ba6841SJoseph Chen for (i = 0; i < gOpts.code471Num; i++) { 829*23ba6841SJoseph Chen if (!saveEntry(outFile, (char *)gOpts.code471Path[i], ENTRY_471, 830*23ba6841SJoseph Chen gOpts.code471Sleep, &dataOffset, NULL, false)) 831*23ba6841SJoseph Chen goto end; 832*23ba6841SJoseph Chen } 833*23ba6841SJoseph Chen LOGD("write code 472 entry\n"); 834*23ba6841SJoseph Chen for (i = 0; i < gOpts.code472Num; i++) { 835*23ba6841SJoseph Chen if (!saveEntry(outFile, (char *)gOpts.code472Path[i], ENTRY_472, 836*23ba6841SJoseph Chen gOpts.code472Sleep, &dataOffset, NULL, false)) 837*23ba6841SJoseph Chen goto end; 838*23ba6841SJoseph Chen } 839*23ba6841SJoseph Chen LOGD("write loader entry\n"); 840*23ba6841SJoseph Chen for (i = 0; i < gOpts.loaderNum; i++) { 841*23ba6841SJoseph Chen if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, &dataOffset, 842*23ba6841SJoseph Chen gOpts.loader[i].name, true)) 843*23ba6841SJoseph Chen goto end; 844*23ba6841SJoseph Chen } 845*23ba6841SJoseph Chen 846*23ba6841SJoseph Chen LOGD("write code 471\n"); 847*23ba6841SJoseph Chen for (i = 0; i < gOpts.code471Num; i++) { 848*23ba6841SJoseph Chen if (!writeFile(outFile, (char *)gOpts.code471Path[i], false)) 849*23ba6841SJoseph Chen goto end; 850*23ba6841SJoseph Chen } 851*23ba6841SJoseph Chen LOGD("write code 472\n"); 852*23ba6841SJoseph Chen for (i = 0; i < gOpts.code472Num; i++) { 853*23ba6841SJoseph Chen if (!writeFile(outFile, (char *)gOpts.code472Path[i], false)) 854*23ba6841SJoseph Chen goto end; 855*23ba6841SJoseph Chen } 856*23ba6841SJoseph Chen LOGD("write loader\n"); 857*23ba6841SJoseph Chen for (i = 0; i < gOpts.loaderNum; i++) { 858*23ba6841SJoseph Chen if (!writeFile(outFile, gOpts.loader[i].path, true)) 859*23ba6841SJoseph Chen goto end; 860*23ba6841SJoseph Chen } 861*23ba6841SJoseph Chen fflush(outFile); 862*23ba6841SJoseph Chen 863*23ba6841SJoseph Chen LOGD("write crc\n"); 864*23ba6841SJoseph Chen crc = getCrc(gOpts.outPath); 865*23ba6841SJoseph Chen if (!fwrite(&crc, sizeof(crc), 1, outFile)) 866*23ba6841SJoseph Chen goto end; 867*23ba6841SJoseph Chen 868*23ba6841SJoseph Chen ret = true; 869*23ba6841SJoseph Chen end: 870*23ba6841SJoseph Chen if (outFile) 871*23ba6841SJoseph Chen fclose(outFile); 872*23ba6841SJoseph Chen return ret; 873*23ba6841SJoseph Chen } 874*23ba6841SJoseph Chen 875*23ba6841SJoseph Chen /************merge code end************/ 876*23ba6841SJoseph Chen /************unpack code***************/ 877*23ba6841SJoseph Chen 878*23ba6841SJoseph Chen static inline void wide2str(const uint16_t *wide, char *str, int len) 879*23ba6841SJoseph Chen { 880*23ba6841SJoseph Chen int i; 881*23ba6841SJoseph Chen for (i = 0; i < len; i++) { 882*23ba6841SJoseph Chen str[i] = (char)(wide[i] & 0xFF); 883*23ba6841SJoseph Chen } 884*23ba6841SJoseph Chen str[len] = 0; 885*23ba6841SJoseph Chen } 886*23ba6841SJoseph Chen 887*23ba6841SJoseph Chen static bool unpackEntry(rk_boot_entry *entry, const char *name, FILE *inFile) 888*23ba6841SJoseph Chen { 889*23ba6841SJoseph Chen bool ret = false; 890*23ba6841SJoseph Chen int size, i; 891*23ba6841SJoseph Chen FILE *outFile = fopen(name, "wb+"); 892*23ba6841SJoseph Chen if (!outFile) 893*23ba6841SJoseph Chen goto end; 894*23ba6841SJoseph Chen printf("unpack entry(%s)\n", name); 895*23ba6841SJoseph Chen fseek(inFile, entry->dataOffset, SEEK_SET); 896*23ba6841SJoseph Chen size = entry->dataSize; 897*23ba6841SJoseph Chen if (!fread(gBuf, size, 1, inFile)) 898*23ba6841SJoseph Chen goto end; 899*23ba6841SJoseph Chen if (entry->type == ENTRY_LOADER) { 900*23ba6841SJoseph Chen for (i = 0; i < size / SMALL_PACKET; i++) 901*23ba6841SJoseph Chen P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 902*23ba6841SJoseph Chen if (size % SMALL_PACKET) { 903*23ba6841SJoseph Chen P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 904*23ba6841SJoseph Chen } 905*23ba6841SJoseph Chen } else { 906*23ba6841SJoseph Chen P_RC4(gBuf, size); 907*23ba6841SJoseph Chen } 908*23ba6841SJoseph Chen if (!fwrite(gBuf, size, 1, outFile)) 909*23ba6841SJoseph Chen goto end; 910*23ba6841SJoseph Chen ret = true; 911*23ba6841SJoseph Chen end: 912*23ba6841SJoseph Chen if (outFile) 913*23ba6841SJoseph Chen fclose(outFile); 914*23ba6841SJoseph Chen return ret; 915*23ba6841SJoseph Chen } 916*23ba6841SJoseph Chen 917*23ba6841SJoseph Chen static bool unpackBoot(char *path) 918*23ba6841SJoseph Chen { 919*23ba6841SJoseph Chen bool ret = false; 920*23ba6841SJoseph Chen FILE *inFile = fopen(path, "rb"); 921*23ba6841SJoseph Chen int entryNum, i; 922*23ba6841SJoseph Chen char name[MAX_NAME_LEN]; 923*23ba6841SJoseph Chen rk_boot_entry *entrys; 924*23ba6841SJoseph Chen if (!inFile) { 925*23ba6841SJoseph Chen fprintf(stderr, "loader(%s) not found\n", path); 926*23ba6841SJoseph Chen goto end; 927*23ba6841SJoseph Chen } 928*23ba6841SJoseph Chen 929*23ba6841SJoseph Chen rk_boot_header hdr; 930*23ba6841SJoseph Chen if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 931*23ba6841SJoseph Chen fprintf(stderr, "read header failed\n"); 932*23ba6841SJoseph Chen goto end; 933*23ba6841SJoseph Chen } 934*23ba6841SJoseph Chen 935*23ba6841SJoseph Chen entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 936*23ba6841SJoseph Chen entrys = (rk_boot_entry *)malloc(sizeof(rk_boot_entry) * entryNum); 937*23ba6841SJoseph Chen if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 938*23ba6841SJoseph Chen fprintf(stderr, "read data failed\n"); 939*23ba6841SJoseph Chen goto end; 940*23ba6841SJoseph Chen } 941*23ba6841SJoseph Chen 942*23ba6841SJoseph Chen LOGD("entry num:%d\n", entryNum); 943*23ba6841SJoseph Chen for (i = 0; i < entryNum; i++) { 944*23ba6841SJoseph Chen wide2str(entrys[i].name, name, MAX_NAME_LEN); 945*23ba6841SJoseph Chen 946*23ba6841SJoseph Chen LOGD("entry:t=%d, name=%s, off=%d, size=%d\n", entrys[i].type, name, 947*23ba6841SJoseph Chen entrys[i].dataOffset, entrys[i].dataSize); 948*23ba6841SJoseph Chen if (!unpackEntry(entrys + i, name, inFile)) { 949*23ba6841SJoseph Chen fprintf(stderr, "unpack entry(%s) failed\n", name); 950*23ba6841SJoseph Chen goto end; 951*23ba6841SJoseph Chen } 952*23ba6841SJoseph Chen } 953*23ba6841SJoseph Chen 954*23ba6841SJoseph Chen ret = true; 955*23ba6841SJoseph Chen end: 956*23ba6841SJoseph Chen if (inFile) 957*23ba6841SJoseph Chen fclose(inFile); 958*23ba6841SJoseph Chen return ret; 959*23ba6841SJoseph Chen } 960*23ba6841SJoseph Chen 961*23ba6841SJoseph Chen /************unpack code end***********/ 962*23ba6841SJoseph Chen 963*23ba6841SJoseph Chen static void printHelp(void) 964*23ba6841SJoseph Chen { 965*23ba6841SJoseph Chen printf("Usage1: boot_merger [options]... FILE\n"); 966*23ba6841SJoseph Chen printf("Merge or unpack Rockchip's loader (Default action is to merge.)\n"); 967*23ba6841SJoseph Chen printf("Options:\n"); 968*23ba6841SJoseph Chen printf("\t" OPT_MERGE "\t\t\tMerge loader with specified config.\n"); 969*23ba6841SJoseph Chen printf("\t" OPT_UNPACK "\t\tUnpack specified loader to current dir.\n"); 970*23ba6841SJoseph Chen printf("\t" OPT_VERBOSE "\t\tDisplay more runtime informations.\n"); 971*23ba6841SJoseph Chen printf("\t" OPT_HELP "\t\t\tDisplay this information.\n"); 972*23ba6841SJoseph Chen printf("\t" OPT_VERSION "\t\tDisplay version information.\n"); 973*23ba6841SJoseph Chen printf("\t" OPT_SUBFIX "\t\tSpec subfix.\n"); 974*23ba6841SJoseph Chen printf("\t" OPT_REPLACE "\t\tReplace some part of binary path.\n"); 975*23ba6841SJoseph Chen printf("\t" OPT_SIZE 976*23ba6841SJoseph Chen "\t\tImage size.\"--size [image KB size]\", must be 512KB aligned\n"); 977*23ba6841SJoseph Chen printf("Usage2: boot_merger [options] [parameter]\n"); 978*23ba6841SJoseph Chen printf("All below five option are must in this mode!\n"); 979*23ba6841SJoseph Chen printf("\t" OPT_CHIP "\t\tChip type, used for check with usbplug.\n"); 980*23ba6841SJoseph Chen printf("\t" OPT_471 "\t\t471 for download, ddr.bin.\n"); 981*23ba6841SJoseph Chen printf("\t" OPT_472 "\t\t472 for download, usbplug.bin.\n"); 982*23ba6841SJoseph Chen printf("\t" OPT_DATA "\t\tloader0 for flash, ddr.bin.\n"); 983*23ba6841SJoseph Chen printf("\t" OPT_BOOT "\t\tloader1 for flash, miniloader.bin.\n"); 984*23ba6841SJoseph Chen printf("\n./tools/boot_merger --pack --verbose -c RK322A -1 " 985*23ba6841SJoseph Chen "rkbin/rk322x_ddr_300MHz_v1.04.bin -2 " 986*23ba6841SJoseph Chen "rkbin/rk32/rk322x_usbplug_v2.32.bin -d " 987*23ba6841SJoseph Chen "rkbin/rk32/rk322x_ddr_300MHz_v1.04.bin -b " 988*23ba6841SJoseph Chen "rkbin/rk32/rk322x_miniloader_v2.32.bin\n"); 989*23ba6841SJoseph Chen } 990*23ba6841SJoseph Chen 991*23ba6841SJoseph Chen int main(int argc, char **argv) 992*23ba6841SJoseph Chen { 993*23ba6841SJoseph Chen 994*23ba6841SJoseph Chen int i; 995*23ba6841SJoseph Chen bool merge = true; 996*23ba6841SJoseph Chen char *optPath = NULL; 997*23ba6841SJoseph Chen 998*23ba6841SJoseph Chen for (i = 1; i < argc; i++) { 999*23ba6841SJoseph Chen if (!strcmp(OPT_VERBOSE, argv[i])) { 1000*23ba6841SJoseph Chen gDebug = true; 1001*23ba6841SJoseph Chen printf("enable debug\n"); 1002*23ba6841SJoseph Chen } else if (!strcmp(OPT_HELP, argv[i])) { 1003*23ba6841SJoseph Chen printHelp(); 1004*23ba6841SJoseph Chen return 0; 1005*23ba6841SJoseph Chen } else if (!strcmp(OPT_VERSION, argv[i])) { 1006*23ba6841SJoseph Chen printf("boot_merger (cjf@rock-chips.com)\t" VERSION "\n"); 1007*23ba6841SJoseph Chen return 0; 1008*23ba6841SJoseph Chen } else if (!strcmp(OPT_MERGE, argv[i])) { 1009*23ba6841SJoseph Chen merge = true; 1010*23ba6841SJoseph Chen } else if (!strcmp(OPT_UNPACK, argv[i])) { 1011*23ba6841SJoseph Chen merge = false; 1012*23ba6841SJoseph Chen } else if (!strcmp(OPT_SUBFIX, argv[i])) { 1013*23ba6841SJoseph Chen i++; 1014*23ba6841SJoseph Chen snprintf(gSubfix, sizeof(gSubfix), "%s", argv[i]); 1015*23ba6841SJoseph Chen } else if (!strcmp(OPT_REPLACE, argv[i])) { 1016*23ba6841SJoseph Chen i++; 1017*23ba6841SJoseph Chen snprintf(gLegacyPath, sizeof(gLegacyPath), "%s", argv[i]); 1018*23ba6841SJoseph Chen i++; 1019*23ba6841SJoseph Chen snprintf(gNewPath, sizeof(gNewPath), "%s", argv[i]); 1020*23ba6841SJoseph Chen } else if (!strcmp(OPT_SIZE, argv[i])) { 1021*23ba6841SJoseph Chen g_merge_max_size = strtoul(argv[++i], NULL, 10); 1022*23ba6841SJoseph Chen if (g_merge_max_size % 512) { 1023*23ba6841SJoseph Chen printHelp(); 1024*23ba6841SJoseph Chen return -1; 1025*23ba6841SJoseph Chen } 1026*23ba6841SJoseph Chen g_merge_max_size *= 1024; /* bytes */ 1027*23ba6841SJoseph Chen } else { 1028*23ba6841SJoseph Chen optPath = argv[i]; 1029*23ba6841SJoseph Chen break; 1030*23ba6841SJoseph Chen } 1031*23ba6841SJoseph Chen } 1032*23ba6841SJoseph Chen if (!merge && !optPath) { 1033*23ba6841SJoseph Chen fprintf(stderr, "need set out path to unpack!\n"); 1034*23ba6841SJoseph Chen printHelp(); 1035*23ba6841SJoseph Chen return -1; 1036*23ba6841SJoseph Chen } 1037*23ba6841SJoseph Chen 1038*23ba6841SJoseph Chen gBuf = calloc(g_merge_max_size, 1); 1039*23ba6841SJoseph Chen if (!gBuf) { 1040*23ba6841SJoseph Chen LOGE("Merge image: calloc buffer error.\n"); 1041*23ba6841SJoseph Chen return -1; 1042*23ba6841SJoseph Chen } 1043*23ba6841SJoseph Chen 1044*23ba6841SJoseph Chen if (merge) { 1045*23ba6841SJoseph Chen LOGD("do_merge\n"); 1046*23ba6841SJoseph Chen gConfigPath = optPath; 1047*23ba6841SJoseph Chen if (!mergeBoot(argc, argv)) { 1048*23ba6841SJoseph Chen fprintf(stderr, "merge failed!\n"); 1049*23ba6841SJoseph Chen return -1; 1050*23ba6841SJoseph Chen } 1051*23ba6841SJoseph Chen printf("merge success(%s)\n", gOpts.outPath); 1052*23ba6841SJoseph Chen } else { 1053*23ba6841SJoseph Chen LOGD("do_unpack\n"); 1054*23ba6841SJoseph Chen if (!unpackBoot(optPath)) { 1055*23ba6841SJoseph Chen fprintf(stderr, "unpack failed!\n"); 1056*23ba6841SJoseph Chen return -1; 1057*23ba6841SJoseph Chen } 1058*23ba6841SJoseph Chen printf("unpack success\n"); 1059*23ba6841SJoseph Chen } 1060*23ba6841SJoseph Chen return 0; 1061*23ba6841SJoseph Chen } 1062