nand.cpp
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 1,317 行 · 第 1/4 页
CPP
1,317 行
if (!g_bBootMediaExist)
{
OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: device doesn't exist.\r\n")));
return(FALSE);
}
if ( !VALID_TOC(g_pTOC) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: INVALID_TOC\r\n")));
return(FALSE);
}
if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) )
{
OALMSG(OAL_ERROR, (TEXT("ReadOSImageFromBootMedia: ERROR_INVALID_IMAGE_DESCRIPTOR: 0x%x\r\n"),
g_pTOC->id[g_dwTocEntry].dwSignature));
return FALSE;
}
if ( !OEMVerifyMemory(g_pTOC->id[g_dwTocEntry].dwLoadAddress, sizeof(DWORD)) ||
!OEMVerifyMemory(g_pTOC->id[g_dwTocEntry].dwJumpAddress, sizeof(DWORD)) ||
!g_pTOC->id[g_dwTocEntry].dwTtlSectors )
{
OALMSG(OAL_ERROR, (TEXT("ReadOSImageFromBootMedia: ERROR_INVALID_ADDRESS: (address=0x%x, sectors=0x%x, launch address=0x%x)...\r\n"),
g_pTOC->id[g_dwTocEntry].dwLoadAddress, g_pTOC->id[g_dwTocEntry].dwTtlSectors, g_pTOC->id[g_dwTocEntry].dwJumpAddress));
return FALSE;
}
nErr = BML_GetVolInfo(0,&pstVolSpec);
if(nErr!=BML_SUCCESS) {
RETAILMSG(1, (L"WriteOSImageToBootMedia : BML_GetVolInfo is failed.\r\n"));
return FALSE;
}
nErr = BML_LoadPIEntry(0,PARTITION_ID_COPIEDOS,&pstPartEntry);
if(nErr!=BML_SUCCESS) {
RETAILMSG(1, (L"WriteOSImageToBootMedia : BML_LoadPIEntry is failed.\r\n"));
return FALSE;
}
// Open the BINFS partition (it must exist).
//
hPart = BP_OpenPartition( NEXT_FREE_LOC,
USE_REMAINING_SPACE,
PART_BINFS,
TRUE,
PART_OPEN_EXISTING);
if (hPart == INVALID_HANDLE_VALUE )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to open existing partition.\r\n")));
return(FALSE);
}
// Set the partition file pointer to the correct offset for the kernel region.
//
if ( !BP_SetDataPointer(hPart, g_pTOC->id[g_dwTocEntry].dwStoreOffset) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to set data pointer in partition (offset=0x%x).\r\n"),
g_pTOC->id[g_dwTocEntry].dwStoreOffset));
return(FALSE);
}
// Read the kernel region from the Boot Media into RAM.
//
if ( !BP_ReadData( hPart,
(LPBYTE)(g_pTOC->id[g_dwTocEntry].dwLoadAddress),
SECTOR_TO_FILE_SIZE(g_pTOC->id[g_dwTocEntry].dwTtlSectors)) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to read kernel region from partition.\r\n")));
return(FALSE);
}
if (!g_pTOC->chainInfo.dwLoadAddress)
{
chainaddr = g_pTOC->chainInfo.dwLoadAddress;
flashaddr = g_pTOC->chainInfo.dwFlashAddress;
for ( i = 0; i < (g_pTOC->chainInfo.dwLength); i++ )
{
OALMSG(TRUE, (TEXT("chainaddr=0x%x, flashaddr=0x%x\r\n"), chainaddr, flashaddr+i));
if ( !FMD_ReadSector(flashaddr+i, (PUCHAR)(chainaddr), NULL, 1) ) {
OALMSG(OAL_ERROR, (TEXT("TOC_Write ERROR: Unable to read/verify TOC\r\n")));
return FALSE;
}
chainaddr += 512;
}
}
OALMSG(OAL_FUNC, (TEXT("_ReadOSImageFromBootMedia\r\n")));
return(TRUE);
}
BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable)
{
for (int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector++) {
if (!FMD_ReadSector_BML(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, NULL, 1))
return FALSE;
if (pbBlock)
pbBlock += (g_FlashInfo.wDataBytesPerSector);
}
return TRUE;
}
BOOL WriteBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable)
{
for (int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector++) {
if (!FMD_WriteSector_BML(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, NULL, 1))
return FALSE;
if (pbBlock)
pbBlock += (g_FlashInfo.wDataBytesPerSector);
}
return TRUE;
}
BOOL WritePage(DWORD dwPage, LPBYTE pbPage, PSectorInfo pSectorInfo)
{
if (!FMD_WriteSector_BML(dwPage, pbPage, NULL, 1))
return FALSE;
return TRUE;
}
#define SECTOR_WRITE_COMPLETED 0x4
// you must match these defines with <NAND ...> values in memory.cfg.xml file
#define EBOOT_WRITE_NAND_SECTORSIZE (g_FlashInfo.wDataBytesPerSector)
#define EBOOT_WRITE_NAND_BLOCKSIZE (0x20000)
#define EBOOT_WRITE_NAND_SECTOR_PER_BLK (EBOOT_WRITE_NAND_BLOCKSIZE/EBOOT_WRITE_NAND_SECTORSIZE)
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
DWORD dwBlock,dwNumBlocks, dwSector;
LPBYTE pbBuffer, pbDst, pbSectorNo;
unsigned int sectorcnt = 0;
unsigned int areachange = 0;
INT32 nRet = BML_SUCCESS;
UINT32 nVol = 0;
UINT32 nBytesReturned;
XSRPartEntry stBINPartE;
OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia: dwImageStart-0x%x, dwImageLength-0x%x, dwLaunchAddr-0x%x\r\n"), dwImageStart, dwImageLength, dwLaunchAddr));
if ( !g_bBootMediaExist )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n")));
return(FALSE);
}
nRet = BML_IOCtl(nVol,
BML_IOCTL_UNLOCK_WHOLEAREA,
NULL, 0,
NULL, 0,
&nBytesReturned);
if (nRet != BML_SUCCESS)
{
OALMSG(OAL_ERROR, (TEXT("[EBOOT:ERR] BML_IOCtl error\r\n")));
while(1);
}
if (g_ImageType == IMAGE_TYPE_STEPLDR)
{
nRet = BML_LoadPIEntry(0, PARTITION_ID_ONBL1, &stBINPartE);
dwBlock = stBINPartE.n1stVbn;
dwNumBlocks = stBINPartE.nNumOfBlks;
}
else if (g_ImageType == IMAGE_TYPE_IPL)
{
nRet = BML_LoadPIEntry(0, PARTITION_ID_IPL, &stBINPartE);
dwBlock = stBINPartE.n1stVbn;
dwNumBlocks = stBINPartE.nNumOfBlks;
}
else if (g_ImageType == IMAGE_TYPE_SUPERIPL)
{
nRet = BML_LoadPIEntry(0, PARTITION_ID_ONBL1, &stBINPartE);
dwBlock = stBINPartE.n1stVbn;
dwNumBlocks = stBINPartE.nNumOfBlks;
if (nRet == BML_SUCCESS)
{
nRet = BML_LoadPIEntry(0, PARTITION_ID_IPL, &stBINPartE);
dwNumBlocks += stBINPartE.nNumOfBlks;
}
}
else if (g_ImageType == IMAGE_TYPE_LOADER)
{
nRet = BML_LoadPIEntry(0, PARTITION_ID_EBOOT, &stBINPartE);
dwBlock = stBINPartE.n1stVbn;
dwNumBlocks = stBINPartE.nNumOfBlks;
if ( !VALID_TOC(g_pTOC) )
{
OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: INVALID_TOC\r\n")));
if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: INVALID_TOC\r\n")));
return(FALSE);
}
}
}
else if (g_ImageType == IMAGE_TYPE_FLASHBIN)
{
dwBlock = 0; // because of usging ftl_write()
dwImageLength -= (dwImageLength / (EBOOT_WRITE_NAND_SECTORSIZE + 8))*8; // normalization to main data only. 8 means sectorinfo data
dwNumBlocks = (dwImageLength / EBOOT_WRITE_NAND_BLOCKSIZE) + ((dwImageLength%EBOOT_WRITE_NAND_BLOCKSIZE) ? 1: 0);
}
else if (g_ImageType == IMAGE_TYPE_DIO)
{
dwBlock = 0; // because of usging ftl_write()
dwNumBlocks = (dwImageLength / EBOOT_WRITE_NAND_BLOCKSIZE) + ((dwImageLength%EBOOT_WRITE_NAND_BLOCKSIZE) ? 1: 0);
}
else if (g_ImageType == IMAGE_TYPE_DIONB0)
{
dwBlock = 0; // because of usging ftl_write()
dwImageLength -= (dwImageLength / (EBOOT_WRITE_NAND_SECTORSIZE + 8))*8; // normalization to main data only. 8 means sectorinfo data
dwNumBlocks = (dwImageLength / EBOOT_WRITE_NAND_BLOCKSIZE) + ((dwImageLength%EBOOT_WRITE_NAND_BLOCKSIZE) ? 1: 0);
}
else
{
OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: g_ImageType does not exist.\r\n")));
}
if(nRet != BML_SUCCESS)
{
OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't have partition entries.\r\n")));
return FALSE;
}
pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart);
pbDst = pbBuffer;
OALMSG(TRUE, (TEXT("g_FlashInfo.wDataBytesPerSector = 0x%x \r\n"), EBOOT_WRITE_NAND_SECTORSIZE));
OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock = 0x%x \r\n"), g_FlashInfo.wSectorsPerBlock));
OALMSG(TRUE, (TEXT("dwBlock = 0x%x \r\n"), dwBlock));
OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength));
OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks));
while (dwNumBlocks--)
{
// If the block is marked bad, skip to next block. Note that the assumption in our error checking
// is that any truely bad block will be marked either by the factory during production or will be marked
// during the erase and write verification phases. If anything other than a bad block fails ECC correction
// in this routine, it's fatal.
OALMSG(OAL_FUNC, (TEXT("dwBlock(0x%x) \r\n"), dwBlock));
if ((g_ImageType != IMAGE_TYPE_FLASHBIN) && (g_ImageType != IMAGE_TYPE_DIO) && (g_ImageType != IMAGE_TYPE_DIONB0))
{
if (!FMD_EraseBlock_BML(dwBlock))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock));
return FALSE;
}
}
if (g_ImageType == IMAGE_TYPE_FLASHBIN)
#if 1 // write one block
{
pbSectorNo = pbBuffer + EBOOT_WRITE_NAND_SECTORSIZE;
dwSector = *((DWORD*)pbSectorNo);
OALMSG(OAL_FUNC, (TEXT("dwNumBlock = %d, pbBuffer = 0x%x, pbDst = 0x%x, pbSectorNo = 0x%x, dwSector = 0x%x\r\n"), dwBlock, pbBuffer, pbDst, pbSectorNo, dwSector));
if ((dwSector != 0xffffffff) && (dwSector >= dwSector) && (dwSector <= 64*2048))
{
for ( int iSector = 0; iSector < EBOOT_WRITE_NAND_SECTOR_PER_BLK; iSector++ )
{
memcpy(pbDst+iSector*EBOOT_WRITE_NAND_SECTORSIZE, pbBuffer+iSector*(EBOOT_WRITE_NAND_SECTORSIZE+8), EBOOT_WRITE_NAND_SECTORSIZE);
}
if (!FMD_WriteSector(dwSector, pbDst, NULL, EBOOT_WRITE_NAND_SECTOR_PER_BLK))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
return(FALSE);
}
}
pbDst += (EBOOT_WRITE_NAND_SECTORSIZE*EBOOT_WRITE_NAND_SECTOR_PER_BLK);
pbBuffer += ((EBOOT_WRITE_NAND_SECTORSIZE+8)*EBOOT_WRITE_NAND_SECTOR_PER_BLK);
++dwBlock;
}
#else // write one sector
{
for ( int iSector = 0; iSector < EBOOT_WRITE_NAND_SECTOR_PER_BLK; iSector++ )
{
pbSectorNo = pbBuffer + EBOOT_WRITE_NAND_SECTORSIZE;
dwSector = *((DWORD*)pbSectorNo);
if ((dwSector != 0xffffffff) && (dwSector >= dwSector) && (dwSector <= 64*2048))
{
if (!FMD_WriteSector(dwSector, pbBuffer, NULL, 1))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
return(FALSE);
}
}
pbBuffer += EBOOT_WRITE_NAND_SECTORSIZE+8;
}
++dwBlock;
}
#endif
else if (g_ImageType == IMAGE_TYPE_DIO)
{
if (!FMD_WriteSector(dwBlock * EBOOT_WRITE_NAND_SECTOR_PER_BLK, pbBuffer, NULL, EBOOT_WRITE_NAND_SECTOR_PER_BLK))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
return FALSE;
}
pbBuffer += EBOOT_WRITE_NAND_BLOCKSIZE;
++dwBlock;
}
else if (g_ImageType == IMAGE_TYPE_DIONB0)
{
for ( int iSector = 0; iSector < EBOOT_WRITE_NAND_SECTOR_PER_BLK; iSector++ )
{
pbSectorNo = pbBuffer + EBOOT_WRITE_NAND_SECTORSIZE;
dwSector = *((DWORD*)pbSectorNo);
if ((dwSector != 0xffffffff) && (dwSector >= dwSector) && (dwSector <= 64*2048))
{
if (!FMD_WriteSector(dwSector, pbBuffer, NULL, 1))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
return(FALSE);
}
}
pbBuffer += EBOOT_WRITE_NAND_SECTORSIZE+8;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?