//------------------------------------------------------------------------------ // // Function: OEMWriteFlash // // This function is called by the bootloader to write the image that may // be stored in a RAM file cache area to flash memory. // BOOL OEMWriteFlash(ULONG address, ULONG size) { BOOL rc = FALSE; VOID *pSource; OALMSG(OAL_FUNC, (L"+OEMWriteFlash(0x%08x, 0x%08x\r\n", address, size)); // First get location where data are pSource = OEMMapMemAddr(address, address); if (pSource == NULL) { OALMSG(OAL_ERROR, ( L"ERROR: OEMMapMemAddr failed for 0x%08x\r\n", address )); goto cleanUp; } OALMSG(OAL_WARN, ( L"Write flash memory at 0x%08x size 0x%08x...", address, size )); rc = OALFlashWrite( OALPAtoUA(IMAGE_FLASH_PA_START), OALPAtoUA((VOID*)address), size, pSource ); if (!rc) { OALMSG(OAL_ERROR, (L"\r\nERROR: Flash write failed\r\n")); goto cleanUp; } OALMSG(OAL_WARN, (L" Done\r\n")); cleanUp: OALMSG(OAL_FUNC, (L"-OEMWriteFlash(rc = %d)\r\n", rc)); return rc; }
BOOL WriteFlashNK( UINT32 address, UINT32 size ) { BOOL rc = FALSE; UCHAR *pData; void *pBase = OALPAtoVA(g_ulFlashBase, FALSE); void *pStart = (void *)((UINT32)pBase + IMAGE_WINCE_NOR_OFFSET); OALLog(L"\r\nWriting NK image to flash memory\r\n"); // Get data location pData = OEMMapMemAddr(address, address); // Verify that we get CE image if (!VerifyImage(pData, NULL)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: NK image signature not found\r\n")); goto cleanUp; } // Unlock blocks if (!OALFlashLock(pBase, pStart, size, FALSE)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: NK blocks could not be unlocked\r\n")); goto cleanUp; } // Erase blocks if (!OALFlashErase(pBase, pStart, size)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: NK blocks could not be erased\r\n")); goto cleanUp; } // Write blocks if (!OALFlashWrite(pBase, pStart, size, pData)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: NK blocks could not be written\r\n")); goto cleanUp; } OALLog(L"NK image written\r\n"); // Change boot device to NOR g_bootCfg.bootDevLoc.IfcType = Internal; g_bootCfg.bootDevLoc.LogicalLoc = BSP_NOR_REGS_PA; // Done rc = TRUE; cleanUp: return rc; }
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) { DWORD dwBlock = 0; DWORD dwNumBlocks = 0; LPBYTE pbBuffer; SectorInfo si; //unsigned int sectorchk; unsigned int sectorcnt = 0; unsigned int areachange = 0; OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n"))); if ( !g_bBootMediaExist ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if(dwLaunchAddr==0x10) { dwBlock = LOGO_BLOCK; //dwImageLength = UPLDR_RAM_IMAGE_SIZE; g_ImageType=IMAGE_TYPE_RAWBIN; }else{ if (g_ImageType == IMAGE_TYPE_LOADER) { dwBlock = EBOOT_BLOCK; if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: 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); } } } else if (g_ImageType == IMAGE_TYPE_STEPLDR) { dwBlock = STEPLDR_BLOCK; dwImageStart += dwLaunchAddr; //dwImageLength = 0x2050; //step loader can support 8k bytes. //dwImageLength = STEPLDR_RAM_IMAGE_SIZE; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } else if (g_ImageType == IMAGE_TYPE_DIONB0) { dwBlock = DIONB0_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength -= (dwImageLength / (g_FlashInfo.wDataBytesPerSector + 8))*8; } else if (g_ImageType == IMAGE_TYPE_UPLDR) { dwBlock = UPLDR_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength = UPLDR_RAM_IMAGE_SIZE; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } else if (g_ImageType == IMAGE_TYPE_FLASHBIN) { dwBlock = FLASHBIN_BLOCK; // dwImageStart += dwLaunchAddr; // dwImageLength = dwImageLength; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } } if(dwLaunchAddr==0x10) pbBuffer=(LPBYTE)dwImageStart; else pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart); // Compute number of blocks. dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0); OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength)); OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks)); while (dwNumBlocks--) { // If the block is marked bad, skip to next block. Note that the assumption in our error checking // is that any truely bad block will be marked either by the factory during production or will be marked // during the erase and write verification phases. If anything other than a bad block fails ECC correction // in this routine, it's fatal. OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock)); OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock)); OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock)); if (!FMD_EraseBlock(dwBlock)) { OALMSG(TRUE, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } // FMD_GetBlockStatus(dwBlock); if ((FMD_GetBlockStatus(dwBlock) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))&&dwBlock!=0) { OALMSG(TRUE, (TEXT("FMD_GetBlockStatus Error \r\n"))); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } //FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1); if (!FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1)) { OALMSG(TRUE, (TEXT("FMD_ReadSector : Failed to get block(0x%x)'s sector info.\r\n"), dwBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=0xfc )&&dwBlock!=0) { OALMSG(TRUE, (TEXT("si.bBadBlock failed, si.bOEMReserved %x,si.bBadBlock %x.\r\n"),si.bOEMReserved, si.bBadBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) { OALMSG(TRUE, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock)); return(FALSE); } if (g_ImageType == IMAGE_TYPE_DIONB0) { for ( int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector ++ ) { if (!WritePage(dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, pbBuffer, (PSectorInfo)(pbBuffer+g_FlashInfo.wDataBytesPerSector) )) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } pbBuffer += (g_FlashInfo.wDataBytesPerSector + 8); } ++dwBlock; } else if (g_ImageType == IMAGE_TYPE_FLASHBIN) { for ( int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector ++ ) { //RETAILMSG(1, (TEXT("WriteData: (0x%x)(0x%x,0x%x,0x%x).\r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, g_pSectorInfoBuf->dwReserved1, g_pSectorInfoBuf->bOEMReserved, g_pSectorInfoBuf->wReserved2)); if (!WritePage(dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, pbBuffer, (PSectorInfo)(pbBuffer+g_FlashInfo.wDataBytesPerSector) )) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); #ifdef IROMBOOT FMD_EraseBlock(dwBlock); // this block is actually considered to bad block. // because it may be erased initial bad block information. si.bOEMReserved = 0xff; si.bBadBlock = BADBLOCKMARK; si.dwReserved1 = 0xffffffff; si.wReserved2 = 0xffff; FMD_WriteSector(BLOCK_TO_SECTOR(dwBlock), NULL, &si, 1); pbBuffer -= (g_FlashInfo.wDataBytesPerSector + 8)*iSector; iSector = 0; break; #else return(FALSE); #endif // !IROMBOOT } pbBuffer += (g_FlashInfo.wDataBytesPerSector + 8); } ++dwBlock; } else { OALMSG(TRUE, (TEXT(" Write Reserved Area \n"))); if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } ++dwBlock; OALMSG(TRUE, (TEXT("pbBuffer + %x .\r\n"), SECTOR_SIZE/*SECTORS_PER_PAGE*/*PAGES_PER_BLOCK)); #ifdef IROMBOOT pbBuffer += (SECTOR_SIZE/*SECTORS_PER_PAGE*/*PAGES_PER_BLOCK); #else pbBuffer += 0x4000; #endif // !IROMBOOT } } if (g_ImageType == IMAGE_TYPE_LOADER) { g_pTOC->id[0].dwLoadAddress = dwImageStart; g_pTOC->id[0].dwJumpAddress = 0; g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength); g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK); g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors; } OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\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); }
//------------------------------------------------------------------------------ // // Function: OEMLaunch // // This function is the last one called by the boot framework and it is // responsible for to launching the image. // VOID OEMLaunch( ULONG start, ULONG size, ULONG launch, const ROMHDR *pRomHeader ) { BSP_ARGS *pArgs = OALCAtoUA(IMAGE_SHARE_ARGS_CA); UNREFERENCED_PARAMETER(size); UNREFERENCED_PARAMETER(pRomHeader); OALMSG(OAL_FUNC, ( L"+OEMLaunch(0x%08x, 0x%08x, 0x%08x, 0x%08x - %d/%d)\r\n", start, size, launch, pRomHeader, g_eboot.bootDeviceType, g_eboot.type )); // Depending on protocol there can be some action required switch (g_eboot.bootDeviceType) { #if BUILDING_EBOOT_SD case BOOT_SDCARD_TYPE: switch (g_eboot.type) { #if 0 /* case DOWNLOAD_TYPE_FLASHRAM: if (BLFlashDownload(&g_bootCfg, g_kitlDevices) != BL_JUMP) { OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: " L"Image load from flash memory failed\r\n" )); goto cleanUp; } launch = g_eboot.launchAddress; break; */ #endif case DOWNLOAD_TYPE_RAM: launch = (UINT32)OEMMapMemAddr(start, launch); break; case DOWNLOAD_TYPE_FLASHNAND: if (BLFlashDownload(&g_bootCfg, g_kitlDevices) != BL_JUMP) { OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: " L"Image load from flash memory failed\r\n" )); goto cleanUp; } launch = g_eboot.launchAddress; break; #if 0 /* case DOWNLOAD_TYPE_EBOOT: case DOWNLOAD_TYPE_XLDR: OALMSG(OAL_INFO, (L"INFO: " L"XLDR/EBOOT/IPL downloaded, spin forever\r\n" )); while (TRUE); break; */ #endif default: OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: Unknown download type, spin forever\r\n")); for(;;); break; } break; #endif case OAL_KITL_TYPE_ETH: BLEthConfig(pArgs); switch (g_eboot.type) { case DOWNLOAD_TYPE_FLASHNAND: case DOWNLOAD_TYPE_FLASHNOR: if (BLFlashDownload(&g_bootCfg, g_kitlDevices) != BL_JUMP) { OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: " L"Image load from flash memory failed\r\n" )); goto cleanUp; } launch = g_eboot.launchAddress; break; case DOWNLOAD_TYPE_RAM: launch = (UINT32)OEMMapMemAddr(start, launch); break; case DOWNLOAD_TYPE_EBOOT: case DOWNLOAD_TYPE_XLDR: OALMSG(OAL_INFO, (L"INFO: " L"XLDR/EBOOT/IPL downloaded, spin forever\r\n" )); for(;;); break; case DOWNLOAD_TYPE_LOGO: OALMSG(OAL_INFO, (L"INFO: " L"Splashcreen logo downloaded, spin forever\r\n" )); for(;;); break; default: OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: Unknown download type, spin forever\r\n")); for(;;); break; } break; default: launch = g_eboot.launchAddress; break; } #ifndef BSP_NO_NAND_IN_SDBOOT if ((g_bootCfg.flashNKFlags & ENABLE_FLASH_NK) && /* if loading from NAND then do not need to flash NAND again */ (g_eboot.bootDeviceType != OAL_KITL_TYPE_FLASH) && (start != (IMAGE_WINCE_CODE_CA + NAND_ROMOFFSET)) && (start != (IMAGE_WINCE_CODE_CA + NOR_ROMOFFSET))) { if( !WriteFlashNK(start, size)) OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: " L"Flash NK.bin failed, start=%x\r\n", start )); } #endif // Check if we get launch address if (launch == (UINT32)INVALID_HANDLE_VALUE) { OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: " L"Unknown image launch address, spin forever\r\n" )); for(;;); } // Print message, flush caches and jump to image OALLog( L"Launch Windows CE image by jumping to 0x%08x...\r\n\r\n", launch ); OEMDeinitDebugSerial(); OEMPlatformDeinit(); JumpTo(OALVAtoPA((UCHAR*)launch)); cleanUp: return; }
BOOL WriteFlashLogo( UINT32 address, UINT32 size ) { BOOL rc = FALSE; HANDLE hFlash = NULL; UINT8 *pData; UINT32 offset; OALMSG(OAL_INFO, (L"\r\nWriting Splashcreen image to flash memory\r\n")); // Open flash storage hFlash = OALFlashStoreOpen(g_ulFlashBase); if (hFlash == NULL) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"OALFlashStoreOpen call failed!\r\n" )); goto cleanUp; } // Check if image fit (last sector used for configuration) if (size > (IMAGE_BOOTLOADER_BITMAP_SIZE - OALFlashStoreSectorSize(hFlash))) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"Logo image too big (size 0x%08x, maximum size 0x%08x)\r\n", size, IMAGE_BOOTLOADER_BITMAP_SIZE - OALFlashStoreBlockSize(hFlash) )); goto cleanUp; } // Get data location pData = OEMMapMemAddr(address, address); // Fill unused space with 0xFF if (size < IMAGE_BOOTLOADER_BITMAP_SIZE) { memset(pData + size, 0xFF, IMAGE_BOOTLOADER_BITMAP_SIZE - size); } offset = IMAGE_XLDR_BOOTSEC_NAND_SIZE + IMAGE_EBOOT_BOOTSEC_NAND_SIZE; if (!OALFlashStoreWrite( hFlash, offset, pData, IMAGE_BOOTLOADER_BITMAP_SIZE, FALSE, FALSE )) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"OALFlashStoreWrite at relative address 0x%08x failed\r\n", offset )); goto cleanUp; } OALMSG(OAL_INFO, (L"Splashcreen image written\r\n")); // Done rc = TRUE; cleanUp: if (hFlash != NULL) OALFlashStoreClose(hFlash); 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 WriteFlashXLDR( UINT32 address, UINT32 size ) { BOOL rc = FALSE; HANDLE hFlash = NULL; ROMHDR *pTOC; UINT32 offset, xldrSize, blocknum, blocksize; UINT8 *pData; UNREFERENCED_PARAMETER(size); OALMSG(OAL_INFO, (L"\r\nWriting XLDR image to flash memory\r\n")); // Open flash storage hFlash = OALFlashStoreOpen(g_ulFlashBase); if (hFlash == NULL) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"OALFlashStoreOpen call failed!\r\n" )); goto cleanUp; } // Get data location pData = OEMMapMemAddr(address, address); // Verify image if (!VerifyImage(pData, &pTOC)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"XLDR image signature not found\r\n" )); } // Verify that this is XLDR image if (pTOC->numfiles > 0 || pTOC->nummods > 1) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"XLDR image must have only one module and no file\r\n" )); goto cleanUp; } // Check for maximal XLRD size xldrSize = pTOC->physlast - pTOC->physfirst; if (xldrSize > (IMAGE_XLDR_CODE_SIZE - 2*sizeof(DWORD)) ) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"XLDR image size 0x%04x doesn't fit to limit 0x%04x\r\n", size, IMAGE_XLDR_CODE_SIZE - 2*sizeof(DWORD) )); goto cleanUp; } blocksize = OALFlashStoreBlockSize(hFlash); if (blocksize < IMAGE_XLDR_CODE_SIZE) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"XLDR image size 0x%04x doesn't fit to flash block size 0x%04x\r\n", IMAGE_XLDR_CODE_SIZE, blocksize )); goto cleanUp; } // First we have to offset image by 2 DWORDS to insert BootROM header memmove(pData + 2*sizeof(DWORD), pData, xldrSize); // Insert BootROM header ((DWORD*)pData)[0] = IMAGE_XLDR_CODE_SIZE - 2*sizeof(DWORD); // Max size of image ((DWORD*)pData)[1] = IMAGE_XLDR_CODE_PA; // Load address // Now copy into first four blocks per boot ROM requirement. // Internal boot ROM expects the loader to be duplicated in the first 4 blocks for // data redundancy. Note that block size of memory used on this platform is larger // than xldr size so there will be a gap in each block. offset = 0; for (blocknum = 0; blocknum < 4; blocknum++) { if (!OALFlashStoreWrite( hFlash, offset, pData, IMAGE_XLDR_CODE_SIZE, FALSE, FALSE )) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"OALFlashStoreWrite at relative address 0x%08x failed\r\n", offset )); } offset += blocksize; } OALMSG(OAL_INFO, (L"XLDR image written\r\n")); // Done rc = TRUE; cleanUp: if (hFlash != NULL) OALFlashStoreClose(hFlash); 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; }
BOOL WriteFlashEBOOT( UINT32 address, UINT32 size ) { void *pData; void *pBase = OALPAtoVA(g_ulFlashBase, FALSE); void *pStart = (void *)((UINT32)pBase + IMAGE_EBOOT_NOR_OFFSET); BOOL rc = FALSE; OALMSG(OAL_INFO, (L"\r\nWriting EBOOT image to flash memory\r\n")); // Check if image fit (last sector used for configuration) if (size > IMAGE_EBOOT_CODE_SIZE) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT image too big (size 0x%08x, maximum size 0x%08x)\r\n", size, IMAGE_EBOOT_CODE_SIZE)); goto cleanUp; } // Get data location pData = OEMMapMemAddr(address, address); // Verify that we get CE image if (!VerifyImage(pData, NULL)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT image signature not found\r\n")); goto cleanUp; } // Fill unused space with 0xFF if (size < IMAGE_EBOOT_CODE_SIZE) { memset((void *)((UINT32)pData + size), 0xFF, IMAGE_EBOOT_CODE_SIZE - size); } // Unlock blocks if (!OALFlashLock(pBase, pStart, size, FALSE)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT blocks could not be unlocked\r\n")); goto cleanUp; } // Erase blocks if (!OALFlashErase(pBase, pStart, size)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT blocks could not be erased\r\n")); goto cleanUp; } // Write blocks if (!OALFlashWrite(pBase, pStart, size, pData)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT blocks could not be written\r\n")); goto cleanUp; } OALMSG(OAL_INFO, (L"EBOOT image written\r\n")); // Done rc = TRUE; cleanUp: return rc; }
BOOL WriteFlashXLDR( UINT32 address, UINT32 size ) { ROMHDR *pTOC; UINT8 *pData; void *pBase = OALPAtoVA(g_ulFlashBase, FALSE); void *pStart = (void *)((UINT32)pBase + IMAGE_XLDR_NOR_OFFSET); UINT32 xldrSize; BOOL rc = FALSE; OALMSG(OAL_INFO, (L"\r\nWriting XLDR image to flash memory\r\n")); // Get data location pData = OEMMapMemAddr(address, address); // Verify image if (!VerifyImage(pData, &pTOC)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR image signature not found\r\n")); goto cleanUp; } // Verify that this is XLDR image if (pTOC->numfiles > 0 || pTOC->nummods > 1) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR image must have only one module and no file\r\n")); goto cleanUp; } // Check for maximal XLRD size xldrSize = pTOC->physlast - pTOC->physfirst; if (xldrSize > IMAGE_XLDR_CODE_SIZE) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR image size 0x%04x doesn't fit to limit 0x%04x\r\n", size, IMAGE_XLDR_CODE_SIZE)); goto cleanUp; } // Unlock blocks if (!OALFlashLock(pBase, pStart, size, FALSE)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR blocks could not be unlocked\r\n")); goto cleanUp; } // Erase blocks if (!OALFlashErase(pBase, pStart, size)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR blocks could not be erased\r\n")); goto cleanUp; } // Write blocks if (!OALFlashWrite(pBase, pStart, size, pData)) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR blocks could not be written\r\n")); goto cleanUp; } // Done rc = TRUE; cleanUp: return rc; }
BOOL WriteFlashNK(UINT32 address, UINT32 size) { BOOL rc = FALSE; HANDLE hFMD; FlashInfo flashInfo; SectorInfo sectorInfo; BOOL ok = FALSE; BLOCK_ID block; //ROMHDR *pTOC; UINT32 *pInfo, count, sector; UINT32 blockSize, sectorSize, sectorsPerBlock; UINT8 *pData; OALMSG(OAL_INFO, (L"OEMWriteFlash: Writing NK image to flash\r\n")); // We need to know sector/block size if ((hFMD = FMD_Init(NULL, NULL, NULL)) == NULL) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"FMD_Init call failed\r\n" )); goto cleanUp; } // Get flash info if (!FMD_GetInfo(&flashInfo)) { OALMSG(OAL_ERROR, (L"ERROR: EBOOT!OEMWriteFlash: " L"FMD_GetInfo call failed!\r\n" )); FMD_Deinit(hFMD); goto cleanUp; } // We don't need access to FMD library FMD_Deinit(hFMD); OALMSG(OAL_INFO, (L"OEMWriteFlash: " L"Flash has %d blocks, %d bytes/block, %d sectors/block\r\n", flashInfo.dwNumBlocks, flashInfo.dwBytesPerBlock, flashInfo.wSectorsPerBlock )); // Make block & sector size ready blockSize = flashInfo.dwBytesPerBlock; sectorSize = flashInfo.wDataBytesPerSector; sectorsPerBlock = flashInfo.wSectorsPerBlock; // Get data location pData = OEMMapMemAddr(address, address); // Verify that we get CE image. pInfo = (UINT32*)(pData + ROM_SIGNATURE_OFFSET); if (*pInfo++ != ROM_SIGNATURE) { OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: " L"Image Signature not found\r\n" )); goto cleanUp; } pInfo++; // Skip reserved blocks block = 0; while (block < flashInfo.dwNumBlocks) { if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) { OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: " L"Skip bad block %d\r\n", block )); block++; continue; } if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_RESERVED) == 0) break; block++; } OALMSG(OAL_INFO, (L"OEMWriteFlash: " L"NK image starts at block %d\r\n", block )); // Write image count = 0; while (count < size && block < flashInfo.dwNumBlocks) { // If block is bad, we have to offset it if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) { block++; OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: " L"Skip bad block %d\r\n", block )); continue; } // Erase block if (!EraseBlock(block)) { FMD_SetBlockStatus(block, BLOCK_STATUS_BAD); block++; OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: " L"Block %d erase failed, mark block as bad\r\n", block )); continue; } // Now write sectors sector = 0; while (sector < sectorsPerBlock && count < size) { // Prepare sector info memset(§orInfo, 0xFF, sizeof(sectorInfo)); sectorInfo.dwReserved1 = 0; sectorInfo.wReserved2 = 0; // Write sector if (!(ok = WriteSector( block * sectorsPerBlock + sector, pData + count, §orInfo ))) break; // Move to next sector count += sectorSize; sector++; } // When sector write failed, mark block as bad and move back if (!ok) { OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: " L"Block %d sector %d write failed, mark block as bad\r\n", block, sector )); // First move back count -= sector * flashInfo.wDataBytesPerSector; // Mark block as bad FMD_SetBlockStatus(block, BLOCK_STATUS_BAD); } // We are done with block block++; } // Erase rest of media while (block < flashInfo.dwNumBlocks) { // If block is bad, we have to offset it if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) { block++; OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: " L"Skip bad block %d\r\n", block )); continue; } // When erase failed, mark block as bad and skip it if (!EraseBlock(block)) { FMD_SetBlockStatus(block, BLOCK_STATUS_BAD); block++; OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: " L"Block %d erase failed, mark block as bad\r\n", block )); continue; } // Move to next block block++; } // Close FMD driver FMD_Deinit(hFMD); hFMD = NULL; OALMSG(OAL_INFO, (L"OEMWriteFlash: NK written\r\n")); // Done rc = TRUE; cleanUp: if (hFMD != NULL) FMD_Deinit(hFMD); return rc; }
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) { DWORD dwBlock,dwNumBlocks; LPBYTE pbBuffer; SectorInfo si; OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n"))); if ( !g_bBootMediaExist ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if (g_ImageType == IMAGE_TYPE_LOADER) { dwBlock = EBOOT_BLOCK; if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: 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); } } } else if (g_ImageType == IMAGE_TYPE_STEPLDR) { dwBlock = NBOOT_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength = STEPPINGSTONE_SIZE; //step loader can support 8k bytes. } pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart); // Compute number of blocks. //dwNumBlocks = (dwImageLength / 0x4000) + 1; dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0); OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength)); OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks)); while (dwNumBlocks--) { // If the block is marked bad, skip to next block. Note that the assumption in our error checking // is that any truely bad block will be marked either by the factory during production or will be marked // during the erase and write verification phases. If anything other than a bad block fails ECC correction // in this routine, it's fatal. OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock)); OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock)); OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock)); FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1); // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == BADBLOCKMARK) && (si.bOEMReserved != 0xFC )) { ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock)); return(FALSE); } if (!FMD_EraseBlock(dwBlock)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock)); return FALSE; } if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } ++dwBlock; pbBuffer += g_FlashInfo.dwBytesPerBlock; //c ksk 20060311 OALMSG(TRUE, (TEXT("dwBytesPerBlock : %d\r\n"), g_FlashInfo.dwBytesPerBlock)); } if (g_ImageType == IMAGE_TYPE_LOADER) { g_pTOC->id[0].dwLoadAddress = dwImageStart; g_pTOC->id[0].dwJumpAddress = 0; g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength); g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK); g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors; } OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n"))); return TRUE; }
VOID BLWriteFlashNK(OAL_BLMENU_ITEM *pMenu) { DWORD i = 0; UCHAR ch; DWORD dwImageStart, dwImageLength, dwRecAddr, dwRecLen, dwRecChk; DWORD dwRecNum = 0; LPBYTE lpDest = NULL; OAL_KITL_TYPE bkType; wcscpy(g_bootCfg.filename, L"nk.bin"); if (BL_ERROR == BLSDCardDownload(g_bootCfg.filename)) { OALLog(TEXT("SD boot failed to open file\r\n")); goto CleanUp; } bkType = g_eboot.type; g_eboot.bootDeviceType = BOOT_SDCARD_TYPE; g_eboot.type = DOWNLOAD_TYPE_RAM; for (i=0; i < 7; i++) OEMReadData(1, &ch); if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageStart) || !OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageLength)) { KITLOutputDebugString ("Unable to read image start/length\r\n"); return ; } while ( OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr) && OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen) && OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk) ) { KITLOutputDebugString(" <> Record [ %d ] dwRecAddr = 0x%x, dwRecLen = 0x%x\r\n", dwRecNum, dwRecAddr, dwRecLen); dwRecNum++; // last record of .bin file uses sentinel values for address and checksum. if (!dwRecAddr && !dwRecChk) { break; } // map the record address (FLASH data is cached, for example) lpDest = OEMMapMemAddr (dwImageStart, dwRecAddr); // read data block if (!OEMReadData (dwRecLen, lpDest)) { KITLOutputDebugString ("****** Data record %d corrupted, ABORT!!! ******\r\n", dwRecNum); return ; } if (!VerifyChecksum (dwRecLen, lpDest, dwRecChk)) { KITLOutputDebugString ("****** Checksum failure on record %d, ABORT!!! ******\r\n", dwRecNum); return ; } // Look for ROMHDR to compute ROM offset. NOTE: romimage guarantees that the record containing // the TOC signature and pointer will always come before the record that contains the ROMHDR contents. // if (dwRecLen == sizeof(ROMHDR) && (*(LPDWORD) OEMMapMemAddr(dwImageStart, dwImageStart+ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)) { DWORD dwTempOffset = (dwRecAddr - *(LPDWORD)OEMMapMemAddr(dwImageStart, dwImageStart+ ROM_SIGNATURE_OFFSET + sizeof(ULONG))); ROMHDR *pROMHdr = (ROMHDR *)lpDest; // Check to make sure this record really contains the ROMHDR. // if ((pROMHdr->physfirst == (dwImageStart - dwTempOffset)) && (pROMHdr->physlast == (dwImageStart - dwTempOffset + dwImageLength)) && (DWORD)(HIWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast) && (DWORD)(LOWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast)) { KITLOutputDebugString("rom_offset=0x%x.\r\n", dwTempOffset); } } } // while( records remaining ) g_eboot.bootDeviceType = bkType; //g_eboot.type = DOWNLOAD_TYPE_RAM; g_eboot.type = DOWNLOAD_TYPE_FLASHNAND; if (OEMWriteFlash(dwImageStart, dwImageLength)) OALLog(L"BLWriteFlashNK success..\n"); else OALLog(L"BLWriteFlashNK fail..\n"); //write boot device for nand flash if (BLWriteBootCfg(&g_bootCfg)) { OALLog(L" Current settings has been saved\r\n"); } else { OALLog(L"ERROR: Settings save failed!\r\n"); } CleanUp: return; }