/* @func BOOL | ReadKernelRegionFromBootMedia | BinFS support. Reads the kernel region from Boot Media into RAM. The kernel region is fixed up to run from RAM and this is done just before jumping to the kernel entry point. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL ReadOSImageFromBootMedia() { HANDLE hPart; SectorInfo si; DWORD chainaddr, flashaddr; DWORD i; OALMSG(OAL_FUNC, (TEXT("+ReadOSImageFromBootMedia\r\n"))); if (!g_bBootMediaExist) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: INVALID_TOC\r\n"))); return(FALSE); } if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) ) { OALMSG(OAL_ERROR, (TEXT("ReadOSImageFromBootMedia: ERROR_INVALID_IMAGE_DESCRIPTOR: 0x%x\r\n"), g_pTOC->id[g_dwTocEntry].dwSignature)); return FALSE; } if ( !OEMVerifyMemory(g_pTOC->id[g_dwTocEntry].dwLoadAddress, sizeof(DWORD)) || !OEMVerifyMemory(g_pTOC->id[g_dwTocEntry].dwJumpAddress, sizeof(DWORD)) || !g_pTOC->id[g_dwTocEntry].dwTtlSectors ) { OALMSG(OAL_ERROR, (TEXT("ReadOSImageFromBootMedia: ERROR_INVALID_ADDRESS: (address=0x%x, sectors=0x%x, launch address=0x%x)...\r\n"), g_pTOC->id[g_dwTocEntry].dwLoadAddress, g_pTOC->id[g_dwTocEntry].dwTtlSectors, g_pTOC->id[g_dwTocEntry].dwJumpAddress)); return FALSE; } // Open the BINFS partition (it must exist). // hPart = BP_OpenPartition( NEXT_FREE_LOC, USE_REMAINING_SPACE, PART_BINFS, TRUE, PART_OPEN_EXISTING); if (hPart == INVALID_HANDLE_VALUE ) { OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to open existing partition.\r\n"))); return(FALSE); } // Set the partition file pointer to the correct offset for the kernel region. // if ( !BP_SetDataPointer(hPart, g_pTOC->id[g_dwTocEntry].dwStoreOffset) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to set data pointer in partition (offset=0x%x).\r\n"), g_pTOC->id[g_dwTocEntry].dwStoreOffset)); return(FALSE); } // Read the kernel region from the Boot Media into RAM. // if ( !BP_ReadData( hPart, (LPBYTE)(g_pTOC->id[g_dwTocEntry].dwLoadAddress), SECTOR_TO_FILE_SIZE(g_pTOC->id[g_dwTocEntry].dwTtlSectors)) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to read kernel region from partition.\r\n"))); return(FALSE); } if (!g_pTOC->chainInfo.dwLoadAddress) { chainaddr = g_pTOC->chainInfo.dwLoadAddress; flashaddr = g_pTOC->chainInfo.dwFlashAddress; for ( i = 0; i < (g_pTOC->chainInfo.dwLength); i++ ) { OALMSG(TRUE, (TEXT("chainaddr=0x%x, flashaddr=0x%x\r\n"), chainaddr, flashaddr+i)); if ( !FMD_ReadSector(flashaddr+i, (PUCHAR)(chainaddr), &si, 1) ) { OALMSG(OAL_ERROR, (TEXT("TOC_Write ERROR: Unable to read/verify TOC\r\n"))); return FALSE; } chainaddr += 512; } } OALMSG(OAL_FUNC, (TEXT("_ReadOSImageFromBootMedia\r\n"))); return(TRUE); }
/* @func BOOL | WriteOSImageToBootMedia | Stores the image cached in RAM to the Boot Media. The image may be comprised of one or more BIN regions. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL WriteOSImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) { BYTE nCount; DWORD dwNumExts; PXIPCHAIN_SUMMARY pChainInfo = NULL; EXTENSION *pExt = NULL; DWORD dwBINFSPartLength = 0; HANDLE hPart, hPartEx; DWORD dwStoreOffset; DWORD dwMaxRegionLength[BL_MAX_BIN_REGIONS] = {0}; DWORD dwChainStart, dwChainLength; // Initialize the variables dwChainStart = dwChainLength = 0; OALMSG(OAL_FUNC, (TEXT("+WriteOSImageToBootMedia\r\n"))); OALMSG(OAL_INFO, (TEXT("+WriteOSImageToBootMedia: g_dwTocEntry =%d, ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%x\r\n"), g_dwTocEntry, dwImageStart, dwImageLength, dwLaunchAddr)); if ( !g_bBootMediaExist ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_WARN, (TEXT("WARN: WriteOSImageToBootMedia: INVALID_TOC\r\n"))); if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: INVALID_TOC\r\n"))); return(FALSE); } } // Look in the kernel region's extension area for a multi-BIN extension descriptor. // This region, if found, details the number, start, and size of each BIN region. // for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions); nCount++) { // Does this region contain nk.exe and an extension pointer? // pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart, g_BINRegionInfo.Region[nCount].dwRegionLength ); if ( pExt != NULL) { // If there is an extension pointer region, walk it until the end. // while (pExt) { DWORD dwBaseAddr = g_BINRegionInfo.Region[nCount].dwRegionStart; pExt = (EXTENSION *)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt); OALMSG(OAL_INFO, (TEXT("INFO: OEMLaunch: Found chain extenstion: '%s' @ 0x%x\r\n"), pExt->name, dwBaseAddr)); if ((pExt->type == 0) && !strcmp(pExt->name, "chain information")) { pChainInfo = (PXIPCHAIN_SUMMARY) OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata); dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY)); OALMSG(OAL_INFO, (TEXT("INFO: OEMLaunch: Found 'chain information' (pChainInfo=0x%x Extensions=0x%x).\r\n"), (DWORD)pChainInfo, dwNumExts)); break; } pExt = (EXTENSION *)pExt->pNextExt; } } else { // Search for Chain region. Chain region doesn't have the ROMSIGNATURE set DWORD dwRegionStart = g_BINRegionInfo.Region[nCount].dwRegionStart; DWORD dwSig = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET); if ( dwSig != ROM_SIGNATURE) { // It is the chain dwChainStart = dwRegionStart; dwChainLength = g_BINRegionInfo.Region[nCount].dwRegionLength; OALMSG(TRUE, (TEXT("Found the Chain region: StartAddress: 0x%X; Length: 0x%X\n"), dwChainStart, dwChainLength)); } } } // Determine how big the Total BINFS partition needs to be to store all of this. // if (pChainInfo && dwNumExts == g_BINRegionInfo.dwNumRegions) // We're downloading all the regions in a multi-region image... { DWORD i; OALMSG(TRUE, (TEXT("Writing multi-regions\r\n"))); for (nCount = 0, dwBINFSPartLength = 0 ; nCount < dwNumExts ; nCount++) { dwBINFSPartLength += (pChainInfo + nCount)->dwMaxLength; OALMSG(OAL_ERROR, (TEXT("BINFSPartMaxLength[%u]: 0x%x, TtlBINFSPartLength: 0x%x \r\n"), nCount, (pChainInfo + nCount)->dwMaxLength, dwBINFSPartLength)); // MultiBINInfo does not store each Regions MAX length, and pChainInfo is not in any particular order. // So, walk our MultiBINInfo matching up pChainInfo to find each regions MAX Length for (i = 0; i < dwNumExts; i++) { if ( g_BINRegionInfo.Region[i].dwRegionStart == (DWORD)((pChainInfo + nCount)->pvAddr) ) { dwMaxRegionLength[i] = (pChainInfo + nCount)->dwMaxLength; OALMSG(TRUE, (TEXT("dwMaxRegionLength[%u]: 0x%x \r\n"), i, dwMaxRegionLength[i])); break; } } } } else // A single BIN file or potentially a multi-region update (but the partition's already been created in this latter case). { dwBINFSPartLength = g_BINRegionInfo.Region[0].dwRegionLength; OALMSG(TRUE, (TEXT("Writing single region/multi-region update, dwBINFSPartLength: %u \r\n"), dwBINFSPartLength)); } // Open/Create the BINFS partition where images are stored. This partition starts immediately after the MBR on the Boot Media and its length is // determined by the maximum image size (or sum of all maximum sizes in a multi-region design). // Parameters are LOGICAL sectors. // hPart = BP_OpenPartition( (IMAGE_START_BLOCK)*PAGES_PER_BLOCK, // MBR block SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength))*PAGES_PER_BLOCK, // align to block PART_BINFS, TRUE, PART_OPEN_ALWAYS); if (hPart == INVALID_HANDLE_VALUE ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: Failed to open/create partition.\r\n"))); return(FALSE); } // Are there multiple BIN files in RAM (we may just be updating one in a multi-BIN solution)? // for (nCount = 0, dwStoreOffset = 0; nCount < g_BINRegionInfo.dwNumRegions ; nCount++) { DWORD dwRegionStart = (DWORD)OEMMapMemAddr(0, g_BINRegionInfo.Region[nCount].dwRegionStart); DWORD dwRegionLength = g_BINRegionInfo.Region[nCount].dwRegionLength; // Media byte offset where image region is stored. dwStoreOffset += nCount ? dwMaxRegionLength[nCount-1] : 0; // Set the file pointer (byte indexing) to the correct offset for this particular region. // if ( !BP_SetDataPointer(hPart, dwStoreOffset) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: StoreImageToBootMedia: Failed to set data pointer in partition (offset=0x%x).\r\n"), dwStoreOffset)); return(FALSE); } // Write the region to the BINFS partition. // if ( !BP_WriteData(hPart, (LPBYTE)dwRegionStart, dwRegionLength) ) { EdbgOutputDebugString("ERROR: StoreImageToBootMedia: Failed to write region to BINFS partition (start=0x%x, length=0x%x).\r\n", dwRegionStart, dwRegionLength); return(FALSE); } RETAILMSG(TRUE, (TEXT("g_pTOC->id[g_dwTocEntry].dwLoadAddress = 0x%x \r\n"), g_pTOC->id[g_dwTocEntry].dwLoadAddress)); RETAILMSG(TRUE, (TEXT("g_BINRegionInfo.Region[nCount].dwRegionStart = 0x%x \r\n"), g_BINRegionInfo.Region[nCount].dwRegionStart)); RETAILMSG(TRUE, (TEXT("g_pTOC->id[g_dwTocEntry].dwTtlSectors = 0x%x \r\n"), g_pTOC->id[g_dwTocEntry].dwTtlSectors)); RETAILMSG(TRUE, (TEXT("FILE_TO_SECTOR_SIZE(dwRegionLength) = 0x%x \r\n"), FILE_TO_SECTOR_SIZE(dwRegionLength))); // update our TOC? // if ((g_pTOC->id[g_dwTocEntry].dwLoadAddress == g_BINRegionInfo.Region[nCount].dwRegionStart) && g_pTOC->id[g_dwTocEntry].dwTtlSectors == FILE_TO_SECTOR_SIZE(dwRegionLength) ) { OALMSG(TRUE, (TEXT("if \r\n"))); g_pTOC->id[g_dwTocEntry].dwStoreOffset = dwStoreOffset; g_pTOC->id[g_dwTocEntry].dwJumpAddress = 0; // Filled upon return to OEMLaunch g_pTOC->id[g_dwTocEntry].dwImageType = g_ImageType; g_pTOC->id[g_dwTocEntry].sgList[0].dwSector = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc); g_pTOC->id[g_dwTocEntry].sgList[0].dwLength = g_pTOC->id[g_dwTocEntry].dwTtlSectors; // copy Kernel Region to SDRAM for jump memcpy((void*)g_pTOC->id[g_dwTocEntry].dwLoadAddress, (void*)dwRegionStart, dwRegionLength); OALMSG(TRUE, (TEXT("Updateded TOC!\r\n"))); } else if( (dwChainStart == g_BINRegionInfo.Region[nCount].dwRegionStart) && (dwChainLength == g_BINRegionInfo.Region[nCount].dwRegionLength)) { OALMSG(TRUE, (TEXT("else if \r\n"))); // Update our TOC for Chain region g_pTOC->chainInfo.dwLoadAddress = dwChainStart; g_pTOC->chainInfo.dwFlashAddress = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc); g_pTOC->chainInfo.dwLength = FILE_TO_SECTOR_SIZE(dwMaxRegionLength[nCount]); OALMSG(TRUE, (TEXT("Written Chain Region to the Flash\n"))); OALMSG(TRUE, (TEXT("LoadAddress = 0x%X; FlashAddress = 0x%X; Length = 0x%X\n"), g_pTOC->chainInfo.dwLoadAddress, g_pTOC->chainInfo.dwFlashAddress, g_pTOC->chainInfo.dwLength)); // Now copy it to the SDRAM memcpy((void *)g_pTOC->chainInfo.dwLoadAddress, (void *)dwRegionStart, dwRegionLength); } OALMSG(TRUE, (TEXT("pass \r\n"))); } // create extended partition in whatever is left // hPartEx = BP_OpenPartition( NEXT_FREE_LOC, USE_REMAINING_SPACE, PART_DOS32, TRUE, PART_OPEN_ALWAYS); if (hPartEx == INVALID_HANDLE_VALUE ) { OALMSG(OAL_WARN, (TEXT("*** WARN: StoreImageToBootMedia: Failed to open/create Extended partition ***\r\n"))); } OALMSG(OAL_FUNC, (TEXT("-WriteOSImageToBootMedia\r\n"))); return(TRUE); }
BOOL BLConfigureFlashPartitions(BOOL bForceEnable) { BOOL rc = FALSE; HANDLE hFMD; PCI_REG_INFO regInfo; FlashInfo flashInfo; HANDLE hPartition; PPARTENTRY pPartitionEntry; DWORD dwBootPartitionSectorCount; #ifdef IMGMULTIXIP // Variable for sector count for the new BinFS region (EXT) DWORD dwExtPartitionSectorCount; #endif memset(®Info, 0, sizeof(PCI_REG_INFO)); regInfo.MemBase.Num = 1; regInfo.MemLen.Num = 1; regInfo.MemBase.Reg[0] = g_ulFlashBase; // Get flash info hFMD = FMD_Init(NULL, ®Info, NULL); if (hFMD == NULL) goto cleanUp; if (!FMD_GetInfo(&flashInfo)) goto cleanUp; FMD_Deinit(hFMD); // Initialize boot partition library if (!BP_Init((LPBYTE)g_ulBPartBase, g_ulBPartLengthBytes, NULL, ®Info, NULL)) { OALLog(L"BLConfigureFlashPartitions: Error initializing bootpart library!!\r\n"); goto cleanUp; } // Get boot partition size // Ensure boot partition uses entire blocks with no space left over // Round up to an even block size dwBootPartitionSectorCount = ((g_bootCfg.osPartitionSize + (flashInfo.dwBytesPerBlock - 1))/ flashInfo.dwBytesPerBlock) * flashInfo.wSectorsPerBlock; // Reduce by one to account for MBR, which will be the first sector in non reserved area. // This causes boot partition to end on a block boundary dwBootPartitionSectorCount -= 1; #ifdef IMGMULTIXIP // Calculation of the size for the EXT region dwExtPartitionSectorCount = ((IMAGE_WINCE_EXT_SIZE + (flashInfo.dwBytesPerBlock - 1))/ flashInfo.dwBytesPerBlock) * flashInfo.wSectorsPerBlock; dwExtPartitionSectorCount -= 1; #endif // Check for existence and size of OS boot partition hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, PART_BOOTSECTION, FALSE, PART_OPEN_EXISTING); if (hPartition == INVALID_HANDLE_VALUE) OALLog(L"OS partition does not exist!!\r\n"); else { pPartitionEntry = BP_GetPartitionInfo(hPartition); if (dwBootPartitionSectorCount != pPartitionEntry->Part_TotalSectors) { OALLog(L"OS partition does not match configured size!! Sector count expected: 0x%x, actual 0x%x\r\n", dwBootPartitionSectorCount, pPartitionEntry->Part_TotalSectors); // Mark handle invalid to kick us into formatting code hPartition = INVALID_HANDLE_VALUE; } } if ((hPartition == INVALID_HANDLE_VALUE) || (bForceEnable == TRUE)) { // OS binary partition either does not exist or does not match configured size OALLog(L"Formatting flash...\r\n"); // Create a new partion // Can't just call BP_OpenPartition with PART_OPEN_ALWAYS because it will erase reserved // blocks (bootloader) if MBR doesn't exist. Also, we want to ensure the boot partition // is actually the first partition on the flash. So do low level format here (note that // this destroys all other partitions on the device) // Note, we're skipping the block check for speed reasons. Might not want this in a production device... BP_LowLevelFormat (0, flashInfo.dwNumBlocks, FORMAT_SKIP_RESERVED|FORMAT_SKIP_BLOCK_CHECK); // Create the OS partition hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, dwBootPartitionSectorCount, PART_BOOTSECTION, FALSE, PART_CREATE_NEW); if (hPartition == INVALID_HANDLE_VALUE) { OALLog(L"Error creating OS partition!!\r\n"); goto cleanUp; } OALLog(L"NK partition created\r\n"); #ifdef IMGMULTIXIP // Creation of the BinFS partition hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, dwExtPartitionSectorCount, PART_BINFS, FALSE, PART_CREATE_NEW); if (hPartition == INVALID_HANDLE_VALUE) { OALLog(L"Error creating OS partition!!\r\n"); goto cleanUp; } OALLog(L"EXT partition created\r\n"); #endif // Create FAT partition on remaining flash (can be automatically mounted) hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, PART_DOS32, FALSE, PART_CREATE_NEW); if (hPartition == INVALID_HANDLE_VALUE) { OALLog(L"Error creating file partition!!\r\n"); goto cleanUp; } OALLog(L"Flash format complete!\r\n"); } // Done rc = TRUE; cleanUp: return rc; }
BOOL WriteFlashNK( UINT32 address, UINT32 size ) { BOOL rc = FALSE; BOOL bExt = FALSE; HANDLE hPartition; UCHAR *pData; PCI_REG_INFO regInfo; memset(®Info, 0, sizeof(PCI_REG_INFO)); regInfo.MemBase.Num = 1; regInfo.MemLen.Num = 1; regInfo.MemBase.Reg[0] = g_ulFlashBase; regInfo.MemLen.Reg[0] = g_ulFlashLengthBytes; // Get data location pData = OEMMapMemAddr(address, address); #ifdef IMGMULTIXIP // Checking if this is an EXT region if((address == (IMAGE_WINCE_EXT_CA + NAND_ROMOFFSET)) || (address == IMAGE_WINCE_EXT_CA) ) { bExt = TRUE; OALLog(L"\r\nWriting EXT image to OS partition, address=%x, SIZE=%x\r\n", address, size); } else if ((address == (IMAGE_WINCE_CODE_CA + NAND_ROMOFFSET) )|| (address == IMAGE_WINCE_CODE_CA)) #endif { OALLog(L"\r\nWriting NK image to OS partition address=%x, SIZE=%x\r\n", address, size); } // Verify that we get CE image. if (!VerifyImage(pData, NULL)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"NK image signature not found\r\n" )); rc = TRUE; goto cleanUp; } // Initialize boot partition library if (!BP_Init((LPBYTE)g_ulBPartBase, g_ulBPartLengthBytes, NULL, ®Info, NULL)) { OALLog(L"WriteFlashNK: Error initializing bootpart library!!\r\n"); goto cleanUp; } // Open partition based on region type hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, bExt ? PART_BINFS : PART_BOOTSECTION, FALSE, PART_OPEN_EXISTING); if (hPartition == INVALID_HANDLE_VALUE) { OALMSG(OAL_ERROR, (L"ERROR: OS partition not found!\r\n")); goto cleanUp; } // Check length against size of partition if (!BP_SetDataPointer(hPartition, size)) { OALMSG(OAL_ERROR, (L"ERROR: OS partition too small! Aborting...\r\n")); goto cleanUp; } // Write image to partition BP_SetDataPointer(hPartition, 0); if (!BP_WriteData(hPartition, pData, size)) { OALMSG(OAL_ERROR, (L"ERROR: Failed writing to OS partition!\r\n")); goto cleanUp; } //OALLog(L"%s image written\r\n", bExt ? L"EXT" :L"nk"); // Change boot device to NAND g_bootCfg.bootDevLoc.IfcType = Internal; g_bootCfg.bootDevLoc.LogicalLoc = BSP_NAND_REGS_PA + 0x20; // Done rc = TRUE; cleanUp: return rc; }
BOOL WriteFlashEXT( UINT32 address, UINT32 size ) { BOOL rc = FALSE; HANDLE hPartition; UCHAR *pData; PCI_REG_INFO regInfo; memset(®Info, 0, sizeof(PCI_REG_INFO)); regInfo.MemBase.Num = 1; regInfo.MemLen.Num = 1; regInfo.MemBase.Reg[0] = g_ulFlashBase; regInfo.MemLen.Reg[0] = g_ulFlashLengthBytes; // Get data location pData = OEMMapMemAddr(address, address); // Verify that we get CE image. if (!VerifyImage(pData, NULL)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"EXT image signature not found\r\n" )); rc = TRUE; goto cleanUp; } // Initialize boot partition library if (!BP_Init((LPBYTE)g_ulBPartBase, g_ulBPartLengthBytes, NULL, ®Info, NULL)) { OALLog(L"WriteFlashEXT: Error initializing bootpart library!!\r\n"); goto cleanUp; } // Open partition hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, PART_BINFS, FALSE, PART_OPEN_EXISTING); if (hPartition == INVALID_HANDLE_VALUE) { OALMSG(OAL_ERROR, (L"ERROR: OS partition not found!\r\n")); goto cleanUp; } // Check length against size of partition if (!BP_SetDataPointer(hPartition, size)) { OALMSG(OAL_ERROR, (L"ERROR: OS partition too small! Aborting...\r\n")); goto cleanUp; } // Write image to partition BP_SetDataPointer(hPartition, 0); if (!BP_WriteData(hPartition, pData, size)) { OALMSG(OAL_ERROR, (L"ERROR: Failed writing to OS partition!\r\n")); goto cleanUp; } OALLog(L"EXT image written, spin for ever!\r\n"); OALLog(L"EXT image written, spin for ever!\r\n"); for(;;); // Done //rc = TRUE; cleanUp: return rc; }
static UINT32 ReadFlashNK( ) { UINT32 rc = (UINT32) BL_ERROR; HANDLE hPartition; ROMHDR *pTOC; ULONG offset, size; UCHAR *pData; DWORD *pInfo; PCI_REG_INFO regInfo; memset(®Info, 0, sizeof(PCI_REG_INFO)); regInfo.MemBase.Num = 1; regInfo.MemLen.Num = 1; regInfo.MemBase.Reg[0] = g_ulFlashBase; regInfo.MemLen.Reg[0] = g_ulFlashLengthBytes; // Check if there is a valid image OALMSG(OAL_INFO, (L"\r\nLoad NK image from flash memory\r\n")); // Initialize boot partition library if (!BP_Init((LPBYTE)g_ulBPartBase, g_ulBPartLengthBytes, NULL, ®Info, NULL)) { OALLog(L"ReadFlashNK: Error initializing bootpart library!!\r\n"); goto cleanUp; } // Open OS boot partition hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, PART_BOOTSECTION, FALSE, PART_OPEN_EXISTING); if (hPartition == INVALID_HANDLE_VALUE) { OALMSG(OAL_ERROR, (L"ERROR: OS partition not found!\r\n")); goto cleanUp; } BP_SetDataPointer(hPartition, 0); // Set address where to place image pData = (UCHAR*)IMAGE_WINCE_CODE_CA; // First read 4kB with pointer to TOC offset = 0; size = 4096; if (!BP_ReadData(hPartition, pData + offset, size)) { OALMSG(OAL_ERROR, (L"ERROR: Error reading OS partition!\r\n")); goto cleanUp; } // Verify that we get CE image pInfo = (DWORD*)(pData + ROM_SIGNATURE_OFFSET); if (*pInfo != ROM_SIGNATURE) { OALMSG(OAL_ERROR, (L"ERROR: " L"Image signature not found\r\n" )); goto cleanUp; } // Read image up through actual TOC offset = size; size = pInfo[2] - size + sizeof(ROMHDR); if (!BP_ReadData(hPartition, pData + offset, size)) { OALMSG(OAL_ERROR, (L"ERROR: " L"BP_ReadData call failed!\r\n" )); goto cleanUp; } // Verify image if (!VerifyImage(pData, &pTOC)) { OALMSG(OAL_ERROR, (L"ERROR: " L"NK image doesn't have ROM signature\r\n" )); goto cleanUp; } // Read remainder of image offset += size; size = pTOC->physlast - pTOC->physfirst - offset; if (!BP_ReadData(hPartition, pData + offset, size)) { OALMSG(OAL_ERROR, (L"ERROR: " L"BP_ReadData call failed!\r\n" )); goto cleanUp; } OALMSG(OAL_INFO, (L"NK Image Loaded\r\n")); // Done g_eboot.launchAddress = OALVAtoPA((UCHAR*)IMAGE_WINCE_CODE_CA); rc = BL_JUMP; cleanUp: return rc; }