📄 flash.c
字号:
g_pTOC->id[g_dwTocEntry].dwJumpAddress = IMAGE_WINCE_CODE_PA;
rc = BL_JUMP;
cleanUp:
return rc;
}
/*
@func BOOL | OEMStartEraseFlash | Called at the start of image download, this routine begins the flash erase process.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL OEMStartEraseFlash(DWORD dwStartAddr, DWORD dwLength)
{
// Nothing to do (erase done in OEMWriteFlash)...
//
// OALMSG(OAL_INFO, (L"OEMStartEraseFlash: return TRUE\r\n"));
return(TRUE);
}
/*
@func void | OEMContinueEraseFlash | Called frequenty during image download, this routine continues the flash erase process.
@rdesc N/A.
@comm
@xref
*/
void OEMContinueEraseFlash(void)
{
// Nothing to do (erase done in OEMWriteFlash)...
//
// EdbgOutputDebugString("OEMContinueEraseFlash\r\n");
}
/*
@func BOOL | OEMFinishEraseFlash | Called following the image download, this routine completes the flash erase process.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL OEMFinishEraseFlash(void)
{
// Nothing to do (erase done in OEMWriteFlash)...
//
// EdbgOutputDebugString("OEMFinishEraseFlash\r\n");
return(TRUE);
}
/*
@func BOOL | OEMWriteFlash | Writes data to flash (the source location is determined using OEMMapMemAddr).
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL OEMWriteFlash(DWORD dwStartAddr, DWORD dwLength)
{
BOOL rc;
EdbgOutputDebugString("OEMWriteFlash 0x%x 0x%x\r\n", dwStartAddr, dwLength);
EdbgOutputDebugString("OEMWriteFlash 0x%x \r\n", g_ImageType);
switch (g_ImageType) {
case IMAGE_TYPE_DIONB0:
rc = TRUE;
break;
case IMAGE_TYPE_FLASHBIN:
// rc = WriteFlashNK(dwStartAddr, dwLength);
rc = TRUE;
break;
case IMAGE_TYPE_STEPLDR:
rc = TRUE;
break;
default:
rc = FALSE;
}
return rc;
// return(TRUE);
}
//------------------------------------------------------------------------------
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 WriteSector(SECTOR_ADDR sector, VOID *pBuffer, SectorInfo *pInfo)
{
BOOL rc;
UINT32 retry = 4;
do {
rc = FMD_WriteSector(sector, pBuffer, pInfo, 1);
} while (!rc && --retry > 0);
return rc;
}
//------------------------------------------------------------------------------
BOOL EraseBlock(BLOCK_ID block)
{
BOOL rc;
UINT32 retry = 4;
// Erase block
do {
rc = FMD_EraseBlock(block);
} while (!rc && --retry > 0);
return rc;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -