📄 nand.c
字号:
EdbgOutputDebugString("WARNING: NAND device doesn't exist - unable to store image.\r\n");
return(FALSE);
}
EdbgOutputDebugString("INFO: Writing IPL image to NAND (please wait)...\r\n");
if (!FMD_GetInfo(&flashInfo))
{
EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
return(FALSE);
}
// Make sure IPL length does not exceed reserved NAND size
if (dwLength > IMAGE_BOOT_IPLIMAGE_NAND_SIZE)
{
EdbgOutputDebugString("ERROR: IPL size exceeds reserved NAND region (size = 0x%x)\r\n", dwLength);
return(FALSE);
}
// Calculate the physical block range for the IPL image
startBlockID = IMAGE_BOOT_IPLIMAGE_NAND_OFFSET / flashInfo.dwBytesPerBlock;
endBlockID = startBlockID + (IMAGE_BOOT_IPLIMAGE_NAND_SIZE / flashInfo.dwBytesPerBlock);
EdbgOutputDebugString("INFO: Erasing NAND flash blocks [0x%x - 0x%x].\r\n", startBlockID, endBlockID);
// Erase range of NAND blocks reserved for IPL
for (blockID = startBlockID; blockID < endBlockID; blockID++)
{
// Skip bad blocks
if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
{
EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
continue;
}
// Erase the block...
if (!FMD_EraseBlock(blockID))
{
EdbgOutputDebugString("ERROR: Unable to erase NAND flash block [0x%x].\r\n", blockID);
return(FALSE);
}
}
// Get cached image location
pImage = OEMMapMemAddr(dwStartAddr, dwStartAddr);
// Fill unused space with 0xFF
memset(pImage + dwLength, 0xFF, (IMAGE_BOOT_IPLIMAGE_NAND_SIZE) - dwLength);
EdbgOutputDebugString("INFO: Programming IPL image from flash cache address 0x%x, size = %d\r\n", pImage, dwLength);
sectorInfo.dwReserved1 = 0xFFFFFFFF;
sectorInfo.bOEMReserved = 0x00;
sectorInfo.bBadBlock = 0xFF;
sectorInfo.wReserved2 = 0xFFFF;
// Write IPL to NAND flash
pSectorBuf = pImage;
for (blockID = startBlockID; blockID < endBlockID; blockID++)
{
// Skip bad blocks
if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
{
EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
continue;
}
// Compute sector address based on current physical block
startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
{
if (!FMD_WriteSector(sectorAddr, pSectorBuf, §orInfo, 1))
{
EdbgOutputDebugString("ERROR: Failed to update IPL.\r\n");
return(FALSE);
}
pSectorBuf += flashInfo.wDataBytesPerSector;
}
}
// Read IPL from NAND flash to verify contents
pSectorBuf = pImage + IMAGE_BOOT_IPLIMAGE_NAND_SIZE;
for (blockID = startBlockID; blockID < endBlockID ; blockID++)
{
// Skip bad blocks
if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
{
EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
continue;
}
// Compute sector address based on current physical block
startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
{
if (!FMD_ReadSector(sectorAddr, pSectorBuf, §orInfo, 1))
{
EdbgOutputDebugString("ERROR: Failed to update IPL.\r\n");
return(FALSE);
}
pSectorBuf += flashInfo.wDataBytesPerSector;
}
}
EdbgOutputDebugString("INFO: Verifying image.\r\n");
if (memcmp(pImage, pImage + IMAGE_BOOT_IPLIMAGE_NAND_SIZE, IMAGE_BOOT_IPLIMAGE_NAND_SIZE) != 0)
{
EdbgOutputDebugString("ERROR: Failed to verify IPL.\r\n");
}
EdbgOutputDebugString("INFO: Update of IPL completed successfully.\r\n");
return(TRUE);
}
//-----------------------------------------------------------------------------
//
// Function: NANDWriteNK
//
// This function writes to NAND flash memory the OS image stored
// in the RAM file cache area.
//
// Parameters:
// dwStartAddr
// [in] Address in flash memory where the start of the downloaded
// OS image is to be written.
//
// dwLength
// [in] Length of the OS image, in bytes, to be written to flash
// memory.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDWriteNK(DWORD dwStartAddr, DWORD dwLength)
{
FlashInfo flashInfo;
LPBYTE pSectorBuf, pImage;
SectorInfo sectorInfo;
BLOCK_ID blockID, startBlockID, endBlockID;
SECTOR_ADDR sectorAddr, startSectorAddr, endSectorAddr;
UINT32 percentComplete, lastPercentComplete;
// Check for NAND device availability
//
if (!g_bNandExist)
{
EdbgOutputDebugString("WARNING: NAND device doesn't exist - unable to store image.\r\n");
return(FALSE);
}
EdbgOutputDebugString("INFO: Writing NK image to NAND (please wait)...\r\n");
if (!FMD_GetInfo(&flashInfo))
{
EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
return(FALSE);
}
// Make sure NK length does not exceed reserved NAND size
if (dwLength > IMAGE_BOOT_NKIMAGE_NAND_SIZE)
{
EdbgOutputDebugString("ERROR: NK size exceeds reserved NAND region (size = 0x%x)\r\n", dwLength);
return(FALSE);
}
// Calculate the physical block range for the NK image
startBlockID = IMAGE_BOOT_NKIMAGE_NAND_OFFSET / flashInfo.dwBytesPerBlock;
endBlockID = startBlockID + (IMAGE_BOOT_NKIMAGE_NAND_SIZE / flashInfo.dwBytesPerBlock);
EdbgOutputDebugString("INFO: Erasing NAND flash blocks [0x%x - 0x%x].\r\n", startBlockID, endBlockID);
lastPercentComplete = 0;
// Erase range of NAND blocks reserved for NK
for (blockID = startBlockID; blockID < endBlockID; blockID++)
{
// Skip bad blocks
if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
{
EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
continue;
}
// Erase the block...
if (!FMD_EraseBlock(blockID))
{
EdbgOutputDebugString("ERROR: Unable to erase NAND flash block [0x%x].\r\n", blockID);
return(FALSE);
}
}
// Get cached image location
pImage = OEMMapMemAddr(dwStartAddr, dwStartAddr);
// Fill unused space with 0xFF
memset(pImage + dwLength, 0xFF, (IMAGE_BOOT_NKIMAGE_NAND_SIZE) - dwLength);
EdbgOutputDebugString("INFO: Programming NK image from flash cache address 0x%x, size = %d\r\n", pImage, dwLength);
sectorInfo.dwReserved1 = 0xFFFFFFFF;
sectorInfo.bOEMReserved = 0x00;
sectorInfo.bBadBlock = 0xFF;
sectorInfo.wReserved2 = 0xFFFF;
// Write NK to NAND flash
pSectorBuf = pImage;
lastPercentComplete = 0;
for (blockID = startBlockID; blockID < endBlockID; blockID++)
{
// Skip bad blocks
if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
{
EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
continue;
}
// Compute sector address based on current physical block
startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
{
if (!FMD_WriteSector(sectorAddr, pSectorBuf, §orInfo, 1))
{
EdbgOutputDebugString("ERROR: Failed to update NK.\r\n");
return(FALSE);
}
pSectorBuf += flashInfo.wDataBytesPerSector;
}
percentComplete = 100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);
// If percentage complete has changed, show the progress
if (lastPercentComplete != percentComplete)
{
lastPercentComplete = percentComplete;
OEMWriteDebugByte('\r');
EdbgOutputDebugString("INFO: Program is %d%% complete.", percentComplete);
}
}
EdbgOutputDebugString("\r\nINFO: Reading image in NAND for verification.\r\n");
// Read NK from NAND flash to verify contents
pSectorBuf = pImage + IMAGE_BOOT_NKIMAGE_NAND_SIZE;
lastPercentComplete = 0;
for (blockID = startBlockID; blockID < endBlockID ; blockID++)
{
// Skip bad blocks
if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
{
EdbgOutputDebugString("\r\nINFO: Found bad NAND flash block [0x%x].\r\n", blockID);
continue;
}
// Compute sector address based on current physical block
startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
{
if (!FMD_ReadSector(sectorAddr, pSectorBuf, §orInfo, 1))
{
EdbgOutputDebugString("\r\nERROR: Failed to update NK.\r\n");
return(FALSE);
}
pSectorBuf += flashInfo.wDataBytesPerSector;
}
percentComplete = 100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);
// If percentage complete has changed, show the progress
if (lastPercentComplete != percentComplete)
{
lastPercentComplete = percentComplete;
OEMWriteDebugByte('\r');
EdbgOutputDebugString("INFO: Read is %d%% complete.", percentComplete);
}
}
EdbgOutputDebugString("\nINFO: Verifying image.\r\n");
if (memcmp(pImage, pImage + IMAGE_BOOT_NKIMAGE_NAND_SIZE, IMAGE_BOOT_NKIMAGE_NAND_SIZE) != 0)
{
EdbgOutputDebugString("ERROR: Failed to verify NK.\r\n");
}
EdbgOutputDebugString("INFO: Update of NK completed successfully.\r\n");
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: IsSectorEmpty
//
// N/A
//
// Parameters:
// None.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL IsSectorEmpty(UCHAR *pData, ULONG sectorSize, SectorInfo *pSectorInfo)
{
BOOL rc = FALSE;
ULONG idx;
if (pSectorInfo->dwReserved1 != 0xFFFFFFFF) goto cleanUp;
if (pSectorInfo->wReserved2 != 0xFFFF) goto cleanUp;
if (pSectorInfo->bOEMReserved != 0xFF) goto cleanUp;
for (idx = 0; idx < sectorSize; idx++)
{
if (pData[idx] != 0xFF)
goto cleanUp;
}
rc = TRUE;
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
//
// Function: NANDStartWriteBinDIO
//
// N/A
//
// Parameters:
// None.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDStartWriteBinDIO(DWORD dwStartAddr, DWORD dwLength)
{
BLOCK_ID blockID, startBlockID, endBlockID;
UINT32 percentComplete, lastPercentComplete = 0;
// Check for NAND device availability
//
if (!g_bNandExist)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -