📄 bootpart.c
字号:
}
/* BP_Init
*
* Sets up locations for various objects in memory provided by caller
*
* ENTRY
* pMemory - pointer to memory for storing objects
* dwSize - size of the memory
* lpActiveReg - used by FMD_Init. NULL if not needed.
* pRegIn - used by FMD_Init. NULL if not needed.
* pRegOut - used by FMD_Init. NULL if not needed.
*
* EXIT
* TRUE on success
*/
BOOL BP_Init (LPBYTE pMemory, DWORD dwSize) //, LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)
{
DWORD dwBufferSize;
int i = 0;
if (!pMemory) {
Uart_Printf("BP_Init Fails No memory fails!!!\r\n");
return FALSE;
}
if (!FMD_Init ())//lpActiveReg, pRegIn, pRegOut))
return FALSE;
if (!FMD_GetInfo (&g_FlashInfo)) {
Uart_Printf("BP_Init Fails FMD_GetInfo fails!!!\r\n");
return FALSE;
}
// Check to make sure size is enough for one sector, one block, and sectorinfo buffer for one block
g_dwDataBytesPerBlock = g_FlashInfo.wDataBytesPerSector * g_FlashInfo.wSectorsPerBlock;
dwBufferSize = g_FlashInfo.wDataBytesPerSector + g_dwDataBytesPerBlock +
g_FlashInfo.wSectorsPerBlock * sizeof(SectorInfo);
if (dwSize < dwBufferSize) {
Uart_Printf("BP_Init Fails buffer size = %x < required = %x!!!\r\n",dwSize,dwBufferSize);
return FALSE;
}
for (i = 0; i < NUM_PARTS; i++) {
g_partStateTable[i].pPartEntry= NULL;
g_partStateTable[i].dwDataPointer = 0;
}
g_pbMBRSector = pMemory; //size = g_FlashInfo.wDataBytesPerSector;
g_pbBlock = pMemory + g_FlashInfo.wDataBytesPerSector; //size = g_dwDataBytesPerBlock;
g_pSectorInfoBuf = (PSectorInfo)(g_pbBlock + g_dwDataBytesPerBlock); //size = g_FlashInfo.wSectorsPerBlock * sizeof(SectorInfo);
g_dwLastLogSector = 0;
return TRUE;
}
/*
@func BOOL | EraseBlocks | Erases a range of NAND flash blocks, tests, and marks bad blocks.
@rdesc TRUE on success, FALSE on failure.
@comm
@xref
*/
BOOL EraseBlocks(DWORD dwStartBlock, DWORD dwNumBlocks, DWORD dwFlags)
{
DWORD dwSector;
USHORT nCount;
LPBYTE WriteSect = g_pbBlock + g_FlashInfo.wDataBytesPerSector;
LPBYTE ReadSect = g_pbBlock + 2 * g_FlashInfo.wDataBytesPerSector;
SectorInfo WriteSectInfo, ReadSectInfo;
if (dwStartBlock >= g_FlashInfo.dwNumBlocks || (dwStartBlock + dwNumBlocks - 1) >= g_FlashInfo.dwNumBlocks)
{
Uart_Printf("EraseBlocks: block number outside valid range [0x%x, 0x%x].\r\n", dwStartBlock, (dwStartBlock + dwNumBlocks - 1));
return(FALSE);
}
Uart_Printf ("Erasing flash block(s) [0x%x, 0x%x] (please wait): ", dwStartBlock, (dwStartBlock + dwNumBlocks - 1));
while (dwNumBlocks--)
{
DWORD dwStatus = FMD_GetBlockStatus (dwStartBlock);
BOOL fBadBlock = FALSE;
// If the block has already been marked bad, skip it and increase the total number of blocks to be erased by a block. Note that bad
// blocks do count against the total number of blocks to be erased since the caller has max constraints on the erase region size.
if (dwStatus & BLOCK_STATUS_BAD)
{
Uart_Printf ("EraseBlocks: found a bad block (0x%x) - skipping...\r\n", dwStartBlock);
++dwStartBlock;
continue;
}
if ((dwStatus & BLOCK_STATUS_RESERVED) && (dwFlags & FORMAT_SKIP_RESERVED))
{
Uart_Printf ("EraseBlocks: preserving reserved block (0x%x) \r\n", dwStartBlock);
++dwStartBlock;
continue;
}
if (!FMD_EraseBlock(dwStartBlock))
{
Uart_Printf("EraseBlocks: unable to erase block (0x%x). Marking bad..\r\n", dwStartBlock);
FMD_SetBlockStatus(dwStartBlock, BLOCK_STATUS_BAD);
++dwStartBlock;
continue;
}
// Optionally skip the bad block check - this speeds up the erase process, especially on NOR flash.
if (dwFlags & FORMAT_SKIP_BLOCK_CHECK)
{
++dwStartBlock;
continue;
}
#if 0
// Because the bits denoting a bad block can be erased, we take the cautious approach - we'll write an read-verify each sector in this
// block to make sure the block is good. If it's good, we'll re-erase else we'll mark the block bad.
dwSector = (dwStartBlock * g_FlashInfo.wSectorsPerBlock);
for (nCount = 0 ; nCount < g_FlashInfo.wSectorsPerBlock ; nCount++)
{
// Make sure erase set all bits high.
memset(WriteSect, 0xFF, g_FlashInfo.wDataBytesPerSector);
memset(&WriteSectInfo, 0xFF, sizeof(SectorInfo));
FMD_ReadSector((dwSector + nCount), ReadSect, &ReadSectInfo, 1);
if (memcmp(ReadSect, WriteSect, g_FlashInfo.wDataBytesPerSector) ||
memcmp(&ReadSectInfo, &WriteSectInfo, sizeof(SectorInfo)))
{
Uart_Printf ("EraseBlocks: erase didn't set all bits high (marking block 0x%x bad).\r\n", dwStartBlock);
FMD_SetBlockStatus(dwStartBlock, BLOCK_STATUS_BAD);
fBadBlock = TRUE;
break;
}
// Now, make sure we can store zero - this is meant to check for bad blocks (in the event that the bad block marker was erased).
// Note that we *don't* write sector info data here - this is where bad block data is stored.
memset(WriteSect, 0, g_FlashInfo.wDataBytesPerSector);
if (!FMD_WriteSector((dwSector + nCount), WriteSect, NULL, 1))
{
Uart_Printf ("EraseBlocks: write test low data failed (marking block 0x%x bad).\r\n", dwStartBlock);
FMD_SetBlockStatus(dwStartBlock, BLOCK_STATUS_BAD);
fBadBlock = TRUE;
break;
}
// Read back the value and make sure it stored correctly.
if (!FMD_ReadSector((dwSector + nCount), ReadSect, NULL, 1) ||
memcmp(ReadSect, WriteSect, g_FlashInfo.wDataBytesPerSector))
{
Uart_Printf ("EraseBlocks: erase didn't set all bits low (marking block 0x%x bad).\r\n", dwStartBlock);
FMD_SetBlockStatus(dwStartBlock, BLOCK_STATUS_BAD);
fBadBlock = TRUE;
break;
}
}
// If the block has already been marked bad, skip it and increase the total number of blocks to be erased by a block. Note that bad
// blocks do count against the total number of blocks to be erased since the caller has max constraints on the erase region size.
if (fBadBlock)
{
Uart_Printf ("\r\nEraseBlocks: found a bad block (0x%x) - skipping...\r\n", dwStartBlock);
++dwStartBlock;
continue;
}
if (!FMD_EraseBlock(dwStartBlock))
{
Uart_Printf ("EraseBlocks: unable to erase block (0x%x). Marking bad..\r\n", dwStartBlock);
FMD_SetBlockStatus(dwStartBlock, BLOCK_STATUS_BAD);
}
#endif
++dwStartBlock;
}
Uart_Printf ("Done.\r\n");
return(TRUE);
}
/* BP_LowLevelFormat
*
* Called when preparing flash for a multiple-BIN download.
* Erases, verifies, and writes logical sector numbers in the range to be written.
*
* ENTRY
* dwStartBlock - starting physical block for format
* dwNumBlocks - number of physical blocks to format
* dwFlags - Flags used in formatting.
*
* EXIT
* TRUE returned on success and FALSE on failure.
*/
BOOL BP_LowLevelFormat(DWORD dwStartBlock, DWORD dwNumBlocks, DWORD dwFlags)
{
dwNumBlocks = min (dwNumBlocks, g_FlashInfo.dwNumBlocks);
Uart_Printf("Enter LowLevelFormat [0x%x, 0x%x].\r\n", dwStartBlock, dwStartBlock + dwNumBlocks - 1);
// Erase all the flash blocks.
if (!EraseBlocks(dwStartBlock, dwNumBlocks, dwFlags))
return(FALSE);
// Determine first good starting block
while (IS_BLOCK_UNUSABLE (dwStartBlock) && dwStartBlock < g_FlashInfo.dwNumBlocks) {
dwStartBlock++;
}
if (dwStartBlock >= g_FlashInfo.dwNumBlocks) {
Uart_Printf("BP_LowLevelFormat: no good blocks\r\n");
return FALSE;
}
// MBR goes in the first sector of the starting block. This will be logical sector 0.
g_dwMBRSectorNum = dwStartBlock * g_FlashInfo.wSectorsPerBlock+8;//GetMBRSectorNum();//
// Create an MBR.
CreateMBR();
Uart_Printf("Done.\r\n\r\n");
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -