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