--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/brdbootldr/ubootldr/locdrv.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,425 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// improvised boot loader mechanism
+//
+//
+
+/**
+ @file
+*/
+
+#include <e32const.h>
+#include <e32const_private.h>
+#include <e32std.h>
+#include <e32std_private.h>
+#include <e32svr.h>
+#include <e32cons.h>
+#include <f32file.h>
+#include <hal.h>
+#include <u32hal.h>
+#include "bootloader_variantconfig.h"
+#include <nkern/nk_trace.h>
+#include <e32twin.h>
+
+#define FILE_ID 0x594D555D
+#include "bootldr.h"
+
+void CloseAndDeleteFile();
+RFs TheFs;
+
+// Extra stuff to determine inner compression from the ROM header
+#include <e32rom.h>
+extern TInt memcmp1(const TUint8* aTrg, const TUint8* aSrc, TInt aLength);
+
+// XXX FIXED DRIVE PATH
+const TPtrC filePath=_L("d:\\");
+
+#if defined(__SUPPORT_UNZIP__)
+const TBool ZipIsSupported = ETrue;
+#else
+const TBool ZipIsSupported = EFalse;
+#endif
+
+#if defined(__SUPPORT_FLASH_REPRO__)
+const TBool FlashIsSupported = ETrue;
+#else
+const TBool FlashIsSupported = EFalse;
+#endif
+
+typedef struct
+ {
+ TPtrC filename;
+ TBool Zip; // set to ETrue if this file is a ZIP file
+ TBool Flash; // set to ETrue if this file is to be written to flash
+ TBool BootLoader; // set to ETrue if this file is to be flashed to the BootLoader address
+ TBool Delete; // set to ETrue if this file is to be deleted after loading into RAM
+ }
+ TFileTypes;
+
+
+TFileTypes supportedFileTypes [] =
+ {
+ // Name Zip Flash BootLoader Delete
+ {_L("FLASHLDR.ZIP"), ETrue, ETrue, ETrue, ETrue },
+ {_L("FLASHLDR.BIN"), EFalse, ETrue, ETrue, ETrue },
+
+ {VARIANT_ZIP, ETrue, EFalse, EFalse, EFalse },
+ {VARIANT_BIN, EFalse, EFalse, EFalse, EFalse },
+
+ {_L("SYS$ROM.ZIP"), ETrue, EFalse, EFalse, EFalse },
+ {_L("SYS$ROM.BIN"), EFalse, EFalse, EFalse, EFalse },
+
+ {_L("FLASHIMG.ZIP"), ETrue, ETrue, EFalse, EFalse },
+ {_L("FLASHIMG.BIN"), EFalse, ETrue, EFalse, EFalse },
+ {_L("BOOTLDR.ZIP"), ETrue, ETrue, ETrue, EFalse },
+ {_L("BOOTLDR.BIN"), EFalse, ETrue, ETrue, EFalse },
+
+ {_L("COREIMG.BIN"), EFalse, EFalse, EFalse, ETrue },
+
+ {_L(""),0} // Last Entry - this empty row is used in code to detect table end
+ };
+
+
+GLDEF_C TBool SearchDrivesRaw()
+ {
+ // Scan local drives directly (i.e. via TLocalDrv rather than RFS)
+
+ PrintToScreen(_L("Checking local drives directly.\r\n"));
+
+ TDriveInfoV1Buf diBuf;
+ UserHal::DriveInfo(diBuf);
+ TDriveInfoV1 &di=diBuf();
+
+
+ LocDrvChg = EFalse;
+ LocDrvPos = 0;
+ TInt LocalDriveNum = KErrNotFound;
+ TInt r = KErrNone;
+ TInt n=0;
+ for ( ; n<KMaxLocalDrives && LocalDriveNum == KErrNotFound; n++)
+ {
+ r = LocDrv.Connect(n, LocDrvChg);
+
+ if(r != KErrNone)
+ {
+ RDebug::Print(_L("\nDrive %d: TBusLocalDrive::Connect() failed %d"), n, r);
+ continue;
+ }
+
+ TLocalDriveCapsV5Buf capsBuf;
+ TLocalDriveCapsV5& caps = capsBuf();
+ r = LocDrv.Caps(capsBuf);
+ if(r != KErrNone)
+ {
+ RDebug::Print(_L("\nDrive %d: TBusLocalDrive::Caps() failed %d"), n, r);
+ continue;
+ }
+ else
+ {
+ PrintToScreen(_L("Found Drive %d OK\r\n"),n);
+ RDebug::Print(_L("\nDrive %d: %S"), n, &di.iDriveName[n]);
+ RDebug::Print(_L("PartitionType %X"), caps.iPartitionType);
+ RDebug::Print(_L("PartitionSize %ld"), caps.iSize);
+
+ // Check that drive is labelled as MMC or SDIO,
+ // note that this is a platform specific label...
+ if ((di.iDriveName[n].MatchF(_L("MultiMediaCard0")) == KErrNone) ||
+ (di.iDriveName[n].MatchF(_L("SDIOCard0")) == KErrNone))
+ {
+ if (caps.iPartitionType == KPartitionTypeROM)
+ {
+ RDebug::Print(_L("- ROM Partition"));
+ LocalDriveNum = n;
+ FileSize = caps.iSize;
+ break;
+ }
+ }
+
+ CloseLocalDrive();
+ }
+ }
+
+ if (LocalDriveNum == KErrNotFound)
+ {
+ RDebug::Print(_L("No ROM Partitions found"));
+ return EFalse;
+ }
+ else
+ {
+ RDebug::Print(_L("Query ROM in drive %d"), LocalDriveNum);
+ }
+
+ InputFunction=ReadFromLocalDrive;
+ CloseInputFunction=CloseLocalDrive;
+
+ RDebug::Print(_L("Determine the compression"));
+
+ r = GetInnerCompression(ImageDeflated, RomLoaderHeaderExists);
+
+ if(KErrNone != r)
+ {
+ PrintToScreen(_L("Unable to determine the compression!\r\n"));
+ BOOT_FAULT();
+ }
+ else
+ {
+ // Put position back to start
+ LocDrvPos = 0;
+ }
+
+ return ETrue;
+ }
+
+
+TInt ReadFromLocalDrive(TUint8* aDest, TInt& aLength)
+ {
+ // construct as TPtr8(TUint8 *aBuf, TInt aMaxLength);
+ // .. because TBusLocalDrive.Read only understands descriptors
+ TPtr8 d(aDest, aLength);
+
+ TInt r = LocDrv.Read(LocDrvPos,aLength,d);
+ LocDrvPos+=aLength;
+
+ if (LocDrvPos >= FileSize)
+ {
+ // ROM read completely
+ r = KErrEof;
+ }
+
+ return r;
+ }
+
+
+void CloseLocalDrive()
+ {
+ LocDrv.Disconnect();
+ }
+
+
+GLDEF_C TBool SearchDrives()
+ {
+ // set up the list of files to look for -- this code will search through
+ // all available drives until it finds one of these files in a root
+ // directory
+
+ PrintToScreen(_L("Checking local drives.\r\n"));
+
+ // search for files
+ TInt r = TheFs.Connect();
+ if (r != KErrNone)
+ {
+ RDebug::Print(_L("FAULT: Connecting RFs returned %d\r\n"),r);
+ BOOT_FAULT();
+ }
+
+ TFindFile finder(TheFs);
+
+ // for each file in the list
+ TInt NrChecked = 0;
+ r = KErrNotFound;
+
+ while ( (*(supportedFileTypes[NrChecked].filename.Ptr()) != 0) && (r == KErrNotFound))
+ {
+ if ( (!ZipIsSupported && (supportedFileTypes[NrChecked].Zip))
+ || (!FlashIsSupported && (supportedFileTypes[NrChecked].Flash))
+ )
+ {
+ //skip ZIP/FLASH file types if they aren't supported
+ }
+ else
+ {
+ TPtrC thisFile = supportedFileTypes[NrChecked].filename;
+ r = finder.FindByDir(thisFile, filePath);
+
+ if (r == KErrNone)
+ PrintToScreen(_L("Found %s\r\n"), thisFile.Ptr());
+ }
+ NrChecked++;
+ }
+
+ // if found
+ if (r == KErrNone)
+ {
+ // setup some flags
+ LoadFile=--NrChecked; // predecrement since this was incremented at the end of the last loop
+ LoadDevice=ELoadDrive;
+
+ const TPtrC bootFileName = finder.File();
+
+ PrintToScreen(_L("Opening: %s\r\n"), supportedFileTypes[NrChecked].filename.Ptr());
+
+ r = bootFile.Open(TheFs, bootFileName, EFileRead);
+
+ if (r != KErrNone)
+ {
+ PrintToScreen(_L("Bootfile failed to open - err %d.\r\n"),r);
+
+ BOOT_FAULT();
+ }
+
+ ImageZip = supportedFileTypes[NrChecked].Zip;
+ LoadToFlash = supportedFileTypes[NrChecked].Flash;
+ FlashBootLoader = supportedFileTypes[NrChecked].BootLoader;
+
+ InputFunction=ReadFromFile;
+ CloseInputFunction = supportedFileTypes[NrChecked].Delete ? CloseAndDeleteFile : CloseFile;
+
+ if( !ImageZip)
+ {
+ r = GetInnerCompression(ImageDeflated, RomLoaderHeaderExists);
+ if(KErrNone != r)
+ {
+ PrintToScreen(_L("Unable to determine the compression!\r\n"));
+ BOOT_FAULT();
+ }
+ else
+ {
+ // Move file pos back to the beginning
+ TInt pos = 0;
+ r = bootFile.Seek(ESeekStart, pos);
+ }
+ }
+
+ r = bootFile.Size(FileSize);
+
+ if (r == KErrNone)
+ {
+ PrintToScreen(_L("Opened, size: %d bytes.\r\n"), FileSize);
+ if(ImageDeflated)
+ {
+ PrintToScreen(_L("ROM Image is deflated.\r\n"));
+ }
+ }
+ else
+ {
+ PrintToScreen(_L("Unable to read file size\r\n"));
+ BOOT_FAULT();
+ }
+
+ // Found image - return true
+ return ETrue;
+ }
+
+ // else NOT FOUND
+ return EFalse;
+ }
+
+TInt ReadFromFile(TUint8* aDest, TInt& aLength)
+ {
+ // construct as TPtr8(TUint8 *aBuf, TInt aMaxLength);
+ // .. because RFile.Read only understands descriptors
+ TPtr8 d(aDest, aLength);
+
+ TInt r = bootFile.Read(d);
+
+ if (d.Length() < aLength) // may happen at the end of a file
+ {
+ aLength = d.Length();
+ }
+
+ if (d.Length() == 0) // indicates end of file
+ {
+ if (FileSize-aLength == ImageReadProgress)
+ return KErrEof;
+ else
+ // this will drop through to the error code below and will fault
+ return KErrGeneral;
+ }
+
+ return r;
+ }
+
+void CloseFile()
+ {
+ bootFile.Close();
+ }
+
+void CloseAndDeleteFile()
+ {
+ TFileName fileName;
+ TInt r = bootFile.FullName(fileName);
+ if (r != KErrNone)
+ PrintToScreen(_L("CloseAndDeleteFile() RFile::FullName returned %d"), r);
+
+ bootFile.Close();
+
+ r = TheFs.Delete(fileName);
+ PrintToScreen(_L("Deleted file fileName %S"), &fileName);
+ }
+
+//#define TROM_LOADER_HEADER_SIZE 0x100
+#define BUFFER_SIZE (TROM_LOADER_HEADER_SIZE + sizeof(TRomHeader))
+
+TInt GetInnerCompression(TBool &aImageDeflated, TBool &aRomLoaderHeaderExists )
+ {
+ TInt r = KErrNone;
+
+ TUint8 buffer[BUFFER_SIZE];
+ TInt bufferSize = BUFFER_SIZE;
+
+ const TUint8 * romLoaderSignature1 = (const TUint8*)"EPOC";
+ const TUint8 * romLoaderSignature2 = (const TUint8*)"ROM";
+
+ r = ReadInputData((TUint8*)&buffer, bufferSize);
+ if( KErrNone!=r)
+ {
+ PrintToScreen(_L("Unable to read loader headers... (size:%d)\r\n"), bufferSize);
+ BOOT_FAULT();
+ }
+ else
+ {
+ // Check headers
+ TRomHeader* romHeader= (TRomHeader *) &buffer;
+ aRomLoaderHeaderExists = EFalse;
+
+ if( !memcmp1(buffer, romLoaderSignature1, 4) && !memcmp1(&buffer[8], romLoaderSignature2, 3) )
+ {
+ // We have TRomLoaderHeader skip it
+ romHeader = (TRomHeader *) (&buffer[TROM_LOADER_HEADER_SIZE]);
+ aRomLoaderHeaderExists = ETrue;
+ }
+
+ if(romHeader->iCompressionType == 0 )
+ {
+ RDebug::Print(_L("Image is NOT Compressed"));
+ aImageDeflated = EFalse;
+ FileSize = romHeader->iUncompressedSize;
+ PrintToScreen(_L("ROMSIZE:%d\r\n"), romHeader->iUncompressedSize);
+ RDebug::Print(_L("ROMSIZE:%d"), romHeader->iUncompressedSize);
+
+ if (romHeader->iPageableRomStart > 0)
+ {
+ PrintToScreen(_L("Paged ROM FOUND\r\n"));
+ RDebug::Print(_L("Paged ROM FOUND"));
+ FileSize = romHeader->iPageableRomStart;
+ RDebug::Print(_L("Unpaged ROMSIZE:%d"), romHeader->iPageableRomStart);
+ }
+ }
+ else if (romHeader->iCompressionType == KUidCompressionDeflate )
+ {
+ RDebug::Print(_L("Image is Compressed\r\n"));
+ aImageDeflated = ETrue;
+ FileSize = romHeader->iUnpagedUncompressedSize;
+ RDebug::Print(_L("Compressed ROMSIZE:%d\r\n"), romHeader->iUnpagedUncompressedSize);
+ }
+ else
+ {
+ RDebug::Print(_L("Not supported compression method:0x%08x\r\n"), romHeader->iCompressionType);
+ PrintToScreen(_L("Not supported compression method:0x%08x\r\n"), romHeader->iCompressionType);
+ r = KErrNotSupported;
+ }
+ }
+ return r;
+ }
+