📄 flash.c
字号:
));
// Write EBOOT image
count = 0;
while (count < IMAGE_EBOOT_CODE_SIZE && block < flashInfo.dwNumBlocks) {
if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
block++;
OALMSG(OAL_INFO, (L"$"));
continue;
}
// Erase block
if (!EraseBlock(block)) {
FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
block++;
OALMSG(OAL_INFO, (L"#"));
continue;
}
// Now write sectors
ix = 0;
while (
ix < flashInfo.wSectorsPerBlock && count < IMAGE_EBOOT_CODE_SIZE
) {
// Prepare sector info
memset(§orInfo, 0xFF, sizeof(sectorInfo));
sectorInfo.bOEMReserved &= ~(OEM_BLOCK_READONLY|OEM_BLOCK_RESERVED);
sectorInfo.dwReserved1 = 0;
sectorInfo.wReserved2 = 0;
// Write sector
ok = WriteSector(
block * flashInfo.wSectorsPerBlock + ix, pData + count,
§orInfo
);
// When write fail, break sector write loop
if (!ok) break;
// Move to next sector
count += sectorSize;
ix++;
OALMSG(OAL_INFO, (L"."));
}
// When sector write failed, mark block as bad and move back
if (!ok) {
// First move back
count -= ix * flashInfo.wDataBytesPerSector;
// Mark block as bad
FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
block++;
OALMSG(OAL_INFO, (L"%"));
continue;
}
// We are done with block
block++;
}
OALMSG(OAL_INFO, (L"\r\nOEMWriteFlash: EBOOT written\r\n"));
// Done
rc = (count >= size);
cleanUp:
if (hFMD != NULL) FMD_Deinit(hFMD);
return rc;
}
//------------------------------------------------------------------------------
BOOL WriteFlashIPL(UINT32 address, UINT32 size)
{
BOOL rc = FALSE, ok = FALSE;
HANDLE hFMD = NULL;
ROMHDR *pTOC;
FlashInfo flashInfo;
UINT32 blockSize, sectorSize;
SectorInfo sectorInfo;
BLOCK_ID block;
UINT32 *pInfo, ix, count;
UINT8 *pData;
OALMSG(OAL_INFO, (L"OEMWriteFlash: Writing IPL image to flash\r\n"));
// Check if image fit
if (size > IMAGE_EBOOT_CODE_SIZE) {
OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
L"EBOOT image too big (size 0x%08x, maximal size 0x%08x)\r\n",
size, IMAGE_EBOOT_CODE_SIZE
));
}
// Open FMD to access NAND
hFMD = FMD_Init(NULL, NULL, NULL);
if (hFMD == 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: OEMWriteFlash: "
L"FMD_GetInfo call failed!\r\n"
));
goto cleanUp;
}
blockSize = flashInfo.dwBytesPerBlock;
sectorSize = flashInfo.wDataBytesPerSector;
OALMSG(OAL_INFO, (L"OEMWriteFlash: "
L"Flash has %d blocks, %d bytes/block, %d sectors/block\r\n",
flashInfo.dwNumBlocks, flashInfo.dwBytesPerBlock,
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++;
// We are on correct location....
pTOC = (ROMHDR*)((UINT32)*pInfo + IMAGE_WINCE_CODE_PA);
// Let see
DumpTOC(pTOC);
// Fill unused space with 0xFF
if (size < IMAGE_EBOOT_CODE_SIZE) memset(
pData + size, 0xFF, IMAGE_EBOOT_CODE_SIZE - size
);
// Skip OMAP2420 XLDR and EBOOT image
block = 0;
count = 0;
while (
count < IMAGE_XLDR_CODE_SIZE + IMAGE_EBOOT_CODE_SIZE &&
block < flashInfo.dwNumBlocks
) {
if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
block++;
OALMSG(OAL_INFO, (L"$"));
continue;
}
count += blockSize;
block++;
}
OALMSG(OAL_INFO, (L"OEMWriteFlash: "
L"IPL image starts at block %d\r\n", block
));
// Write EBOOT image
count = 0;
while (count < IMAGE_EBOOT_CODE_SIZE && block < flashInfo.dwNumBlocks) {
if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
block++;
OALMSG(OAL_INFO, (L"$"));
continue;
}
// When erase failed, mark block as bad and skip it
if (!EraseBlock(block)) {
FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
block++;
OALMSG(OAL_INFO, (L"#"));
continue;
}
// Now write sectors
ix = 0;
while (
ix < flashInfo.wSectorsPerBlock && count < IMAGE_EBOOT_CODE_SIZE
) {
// Prepare sector info
memset(§orInfo, 0xFF, sizeof(sectorInfo));
sectorInfo.bOEMReserved &= ~(OEM_BLOCK_READONLY|OEM_BLOCK_RESERVED);
sectorInfo.dwReserved1 = 0;
sectorInfo.wReserved2 = 0;
// Write sector
ok = WriteSector(
block * flashInfo.wSectorsPerBlock + ix, pData + count,
§orInfo
);
// When write fail, break sector write loop
if (!ok) break;
// Move to next sector
count += sectorSize;
ix++;
OALMSG(OAL_INFO, (L"."));
}
// When sector write failed, mark block as bad and move back
if (!ok) {
// First move back
count -= ix * flashInfo.wDataBytesPerSector;
// Mark block as bad
FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
block++;
OALMSG(OAL_INFO, (L"%"));
continue;
}
// We are done with block
block++;
}
OALMSG(OAL_INFO, (L"\r\nOEMWriteFlash: IPL written\r\n"));
// Done
rc = (count >= size);
cleanUp:
if (hFMD != NULL) FMD_Deinit(hFMD);
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++;
// We are on correct location....
pTOC = (ROMHDR*)((UINT32)*pInfo + IMAGE_WINCE_CODE_PA);
// Let see
DumpTOC(pTOC);
// 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"));
// Change boot device to NAND
g_bootCfg.bootDevLoc.IfcType = Internal;
g_bootCfg.bootDevLoc.LogicalLoc = BSP_NAND_REGS_PA + 0x20;
// 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;
}
//------------------------------------------------------------------------------
VOID DumpTOC(ROMHDR *pTOC)
{
// Print out ROMHDR information
OALMSG(OAL_INFO, (L"\r\n"));
OALMSG(OAL_INFO, (L"ROMHDR (pTOC = 0x%08x) ---------------------\r\n", pTOC));
OALMSG(OAL_INFO, (L" DLL First : 0x%08x\r\n", pTOC->dllfirst));
OALMSG(OAL_INFO, (L" DLL Last : 0x%08x\r\n", pTOC->dlllast));
OALMSG(OAL_INFO, (L" Physical First : 0x%08x\r\n", pTOC->physfirst));
OALMSG(OAL_INFO, (L" Physical Last : 0x%08x\r\n", pTOC->physlast));
OALMSG(OAL_INFO, (L" Num Modules : %10d\r\n", pTOC->nummods));
OALMSG(OAL_INFO, (L" RAM Start : 0x%08x\r\n", pTOC->ulRAMStart));
OALMSG(OAL_INFO, (L" RAM Free : 0x%08x\r\n", pTOC->ulRAMFree));
OALMSG(OAL_INFO, (L" RAM End : 0x%08x\r\n", pTOC->ulRAMEnd));
OALMSG(OAL_INFO, (L" Num Copy Entries : %10d\r\n", pTOC->ulCopyEntries));
OALMSG(OAL_INFO, (L" Copy Entries Offset : 0x%08x\r\n", pTOC->ulCopyOffset));
OALMSG(OAL_INFO, (L" Prof Symbol Length : 0x%08x\r\n", pTOC->ulProfileLen));
OALMSG(OAL_INFO, (L" Prof Symbol Offset : 0x%08x\r\n", pTOC->ulProfileOffset));
OALMSG(OAL_INFO, (L" Num Files : %10d\r\n", pTOC->numfiles));
OALMSG(OAL_INFO, (L" Kernel Flags : 0x%08x\r\n", pTOC->ulKernelFlags));
OALMSG(OAL_INFO, (L" FileSys RAM Percent : 0x%08x\r\n", pTOC->ulFSRamPercent));
OALMSG(OAL_INFO, (L" Driver Glob Start : 0x%08x\r\n", pTOC->ulDrivglobStart));
OALMSG(OAL_INFO, (L" Driver Glob Length : 0x%08x\r\n", pTOC->ulDrivglobLen));
OALMSG(OAL_INFO, (L" CPU : 0x%04x\r\n", pTOC->usCPUType));
OALMSG(OAL_INFO, (L" MiscFlags : 0x%04x\r\n", pTOC->usMiscFlags));
OALMSG(OAL_INFO, (L" Extensions : 0x%08x\r\n", pTOC->pExtensions));
OALMSG(OAL_INFO, (L" Tracking Mem Start : 0x%08x\r\n", pTOC->ulTrackingStart));
OALMSG(OAL_INFO, (L" Tracking Mem Length : 0x%08x\r\n", pTOC->ulTrackingLen));
OALMSG(OAL_INFO, (L"------------------------------------------------\r\n"));
OALMSG(OAL_INFO, (L"\r\n"));
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -