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