|
1 // Copyright (c) 2005-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 the License "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 // improvised boot loader mechanism |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include <e32const.h> |
|
23 #include <e32const_private.h> |
|
24 #include <e32std.h> |
|
25 #include <e32std_private.h> |
|
26 #include <e32svr.h> |
|
27 #include <e32cons.h> |
|
28 #include <f32file.h> |
|
29 #include <hal.h> |
|
30 #include <u32hal.h> |
|
31 #include "bootloader_variantconfig.h" |
|
32 #include <nkern/nk_trace.h> |
|
33 #include <e32twin.h> |
|
34 |
|
35 #define FILE_ID 0x594D555D |
|
36 #include "bootldr.h" |
|
37 |
|
38 void CloseAndDeleteFile(); |
|
39 RFs TheFs; |
|
40 |
|
41 // Extra stuff to determine inner compression from the ROM header |
|
42 #include <e32rom.h> |
|
43 extern TInt memcmp1(const TUint8* aTrg, const TUint8* aSrc, TInt aLength); |
|
44 |
|
45 // XXX FIXED DRIVE PATH |
|
46 const TPtrC filePath=_L("d:\\"); |
|
47 |
|
48 #if defined(__SUPPORT_UNZIP__) |
|
49 const TBool ZipIsSupported = ETrue; |
|
50 #else |
|
51 const TBool ZipIsSupported = EFalse; |
|
52 #endif |
|
53 |
|
54 #if defined(__SUPPORT_FLASH_REPRO__) |
|
55 const TBool FlashIsSupported = ETrue; |
|
56 #else |
|
57 const TBool FlashIsSupported = EFalse; |
|
58 #endif |
|
59 |
|
60 typedef struct |
|
61 { |
|
62 TPtrC filename; |
|
63 TBool Zip; // set to ETrue if this file is a ZIP file |
|
64 TBool Flash; // set to ETrue if this file is to be written to flash |
|
65 TBool BootLoader; // set to ETrue if this file is to be flashed to the BootLoader address |
|
66 TBool Delete; // set to ETrue if this file is to be deleted after loading into RAM |
|
67 } |
|
68 TFileTypes; |
|
69 |
|
70 |
|
71 TFileTypes supportedFileTypes [] = |
|
72 { |
|
73 // Name Zip Flash BootLoader Delete |
|
74 {_L("FLASHLDR.ZIP"), ETrue, ETrue, ETrue, ETrue }, |
|
75 {_L("FLASHLDR.BIN"), EFalse, ETrue, ETrue, ETrue }, |
|
76 |
|
77 {VARIANT_ZIP, ETrue, EFalse, EFalse, EFalse }, |
|
78 {VARIANT_BIN, EFalse, EFalse, EFalse, EFalse }, |
|
79 |
|
80 {_L("SYS$ROM.ZIP"), ETrue, EFalse, EFalse, EFalse }, |
|
81 {_L("SYS$ROM.BIN"), EFalse, EFalse, EFalse, EFalse }, |
|
82 |
|
83 {_L("FLASHIMG.ZIP"), ETrue, ETrue, EFalse, EFalse }, |
|
84 {_L("FLASHIMG.BIN"), EFalse, ETrue, EFalse, EFalse }, |
|
85 {_L("BOOTLDR.ZIP"), ETrue, ETrue, ETrue, EFalse }, |
|
86 {_L("BOOTLDR.BIN"), EFalse, ETrue, ETrue, EFalse }, |
|
87 |
|
88 {_L("COREIMG.BIN"), EFalse, EFalse, EFalse, ETrue }, |
|
89 |
|
90 {_L(""),0} // Last Entry - this empty row is used in code to detect table end |
|
91 }; |
|
92 |
|
93 |
|
94 GLDEF_C TBool SearchDrivesRaw() |
|
95 { |
|
96 // Scan local drives directly (i.e. via TLocalDrv rather than RFS) |
|
97 |
|
98 PrintToScreen(_L("Checking local drives directly.\r\n")); |
|
99 |
|
100 TDriveInfoV1Buf diBuf; |
|
101 UserHal::DriveInfo(diBuf); |
|
102 TDriveInfoV1 &di=diBuf(); |
|
103 |
|
104 |
|
105 LocDrvChg = EFalse; |
|
106 LocDrvPos = 0; |
|
107 TInt LocalDriveNum = KErrNotFound; |
|
108 TInt r = KErrNone; |
|
109 TInt n=0; |
|
110 for ( ; n<KMaxLocalDrives && LocalDriveNum == KErrNotFound; n++) |
|
111 { |
|
112 r = LocDrv.Connect(n, LocDrvChg); |
|
113 |
|
114 if(r != KErrNone) |
|
115 { |
|
116 RDebug::Print(_L("\nDrive %d: TBusLocalDrive::Connect() failed %d"), n, r); |
|
117 continue; |
|
118 } |
|
119 |
|
120 TLocalDriveCapsV5Buf capsBuf; |
|
121 TLocalDriveCapsV5& caps = capsBuf(); |
|
122 r = LocDrv.Caps(capsBuf); |
|
123 if(r != KErrNone) |
|
124 { |
|
125 RDebug::Print(_L("\nDrive %d: TBusLocalDrive::Caps() failed %d"), n, r); |
|
126 continue; |
|
127 } |
|
128 else |
|
129 { |
|
130 PrintToScreen(_L("Found Drive %d OK\r\n"),n); |
|
131 RDebug::Print(_L("\nDrive %d: %S"), n, &di.iDriveName[n]); |
|
132 RDebug::Print(_L("PartitionType %X"), caps.iPartitionType); |
|
133 RDebug::Print(_L("PartitionSize %ld"), caps.iSize); |
|
134 |
|
135 // Check that drive is labelled as MMC or SDIO, |
|
136 // note that this is a platform specific label... |
|
137 if ((di.iDriveName[n].MatchF(_L("MultiMediaCard0")) == KErrNone) || |
|
138 (di.iDriveName[n].MatchF(_L("SDIOCard0")) == KErrNone)) |
|
139 { |
|
140 if (caps.iPartitionType == KPartitionTypeROM) |
|
141 { |
|
142 RDebug::Print(_L("- ROM Partition")); |
|
143 LocalDriveNum = n; |
|
144 FileSize = caps.iSize; |
|
145 break; |
|
146 } |
|
147 } |
|
148 |
|
149 CloseLocalDrive(); |
|
150 } |
|
151 } |
|
152 |
|
153 if (LocalDriveNum == KErrNotFound) |
|
154 { |
|
155 RDebug::Print(_L("No ROM Partitions found")); |
|
156 return EFalse; |
|
157 } |
|
158 else |
|
159 { |
|
160 RDebug::Print(_L("Query ROM in drive %d"), LocalDriveNum); |
|
161 } |
|
162 |
|
163 InputFunction=ReadFromLocalDrive; |
|
164 CloseInputFunction=CloseLocalDrive; |
|
165 |
|
166 RDebug::Print(_L("Determine the compression")); |
|
167 |
|
168 r = GetInnerCompression(ImageDeflated, RomLoaderHeaderExists); |
|
169 |
|
170 if(KErrNone != r) |
|
171 { |
|
172 PrintToScreen(_L("Unable to determine the compression!\r\n")); |
|
173 BOOT_FAULT(); |
|
174 } |
|
175 else |
|
176 { |
|
177 // Put position back to start |
|
178 LocDrvPos = 0; |
|
179 } |
|
180 |
|
181 return ETrue; |
|
182 } |
|
183 |
|
184 |
|
185 TInt ReadFromLocalDrive(TUint8* aDest, TInt& aLength) |
|
186 { |
|
187 // construct as TPtr8(TUint8 *aBuf, TInt aMaxLength); |
|
188 // .. because TBusLocalDrive.Read only understands descriptors |
|
189 TPtr8 d(aDest, aLength); |
|
190 |
|
191 TInt r = LocDrv.Read(LocDrvPos,aLength,d); |
|
192 LocDrvPos+=aLength; |
|
193 |
|
194 if (LocDrvPos >= FileSize) |
|
195 { |
|
196 // ROM read completely |
|
197 r = KErrEof; |
|
198 } |
|
199 |
|
200 return r; |
|
201 } |
|
202 |
|
203 |
|
204 void CloseLocalDrive() |
|
205 { |
|
206 LocDrv.Disconnect(); |
|
207 } |
|
208 |
|
209 |
|
210 GLDEF_C TBool SearchDrives() |
|
211 { |
|
212 // set up the list of files to look for -- this code will search through |
|
213 // all available drives until it finds one of these files in a root |
|
214 // directory |
|
215 |
|
216 PrintToScreen(_L("Checking local drives.\r\n")); |
|
217 |
|
218 // search for files |
|
219 TInt r = TheFs.Connect(); |
|
220 if (r != KErrNone) |
|
221 { |
|
222 RDebug::Print(_L("FAULT: Connecting RFs returned %d\r\n"),r); |
|
223 BOOT_FAULT(); |
|
224 } |
|
225 |
|
226 TFindFile finder(TheFs); |
|
227 |
|
228 // for each file in the list |
|
229 TInt NrChecked = 0; |
|
230 r = KErrNotFound; |
|
231 |
|
232 while ( (*(supportedFileTypes[NrChecked].filename.Ptr()) != 0) && (r == KErrNotFound)) |
|
233 { |
|
234 if ( (!ZipIsSupported && (supportedFileTypes[NrChecked].Zip)) |
|
235 || (!FlashIsSupported && (supportedFileTypes[NrChecked].Flash)) |
|
236 ) |
|
237 { |
|
238 //skip ZIP/FLASH file types if they aren't supported |
|
239 } |
|
240 else |
|
241 { |
|
242 TPtrC thisFile = supportedFileTypes[NrChecked].filename; |
|
243 r = finder.FindByDir(thisFile, filePath); |
|
244 |
|
245 if (r == KErrNone) |
|
246 PrintToScreen(_L("Found %s\r\n"), thisFile.Ptr()); |
|
247 } |
|
248 NrChecked++; |
|
249 } |
|
250 |
|
251 // if found |
|
252 if (r == KErrNone) |
|
253 { |
|
254 // setup some flags |
|
255 LoadFile=--NrChecked; // predecrement since this was incremented at the end of the last loop |
|
256 LoadDevice=ELoadDrive; |
|
257 |
|
258 const TPtrC bootFileName = finder.File(); |
|
259 |
|
260 PrintToScreen(_L("Opening: %s\r\n"), supportedFileTypes[NrChecked].filename.Ptr()); |
|
261 |
|
262 r = bootFile.Open(TheFs, bootFileName, EFileRead); |
|
263 |
|
264 if (r != KErrNone) |
|
265 { |
|
266 PrintToScreen(_L("Bootfile failed to open - err %d.\r\n"),r); |
|
267 |
|
268 BOOT_FAULT(); |
|
269 } |
|
270 |
|
271 ImageZip = supportedFileTypes[NrChecked].Zip; |
|
272 LoadToFlash = supportedFileTypes[NrChecked].Flash; |
|
273 FlashBootLoader = supportedFileTypes[NrChecked].BootLoader; |
|
274 |
|
275 InputFunction=ReadFromFile; |
|
276 CloseInputFunction = supportedFileTypes[NrChecked].Delete ? CloseAndDeleteFile : CloseFile; |
|
277 |
|
278 if( !ImageZip) |
|
279 { |
|
280 r = GetInnerCompression(ImageDeflated, RomLoaderHeaderExists); |
|
281 if(KErrNone != r) |
|
282 { |
|
283 PrintToScreen(_L("Unable to determine the compression!\r\n")); |
|
284 BOOT_FAULT(); |
|
285 } |
|
286 else |
|
287 { |
|
288 // Move file pos back to the beginning |
|
289 TInt pos = 0; |
|
290 r = bootFile.Seek(ESeekStart, pos); |
|
291 } |
|
292 } |
|
293 |
|
294 r = bootFile.Size(FileSize); |
|
295 |
|
296 if (r == KErrNone) |
|
297 { |
|
298 PrintToScreen(_L("Opened, size: %d bytes.\r\n"), FileSize); |
|
299 if(ImageDeflated) |
|
300 { |
|
301 PrintToScreen(_L("ROM Image is deflated.\r\n")); |
|
302 } |
|
303 } |
|
304 else |
|
305 { |
|
306 PrintToScreen(_L("Unable to read file size\r\n")); |
|
307 BOOT_FAULT(); |
|
308 } |
|
309 |
|
310 // Found image - return true |
|
311 return ETrue; |
|
312 } |
|
313 |
|
314 // else NOT FOUND |
|
315 return EFalse; |
|
316 } |
|
317 |
|
318 TInt ReadFromFile(TUint8* aDest, TInt& aLength) |
|
319 { |
|
320 // construct as TPtr8(TUint8 *aBuf, TInt aMaxLength); |
|
321 // .. because RFile.Read only understands descriptors |
|
322 TPtr8 d(aDest, aLength); |
|
323 |
|
324 TInt r = bootFile.Read(d); |
|
325 |
|
326 if (d.Length() < aLength) // may happen at the end of a file |
|
327 { |
|
328 aLength = d.Length(); |
|
329 } |
|
330 |
|
331 if (d.Length() == 0) // indicates end of file |
|
332 { |
|
333 if (FileSize-aLength == ImageReadProgress) |
|
334 return KErrEof; |
|
335 else |
|
336 // this will drop through to the error code below and will fault |
|
337 return KErrGeneral; |
|
338 } |
|
339 |
|
340 return r; |
|
341 } |
|
342 |
|
343 void CloseFile() |
|
344 { |
|
345 bootFile.Close(); |
|
346 } |
|
347 |
|
348 void CloseAndDeleteFile() |
|
349 { |
|
350 TFileName fileName; |
|
351 TInt r = bootFile.FullName(fileName); |
|
352 if (r != KErrNone) |
|
353 PrintToScreen(_L("CloseAndDeleteFile() RFile::FullName returned %d"), r); |
|
354 |
|
355 bootFile.Close(); |
|
356 |
|
357 r = TheFs.Delete(fileName); |
|
358 PrintToScreen(_L("Deleted file fileName %S"), &fileName); |
|
359 } |
|
360 |
|
361 //#define TROM_LOADER_HEADER_SIZE 0x100 |
|
362 #define BUFFER_SIZE (TROM_LOADER_HEADER_SIZE + sizeof(TRomHeader)) |
|
363 |
|
364 TInt GetInnerCompression(TBool &aImageDeflated, TBool &aRomLoaderHeaderExists ) |
|
365 { |
|
366 TInt r = KErrNone; |
|
367 |
|
368 TUint8 buffer[BUFFER_SIZE]; |
|
369 TInt bufferSize = BUFFER_SIZE; |
|
370 |
|
371 const TUint8 * romLoaderSignature1 = (const TUint8*)"EPOC"; |
|
372 const TUint8 * romLoaderSignature2 = (const TUint8*)"ROM"; |
|
373 |
|
374 r = ReadInputData((TUint8*)&buffer, bufferSize); |
|
375 if( KErrNone!=r) |
|
376 { |
|
377 PrintToScreen(_L("Unable to read loader headers... (size:%d)\r\n"), bufferSize); |
|
378 BOOT_FAULT(); |
|
379 } |
|
380 else |
|
381 { |
|
382 // Check headers |
|
383 TRomHeader* romHeader= (TRomHeader *) &buffer; |
|
384 aRomLoaderHeaderExists = EFalse; |
|
385 |
|
386 if( !memcmp1(buffer, romLoaderSignature1, 4) && !memcmp1(&buffer[8], romLoaderSignature2, 3) ) |
|
387 { |
|
388 // We have TRomLoaderHeader skip it |
|
389 romHeader = (TRomHeader *) (&buffer[TROM_LOADER_HEADER_SIZE]); |
|
390 aRomLoaderHeaderExists = ETrue; |
|
391 } |
|
392 |
|
393 if(romHeader->iCompressionType == 0 ) |
|
394 { |
|
395 RDebug::Print(_L("Image is NOT Compressed")); |
|
396 aImageDeflated = EFalse; |
|
397 FileSize = romHeader->iUncompressedSize; |
|
398 PrintToScreen(_L("ROMSIZE:%d\r\n"), romHeader->iUncompressedSize); |
|
399 RDebug::Print(_L("ROMSIZE:%d"), romHeader->iUncompressedSize); |
|
400 |
|
401 if (romHeader->iPageableRomStart > 0) |
|
402 { |
|
403 PrintToScreen(_L("Paged ROM FOUND\r\n")); |
|
404 RDebug::Print(_L("Paged ROM FOUND")); |
|
405 FileSize = romHeader->iPageableRomStart; |
|
406 RDebug::Print(_L("Unpaged ROMSIZE:%d"), romHeader->iPageableRomStart); |
|
407 } |
|
408 } |
|
409 else if (romHeader->iCompressionType == KUidCompressionDeflate ) |
|
410 { |
|
411 RDebug::Print(_L("Image is Compressed\r\n")); |
|
412 aImageDeflated = ETrue; |
|
413 FileSize = romHeader->iUnpagedUncompressedSize; |
|
414 RDebug::Print(_L("Compressed ROMSIZE:%d\r\n"), romHeader->iUnpagedUncompressedSize); |
|
415 } |
|
416 else |
|
417 { |
|
418 RDebug::Print(_L("Not supported compression method:0x%08x\r\n"), romHeader->iCompressionType); |
|
419 PrintToScreen(_L("Not supported compression method:0x%08x\r\n"), romHeader->iCompressionType); |
|
420 r = KErrNotSupported; |
|
421 } |
|
422 } |
|
423 return r; |
|
424 } |
|
425 |