/* @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); }
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; }