📄 nand.c
字号:
// 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);
// Set image load address
pSectorBuf = (LPBYTE) OALPAtoUA(IMAGE_BOOT_NKIMAGE_RAM_PA_START);
EdbgOutputDebugString("INFO: Copying NK image to RAM address 0x%x\r\n", pSectorBuf);
lastPercentComplete = 0;
// Copy NK from NAND flash to RAM
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 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: Load is %d%% complete.", percentComplete);
}
}
EdbgOutputDebugString("\r\nINFO: Copy of NK completed successfully.\r\n");
return(TRUE);
}
//-----------------------------------------------------------------------------
//
// Function: NANDFormatNK
//
// This function formats (erases) the NAND flash region reserved for OS
// images.
//
// Parameters:
// None.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDFormatNK(void)
{
FlashInfo flashInfo;
BLOCK_ID blockID, startBlockID, endBlockID;
UINT32 percentComplete, lastPercentComplete;
// Get NAND flash data bytes per sector.
//
if (!FMD_GetInfo(&flashInfo))
{
EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
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: Starting format of NAND NK region.\r\n");
lastPercentComplete = 0;
for (blockID = startBlockID; blockID < endBlockID ; blockID++)
{
// Is the block bad?
//
if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
{
EdbgOutputDebugString("\r\nINFO: Found bad NAND flash block [0x%x].\r\n", blockID);
continue;
}
// Erase the block...
//
if (!FMD_EraseBlock(blockID))
{
EdbgOutputDebugString("\r\nERROR: Unable to erase NAND flash block 0x%x.\r\n", blockID);
return(FALSE);
}
else
{
percentComplete = 100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);
// If percentage complete has changed, show the progress
if (lastPercentComplete != percentComplete)
{
lastPercentComplete = percentComplete;
OEMWriteDebugByte('\r');
EdbgOutputDebugString("INFO: Format is %d%% complete.", percentComplete);
}
}
}
EdbgOutputDebugString("\r\nINFO: Format of NAND NK region completed successfully.\r\n");
return(TRUE);
}
//-----------------------------------------------------------------------------
//
// Function: NANDFormatAll
//
// This function formats (erases) the entire NAND flash memory.
//
// Parameters:
// None.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDFormatAll(void)
{
FlashInfo flashInfo;
BLOCK_ID blockID, startBlockID, endBlockID;
UINT32 percentComplete, lastPercentComplete;
// Get NAND flash data bytes per sector.
//
if (!FMD_GetInfo(&flashInfo))
{
EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
return(FALSE);
}
// Calculate the physical block range for the enrire NAND device
startBlockID = 0;
endBlockID = flashInfo.dwNumBlocks;
EdbgOutputDebugString("INFO: Starting format of all NAND regions.\r\n");
lastPercentComplete = 0;
for (blockID = startBlockID; blockID < endBlockID ; blockID++)
{
// Is the block bad?
//
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);
}
else
{
percentComplete = 100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);
// If percentage complete has changed, show the progress
if (lastPercentComplete != percentComplete)
{
lastPercentComplete = percentComplete;
OEMWriteDebugByte('\r');
EdbgOutputDebugString("INFO: Format is %d%% complete.", percentComplete);
}
}
}
EdbgOutputDebugString("\r\nINFO: Format of all NAND regions completed successfully.\r\n");
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: NANDLoadEBootCFG
//
// Retrieves bootloader configuration information (menu settings, etc.) from
// the NAND flash.
//
// Parameters:
// eBootCFG
// [out] Points to bootloader configuration that will be filled with
// loaded data.
//
// cbBootCfgSize
// [in] Size in bytes of the bootloader configuration.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDLoadEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize)
{
BOOL rc = FALSE;
FlashInfo flashInfo;
BLOCK_ID blockID, startBlockID, endBlockID;
SECTOR_ADDR sectorAddr;
if (!FMD_GetInfo(&flashInfo))
{
EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
return(FALSE);
}
// Calculate the physical block range for the boot configuration
startBlockID = IMAGE_BOOT_BOOTCFG_NAND_OFFSET / flashInfo.dwBytesPerBlock;
endBlockID = startBlockID + (IMAGE_BOOT_BOOTCFG_NAND_SIZE / flashInfo.dwBytesPerBlock);
EdbgOutputDebugString("INFO: Loading boot configuration from NAND\r\n");
// Find a good block and load the boot configuration
for (blockID = startBlockID; (blockID < endBlockID) && (rc == FALSE) ; 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
sectorAddr = blockID * flashInfo.wSectorsPerBlock;
rc = FMD_ReadSector(sectorAddr, sectorBuf, NULL, 1);
}
if (rc)
{
memcpy(pBootCfg, sectorBuf, cbBootCfgSize);
}
else
{
EdbgOutputDebugString("ERROR: Failed to load boot configuration from NAND\r\n");
}
return rc;
}
//------------------------------------------------------------------------------
//
// Function: NANDStoreEBootCFG
//
// Stores bootloader configuration information (menu settings, etc.) to
// the NAND flash.
//
// Parameters:
// eBootCFG
// [out] Points to bootloader configuration that will be stored.
//
// cbBootCfgSize
// [in] Size in bytes of the bootloader configuration.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDStoreEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize)
{
FlashInfo flashInfo;
SectorInfo sectorInfo;
BLOCK_ID blockID, startBlockID, endBlockID;
SECTOR_ADDR sectorAddr, startSectorAddr, endSectorAddr;
if (!FMD_GetInfo(&flashInfo))
{
EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
return(FALSE);
}
memcpy(sectorBuf, pBootCfg, cbBootCfgSize);
memset(sectorBuf + cbBootCfgSize, 0xFF, 2048 - cbBootCfgSize);
sectorInfo.dwReserved1 = 0xFFFFFFFF;
sectorInfo.bOEMReserved = 0x00;
sectorInfo.bBadBlock = 0xFF;
sectorInfo.wReserved2 = 0xFFFF;
// Calculate the physical block range for the boot configuration
startBlockID = IMAGE_BOOT_BOOTCFG_NAND_OFFSET / flashInfo.dwBytesPerBlock;
endBlockID = startBlockID + (IMAGE_BOOT_BOOTCFG_NAND_SIZE / flashInfo.dwBytesPerBlock);
EdbgOutputDebugString("INFO: Storing boot configuration to NAND\r\n");
// Erase range of NAND blocks reserved for boot configuration
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;
}
}
// Find a good block and store the boot configuration
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;
// Write out the boot configuration to all sectors as filler so the
// NAND FMD does not try to map it later
for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
{
if (!FMD_WriteSector(sectorAddr, sectorBuf, §orInfo, 1))
{
EdbgOutputDebugString("ERROR: Failed to update EBOOT.\r\n");
return FALSE;
}
}
}
EdbgOutputDebugString("INFO: Successfully stored boot configuration to NAND\r\n");
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -