|
1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <string.h> |
|
17 #include <io.h> |
|
18 |
|
19 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) |
|
20 #include <iomanip> |
|
21 #else //!__MSVCDOTNET__ |
|
22 #include <iomanip.h> |
|
23 #endif //__MSVCDOTNET__ |
|
24 |
|
25 #include "h_utl.h" |
|
26 #include "h_ver.h" |
|
27 |
|
28 // ROMMASK.EXE cl parameters |
|
29 char *gRomImage=NULL; |
|
30 char *gOutputRom=NULL; |
|
31 int gRomSize=0; |
|
32 char gFormat='P'; |
|
33 const int KMaxSections=8; |
|
34 int gNumberOfSections=0; |
|
35 int gSectionSize[KMaxSections]; |
|
36 int gHeader=ETrue; |
|
37 int gVerbose=EFalse; |
|
38 |
|
39 |
|
40 TInt MaskPlain(TInt aRomSize,ifstream& aPsionImageFile,ofstream& aMaskRomImageFile) |
|
41 // |
|
42 // Create a plain mask rom image file |
|
43 // |
|
44 { |
|
45 |
|
46 const char KMaskRomFillCharacter='\377'; |
|
47 const TInt KBufferSize=1024; |
|
48 char empty[KBufferSize]; |
|
49 for (TInt y=0;y<KBufferSize;y++) |
|
50 empty[y]=KMaskRomFillCharacter; |
|
51 char buffer[KBufferSize]; |
|
52 TUint checksum32=0; |
|
53 TUint checksum8=0; |
|
54 for (TInt x=0;x<aRomSize;x+=KBufferSize) |
|
55 { |
|
56 memcpy(buffer,empty,KBufferSize); |
|
57 aPsionImageFile.read(buffer,KBufferSize); |
|
58 aMaskRomImageFile.write(buffer,KBufferSize); |
|
59 TInt z; |
|
60 for (z=0;z<KBufferSize;z+=4) |
|
61 checksum32+=*(TUint32*)&buffer[z]; |
|
62 for (z=0;z<KBufferSize;z++) |
|
63 checksum8+=(TUint8)buffer[z]; |
|
64 } |
|
65 |
|
66 if (gVerbose) |
|
67 { |
|
68 cout << dec; |
|
69 cout << aRomSize << " byte PLAIN\r\n"; |
|
70 cout << "32 bit checksum 0x"; |
|
71 cout << setw(8); |
|
72 cout << hex; |
|
73 cout << setfill('0'); |
|
74 cout << checksum32 << "\r\n"; |
|
75 cout << " 8 bit checksum 0x"; |
|
76 cout << setw(8); |
|
77 cout << hex; |
|
78 cout << setfill('0'); |
|
79 cout << checksum8 << "\r\n"; |
|
80 } |
|
81 return(KErrNone); |
|
82 } |
|
83 |
|
84 TInt MaskMotorola(TInt /*aRomSize*/,ifstream& /*aPsionImageFile*/,ofstream& /*aMaskRomImageFile*/) |
|
85 // |
|
86 // Create a motorola s-record mask rom image file |
|
87 // |
|
88 { |
|
89 return(KErrNone); |
|
90 } |
|
91 |
|
92 TInt MaskRom(TInt aRomSize,ifstream& aPsionImageFile,const char* aMaskRomImageFileName,const char* aMaskRomFormat) |
|
93 { |
|
94 ofstream MaskRomImageFile; |
|
95 |
|
96 TInt r; |
|
97 if (!MaskRomImageFile) |
|
98 { |
|
99 cout << "Error: Cannot create mask rom image file (" << aMaskRomImageFileName << ")\r\n"; |
|
100 r=KErrArgument; |
|
101 } |
|
102 else |
|
103 { |
|
104 if (gVerbose) |
|
105 { |
|
106 cout << "\r\nMask ROM image file: "; |
|
107 cout << aMaskRomImageFileName << "\r\n"; |
|
108 } |
|
109 switch (aMaskRomFormat[0]) |
|
110 { |
|
111 case 'P': |
|
112 MaskRomImageFile.open(aMaskRomImageFileName, ios::in | ios::binary); |
|
113 r=MaskPlain(aRomSize,aPsionImageFile,MaskRomImageFile); |
|
114 break; |
|
115 case 'M': |
|
116 MaskRomImageFile.open(aMaskRomImageFileName, ios::in); |
|
117 r=MaskMotorola(aRomSize,aPsionImageFile,MaskRomImageFile); |
|
118 break; |
|
119 default: |
|
120 cerr << "Error: Rom format not recognised\r\n"; |
|
121 r=KErrGeneral; |
|
122 break; |
|
123 } |
|
124 MaskRomImageFile.close(); |
|
125 } |
|
126 return r; |
|
127 } |
|
128 |
|
129 |
|
130 TInt getIntegerArg(int argc, char *argv[], int param) |
|
131 { |
|
132 |
|
133 int error=KErrNone; |
|
134 if (param>=argc) |
|
135 error=KErrArgument; |
|
136 if (error==KErrNone) |
|
137 { |
|
138 int val; |
|
139 // if (!isNumber(argv[param])) |
|
140 // return KErrArgument; |
|
141 |
|
142 #ifdef __TOOLS2__ |
|
143 istringstream s(argv[param]); |
|
144 #else |
|
145 istrstream s(argv[param], strlen(argv[param])); |
|
146 #endif |
|
147 |
|
148 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) |
|
149 s >> setbase(0); |
|
150 #endif //__MSVCDOTNET__ |
|
151 |
|
152 s>>val; |
|
153 if (!s.fail()) |
|
154 return val; |
|
155 } |
|
156 cerr << "Error: Integer argument required for "; |
|
157 cerr << argv[param-1]; |
|
158 cerr << "\r\n"; |
|
159 return -1; |
|
160 } |
|
161 |
|
162 char *getStringArg(int argc, char *argv[], int param) |
|
163 { |
|
164 |
|
165 if (param>=argc) |
|
166 { |
|
167 cerr << "Error: String argument required for "; |
|
168 cerr << argv[param-1]; |
|
169 cerr << "\r\n"; |
|
170 return NULL; |
|
171 } |
|
172 return argv[param]; |
|
173 } |
|
174 |
|
175 char getCharArg(int argc, char *argv[], int param) |
|
176 { |
|
177 |
|
178 char *p=getStringArg(argc,argv,param); |
|
179 if (p!=NULL) |
|
180 return p[0]; |
|
181 return '\000'; |
|
182 } |
|
183 |
|
184 TInt processCommandLine(int argc, char *argv[]) |
|
185 { |
|
186 |
|
187 if (argc==1) |
|
188 return KErrArgument; |
|
189 int param=1; |
|
190 while (param<argc) |
|
191 { |
|
192 switch (argv[param][1]) |
|
193 { |
|
194 case 'r': |
|
195 case 'R': |
|
196 // rom name |
|
197 param++; |
|
198 gRomImage=getStringArg(argc, argv, param); |
|
199 break; |
|
200 case 's': |
|
201 case 'S': |
|
202 if (argv[param][2]=='i') |
|
203 { |
|
204 // rom size |
|
205 param++; |
|
206 gRomSize=getIntegerArg(argc, argv, param); |
|
207 if (gRomSize==-1) |
|
208 return KErrGeneral; |
|
209 } |
|
210 else |
|
211 { |
|
212 // section |
|
213 if (gNumberOfSections>=KMaxSections) |
|
214 { |
|
215 cerr << "Error: Too many sections\r\n"; |
|
216 return KErrGeneral; |
|
217 } |
|
218 param++; |
|
219 gSectionSize[gNumberOfSections]=getIntegerArg(argc, argv, param); |
|
220 if (gSectionSize[gNumberOfSections]==-1) |
|
221 return KErrGeneral; |
|
222 if (gSectionSize[gNumberOfSections]==0) |
|
223 { |
|
224 cerr << "Error: Section is zero bytes long\r\n"; |
|
225 return KErrGeneral; |
|
226 } |
|
227 if (gSectionSize[gNumberOfSections]>64) |
|
228 { |
|
229 cerr << "Error: Section too big\r\n"; |
|
230 return KErrGeneral; |
|
231 } |
|
232 gNumberOfSections++; |
|
233 } |
|
234 break; |
|
235 case 'f': |
|
236 case 'F': |
|
237 param++; |
|
238 gRomSize=getCharArg(argc, argv, param); |
|
239 break; |
|
240 case 'l': |
|
241 case 'L': |
|
242 cerr << "Error: Use -verbose instead of -log"; |
|
243 break; |
|
244 case 'v': |
|
245 case 'V': |
|
246 gVerbose=ETrue; |
|
247 break; |
|
248 case 'o': |
|
249 case 'O': |
|
250 param++; |
|
251 gOutputRom=getStringArg(argc, argv, param); |
|
252 break; |
|
253 case 'n': |
|
254 case 'N': |
|
255 // -no-header |
|
256 gHeader=EFalse; |
|
257 break; |
|
258 default: |
|
259 cout << "Error: Unrecognised switch '"<<argv[param]<<"'\r\n"; |
|
260 return KErrArgument; |
|
261 } |
|
262 param++; |
|
263 } |
|
264 if (gRomImage==NULL) |
|
265 { |
|
266 cerr << "Error: No rom image specified\r\n"; |
|
267 return KErrArgument; |
|
268 } |
|
269 if (gOutputRom==NULL) |
|
270 { |
|
271 cerr << "Error: No output rom file specified\r\n"; |
|
272 return KErrArgument; |
|
273 } |
|
274 if (gRomSize>64) |
|
275 { |
|
276 cerr << "Error: Rom too big\r\n"; |
|
277 return KErrGeneral; |
|
278 } |
|
279 if (gRomSize==0) |
|
280 { |
|
281 cerr << "Error: No rom size specified\r\n"; |
|
282 return KErrArgument; |
|
283 } |
|
284 if (gFormat!='P' && gFormat!='M') |
|
285 { |
|
286 cerr << "Error: Invalid mask rom format specified\r\n"; |
|
287 return KErrArgument; |
|
288 } |
|
289 |
|
290 return KErrNone; |
|
291 } |
|
292 |
|
293 TInt Align1M(TInt aVal) |
|
294 { |
|
295 return (aVal+0xfffff) & 0x7ff00000; |
|
296 } |
|
297 |
|
298 TInt main(int argc, char *argv[]) |
|
299 { |
|
300 |
|
301 const TInt KPsionImageFileHeaderSize=0x100; |
|
302 |
|
303 cout << "\r\nROMMASK - Rom masker V" << MajorVersion << "." << MinorVersion << "(Build " << Build << ")\r\n"; |
|
304 cout << Copyright; |
|
305 |
|
306 char HelpText[] = |
|
307 "Syntax: ROMMASK -romimage <psion img file> -output <rom img name>\r\n" |
|
308 " [-verbose] [-size <total rom size>]\r\n" |
|
309 " [-no-header] [-format <format>] [-section <size>]*\r\n" |
|
310 "Format: MOTOROLA (ascii s-record format)\r\n" |
|
311 " PLAIN (plain binary format) default\r\n"; |
|
312 int r=processCommandLine(argc, argv); |
|
313 if (r==KErrArgument) |
|
314 { |
|
315 cout << HelpText; |
|
316 return(KErrArgument); |
|
317 } |
|
318 |
|
319 // Open the psion image file |
|
320 |
|
321 ifstream PsionImageFile; |
|
322 char*& PsionImageFileName=gRomImage; |
|
323 |
|
324 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) |
|
325 PsionImageFile.open(PsionImageFileName, ios::in | ios::binary); |
|
326 #else //!__MSVCDOTNET__ |
|
327 PsionImageFile.open(PsionImageFileName, ios::nocreate | ios::binary); |
|
328 #endif //__MSVCDOTNET__ |
|
329 |
|
330 if (!PsionImageFile) |
|
331 { |
|
332 cerr << "Error: Cannot open psion image file (" << PsionImageFileName << ")\r\n"; |
|
333 return(KErrArgument); |
|
334 } |
|
335 |
|
336 gRomSize*=1024*1024; // in Mb |
|
337 // resolve sections to cover whole rom |
|
338 int size=0; |
|
339 int i; |
|
340 for (i=0; i<gNumberOfSections; i++) |
|
341 { |
|
342 gSectionSize[i]*=1024*1024; // in Mb |
|
343 size+=gSectionSize[i]; |
|
344 } |
|
345 if (size<gRomSize) |
|
346 gSectionSize[gNumberOfSections++]=gRomSize-size; |
|
347 if (size>gRomSize) |
|
348 { |
|
349 cerr << "Error: Sections too big for rom"; |
|
350 return KErrGeneral; |
|
351 } |
|
352 |
|
353 // Create the mask rom image file |
|
354 |
|
355 ofstream MaskRomImageFile; |
|
356 char*& MaskRomImageFileName=gOutputRom; |
|
357 |
|
358 MaskRomImageFile.open(MaskRomImageFileName); |
|
359 if (!MaskRomImageFile) |
|
360 { |
|
361 cerr << "Error: Cannot create mask rom image file (" << MaskRomImageFileName << ")\r\n"; |
|
362 PsionImageFile.close(); |
|
363 return(KErrArgument); |
|
364 } |
|
365 |
|
366 if (gHeader) |
|
367 { |
|
368 PsionImageFile.ignore(KPsionImageFileHeaderSize); |
|
369 int count=PsionImageFile.gcount(); |
|
370 if (count!=KPsionImageFileHeaderSize) |
|
371 { |
|
372 cerr << "Error: Corrupt Psion image file\r\n"; |
|
373 return(KErrGeneral); |
|
374 } |
|
375 } |
|
376 |
|
377 r=KErrNone; |
|
378 for (i=0; i<gNumberOfSections; i++) |
|
379 { |
|
380 r=MaskRom(gSectionSize[i],PsionImageFile,MaskRomImageFileName,&gFormat); |
|
381 if (r!=KErrNone) |
|
382 { |
|
383 cerr << "Error: An error occured while processing Rom image\r\n"; |
|
384 return r; |
|
385 } |
|
386 // next section |
|
387 char* ptr=MaskRomImageFileName; |
|
388 while (*++ptr!=0) |
|
389 ; |
|
390 *--ptr=(char)(i+'2'); |
|
391 } |
|
392 |
|
393 PsionImageFile.close(); |
|
394 return(r); |
|
395 } |