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 + -
显示快捷键?