⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.cpp

📁 smdk2416 wince source code/BSP
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	{
		OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: device doesn't exist.\r\n")));
		return(FALSE);
	}

	if (g_ImageType == IMAGE_TYPE_RAMIMAGE)
	{
		g_dwMBRSectorNum = BLOCK_TO_SECTOR(IMAGE_START_BLOCK); 
		OALMSG(TRUE, (TEXT("g_dwMBRSectorNum = 0x%x\r\n"), g_dwMBRSectorNum));
		
 		dwBlock = IMAGE_START_BLOCK; //by hmseo - 20061124 This block is to MBR
		//		dwImageStart += dwLaunchAddr;
		//		dwImageLength = dwImageLength; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block
	}

	RETAILMSG(1,(TEXT("Erase Block from 0x%x, to 0x%x \n"), dwBlock, SPECIAL_AREA_START + SPECIAL_AREA_SIZE - 1));
	for (nBlockNum = dwBlock ; nBlockNum < SPECIAL_AREA_START + SPECIAL_AREA_SIZE; nBlockNum++)
	{
		if (!FMD_EraseBlock(nBlockNum))
		{
			return(FALSE);
		}
	}

	if ( !VALID_TOC(g_pTOC) )
	{
		OALMSG(OAL_WARN, (TEXT("WARN: WriteOSImageToBootMedia: 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);
		}
	}

	// Look in the kernel region's extension area for a multi-BIN extension descriptor.
	// This region, if found, details the number, start, and size of each BIN region.
	//
	for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions); nCount++)
	{
		// Does this region contain nk.exe and an extension pointer?
		//
		pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart,
		            g_BINRegionInfo.Region[nCount].dwRegionLength );
		if ( pExt != NULL)
		{
			// If there is an extension pointer region, walk it until the end.
			//
			while (pExt)
			{
				DWORD dwBaseAddr = g_BINRegionInfo.Region[nCount].dwRegionStart;

				pExt = (EXTENSION *)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt);
				OALMSG(OAL_INFO, (TEXT("INFO: OEMLaunch: Found chain extenstion: '%s' @ 0x%x\r\n"), pExt->name, dwBaseAddr));

				if ((pExt->type == 0) && !strcmp(pExt->name, "chain information"))
				{
					pChainInfo = (PXIPCHAIN_SUMMARY) OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata);
					dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY));
					OALMSG(OAL_INFO, (TEXT("INFO: OEMLaunch: Found 'chain information' (pChainInfo=0x%x  Extensions=0x%x).\r\n"), (DWORD)pChainInfo, dwNumExts));
					break;
				}

				pExt = (EXTENSION *)pExt->pNextExt;
			}
		}
		else
		{
			//  Search for Chain region. Chain region doesn't have the ROMSIGNATURE set
			DWORD   dwRegionStart = g_BINRegionInfo.Region[nCount].dwRegionStart;
			DWORD   dwSig = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET);

			if ( dwSig != ROM_SIGNATURE)
			{
				//  It is the chain
				dwChainStart = dwRegionStart;
				dwChainLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
				OALMSG(TRUE, (TEXT("Found the Chain region: StartAddress: 0x%X; Length: 0x%X\n"), dwChainStart, dwChainLength));
			}
		}
	}

	// Determine how big the Total BINFS partition needs to be to store all of this.
	//
	if (pChainInfo && dwNumExts == g_BINRegionInfo.dwNumRegions)    // We're downloading all the regions in a multi-region image...
	{
		DWORD i;
		OALMSG(TRUE, (TEXT("Writing multi-regions\r\n")));

		for (nCount = 0, dwBINFSPartLength = 0 ; nCount < dwNumExts ; nCount++)
		{
			dwBINFSPartLength += (pChainInfo + nCount)->dwMaxLength;
			OALMSG(OAL_ERROR, (TEXT("BINFSPartMaxLength[%u]: 0x%x, TtlBINFSPartLength: 0x%x \r\n"),
							nCount, (pChainInfo + nCount)->dwMaxLength, dwBINFSPartLength));

			// MultiBINInfo does not store each Regions MAX length, and pChainInfo is not in any particular order.
			// So, walk our MultiBINInfo matching up pChainInfo to find each regions MAX Length
			for (i = 0; i < dwNumExts; i++)
			{
				if ( g_BINRegionInfo.Region[i].dwRegionStart == (DWORD)((pChainInfo + nCount)->pvAddr) )
				{
					dwMaxRegionLength[i] = (pChainInfo + nCount)->dwMaxLength;
					OALMSG(TRUE, (TEXT("dwMaxRegionLength[%u]: 0x%x \r\n"), i, dwMaxRegionLength[i]));
					break;
				}
			}
		}

	}
	else    // A single BIN file or potentially a multi-region update (but the partition's already been created in this latter case).
	{
		dwBINFSPartLength = g_BINRegionInfo.Region[0].dwRegionLength;
		OALMSG(TRUE, (TEXT("Writing single region/multi-region update, dwBINFSPartLength: %u \r\n"), dwBINFSPartLength));
	}

	OALMSG(TRUE, (TEXT("dwBlock = %d \n"), dwBlock));
	// Open/Create the BINFS partition where images are stored.  This partition starts immediately after the MBR on the Boot Media and its length is
	// determined by the maximum image size (or sum of all maximum sizes in a multi-region design).
	// Parameters are LOGICAL sectors.
	//
	hPart = BP_OpenPartition( (dwBlock)*(PAGES_PER_SUBLK)*(SECTORS_PER_SUPAGE),
							//SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength))*PAGES_PER_BLOCK, // align to block
							//(dwBINFSPartLength/SECTOR_SIZE)+1,
							SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength))*SECTORS_PER_SUBLK + (IMAGE_START_BLOCK+1)*SECTORS_PER_SUBLK, // hmseo for whimory... +1 is for MBR
							PART_BINFS,
							TRUE,
							PART_OPEN_ALWAYS);

	if (hPart == INVALID_HANDLE_VALUE )
	{
		OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: Failed to open/create partition.\r\n")));
		return(FALSE);
	}

	for (nCount = 0, dwStoreOffset = 0; nCount < g_BINRegionInfo.dwNumRegions ; nCount++)
	{
		DWORD dwRegionStart  = (DWORD)OEMMapMemAddr(0, g_BINRegionInfo.Region[nCount].dwRegionStart);
		DWORD dwRegionLength = g_BINRegionInfo.Region[nCount].dwRegionLength;

		// No concern about Multiple XIP
//		nCount = 0;
		OALMSG(TRUE, (TEXT("nCount = %d \n"), nCount));

		// Media byte offset where image region is stored.
		dwStoreOffset += nCount ? dwMaxRegionLength[nCount-1] : 0;
//		dwStoreOffset = 0;


		// Set the file pointer (byte indexing) to the correct offset for this particular region.
		//
		if ( !BP_SetDataPointer(hPart, dwStoreOffset + (dwBlock+1)*BYTES_PER_SECTOR*SECTORS_PER_SUBLK) )
		{
			OALMSG(OAL_ERROR, (TEXT("ERROR: StoreImageToBootMedia: Failed to set data pointer in partition (offset=0x%x).\r\n"), dwStoreOffset));
			return(FALSE);
		}

		// Write the region to the BINFS partition.
		//
		if ( !BP_WriteData(hPart, (LPBYTE)dwRegionStart, dwRegionLength) )
		{
			EdbgOutputDebugString("ERROR: StoreImageToBootMedia: Failed to write region to BINFS partition (start=0x%x, length=0x%x).\r\n", dwRegionStart, dwRegionLength);
			return(FALSE);
		}

		// update our TOC?
		//
		if ((g_pTOC->id[g_dwTocEntry].dwLoadAddress == g_BINRegionInfo.Region[nCount].dwRegionStart) &&
			g_pTOC->id[g_dwTocEntry].dwTtlSectors == FILE_TO_SECTOR_SIZE(dwRegionLength) )
		{
			g_pTOC->id[g_dwTocEntry].dwStoreOffset = dwStoreOffset;
			g_pTOC->id[g_dwTocEntry].dwJumpAddress = 0; // Filled upon return to OEMLaunch

			g_pTOC->id[g_dwTocEntry].dwImageType = g_ImageType;

			g_pTOC->id[g_dwTocEntry].sgList[0].dwSector = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
			g_pTOC->id[g_dwTocEntry].sgList[0].dwLength = g_pTOC->id[g_dwTocEntry].dwTtlSectors;

			// copy Kernel Region to SDRAM for jump
//			memcpy((void*)g_pTOC->id[g_dwTocEntry].dwLoadAddress, (void*)dwRegionStart, dwRegionLength);

			OALMSG(TRUE, (TEXT("Updateded TOC!\r\n")));
		} 
		else if( (dwChainStart == g_BINRegionInfo.Region[nCount].dwRegionStart) &&
				(dwChainLength == g_BINRegionInfo.Region[nCount].dwRegionLength)) 
		{
			//  Update our TOC for Chain region
			g_pTOC->chainInfo.dwLoadAddress = dwChainStart;
			g_pTOC->chainInfo.dwFlashAddress = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
			g_pTOC->chainInfo.dwLength = FILE_TO_SECTOR_SIZE(dwMaxRegionLength[nCount]);

			OALMSG(TRUE, (TEXT("Written Chain Region to the Flash\n")));
			OALMSG(TRUE, (TEXT("LoadAddress = 0x%X; FlashAddress = 0x%X; Length = 0x%X\n"), 
						g_pTOC->chainInfo.dwLoadAddress, 
						g_pTOC->chainInfo.dwFlashAddress,
						g_pTOC->chainInfo.dwLength));
			OALMSG(TRUE, (TEXT(" memcpy : g_pTOC->chainInfo.dwLoadAddress = 0x%X; dwRegionStart = 0x%X; dwRegionLength = 0x%X\n"), 
						g_pTOC->chainInfo.dwLoadAddress, 
						dwRegionStart,
						dwRegionLength));
			// Now copy it to the SDRAM
			// by hmseo.... ???? 061125
			//memcpy((void *)g_pTOC->chainInfo.dwLoadAddress, (void *)dwRegionStart, dwRegionLength);
		}
	}

    OALMSG(TRUE, (TEXT("-WriteOSImageToBootMedia\r\n")));

    return(TRUE);
}


/*
    @func   BOOL | ReadKernelRegionFromBootMedia |
            BinFS support. Reads the kernel region from Boot Media into RAM.  The kernel region is fixed up
            to run from RAM and this is done just before jumping to the kernel entry point.
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm
    @xref
*/
BOOL ReadOSImageFromBootMedia()
{
    OALMSG(OAL_FUNC, (TEXT("+ReadOSImageFromBootMedia\r\n")));

    OALMSG(TRUE, (TEXT("+ReadOSImageFromBootMedia\r\n")));
    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;
    }

	{
		DWORD dwStartPage, dwNumPage, dwPage;
		Buffer InBuf;
		DWORD dwRegionStart = (DWORD)((g_pTOC->id[g_dwTocEntry].dwLoadAddress) | CACHED_TO_UNCACHED_OFFSET);
		DWORD dwRegionLength = SECTOR_TO_FILE_SIZE(g_pTOC->id[g_dwTocEntry].dwTtlSectors);

 		dwStartPage = (IMAGE_START_BLOCK+1)*(PAGES_PER_SUBLK);
		dwNumPage = (dwRegionLength-1)/BYTES_PER_MAIN_SUPAGE+1;

		OALMSG(TRUE, (TEXT("Read OS image to BootMedia \r\n")));
		OALMSG(TRUE, (TEXT("ImageLength = %d Byte, dwRegionStart : %08x \r\n"), dwRegionLength,dwRegionStart));
		OALMSG(TRUE, (TEXT("Start Page = %d, End Page = %d, Page Count = %d\r\n"), dwStartPage, dwStartPage+dwNumPage-1, dwNumPage));

		InBuf.pData = (unsigned char *)dwRegionStart;
		InBuf.pSpare = NULL;
		InBuf.nBank = 0;
		if ( TWO_PLANE_PROGRAM == TRUE32 )
		{
 			InBuf.nBitmap = FULL_SECTOR_BITMAP_PAGE; 
 		}
		else
		{
 			InBuf.nBitmap = LEFT_SECTOR_BITMAP_PAGE; 
 		}
		InBuf.eStatus = BUF_AUX;	// No need to sync

		for (dwPage = dwStartPage; dwPage < dwStartPage+dwNumPage; dwPage++)
		{
			if (VFL_Read(dwPage, &InBuf, FALSE32) != FIL_SUCCESS)
			{
				OALMSG(TRUE, (TEXT("[ERR] VFL Read Error @ %d page\r\n"), dwPage));
				OALMSG(TRUE, (TEXT("Read OS image to BootMedia Failed !!!\r\n")));
				while(1);
			}

			InBuf.pData += BYTES_PER_MAIN_SUPAGE;
			
			if (dwPage%PAGES_PER_BLOCK == (PAGES_PER_BLOCK-1)) OALMSG(TRUE, (TEXT(".")));
		}

		OALMSG(TRUE, (TEXT("\r\nRead OS image to BootMedia Success \r\n")));
	}

    OALMSG(OAL_FUNC, (TEXT("_ReadOSImageFromBootMedia\r\n")));
    return(TRUE);
}

BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable)
{
#if 0
    for (int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector++) {
        if (!FMD_ReadSector(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1))
            return FALSE;
        if (pbBlock)
            pbBlock += g_FlashInfo.wDataBytesPerSector;
        if (pSectorInfoTable)
            pSectorInfoTable++;
    }
#else
    if (!FMD_ReadSector(dwBlock * g_FlashInfo.wSectorsPerBlock, pbBlock, /*pSectorInfoTable*/NULL, g_FlashInfo.wSectorsPerBlock))		// hmseo-061028
        return FALSE;
#endif
    return TRUE;
}

BOOL WriteBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable)
{
#if 0
	for (int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector++) {
		if (!FMD_WriteSector(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, /*pSectorInfoTable*/NULL, 1))		// hmseo-061028
			return FALSE;
		if (pbBlock)
			pbBlock += g_FlashInfo.wDataBytesPerSector;
		if (pSectorInfoTable)
			pSectorInfoTable++;
	}
#else
	if (!FMD_WriteSector(dwBlock * g_FlashInfo.wSectorsPerBlock, pbBlock, /*pSectorInfoTable*/NULL, g_FlashInfo.wSectorsPerBlock))		// hmseo-061028
		return FALSE;
#endif
	return TRUE;
}

static UCHAR WMRBuf[WMRBUFSIZE];
static UCHAR BadInfoBuf[4096+128];

BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
	LowFuncTbl *pLowFuncTbl;

	UINT32 dwStartPage, dwNumPage, dwPage;
	UINT32 dwStartBlock, dwNumBlock, dwBlock;
	UINT32 dwPageOffset;
	INT32 nRet;
	BOOL32 bIsBadBlock = FALSE32;
	UINT32 nSyncRet;

	LPBYTE pbBuffer;

	OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n")));

	if ( !g_bBootMediaExist )
	{
		OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n")));
		return(FALSE);
	}

	if (g_ImageType == IMAGE_TYPE_LOADER)
	{
		UINT8 *pMBuf;
		UINT8 *pSBuf;

		pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart);

		dwStartBlock = EBOOT_BLOCK;
		dwNumBlock = (dwImageLength-1)/(BYTES_PER_MAIN_SUPAGE*PAGES_PER_BLOCK)+1;

		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);
			}
		}

		OALMSG(TRUE, (TEXT("Write Eboot image to BootMedia \r\n")));
		OALMSG(TRUE, (TEXT("ImageLength = %d Byte \r\n"), dwImageLength));
		OALMSG(TRUE, (TEXT("Start Block = %d, End Block = %d, Block Count = %d\r\n"), dwStartBlock, dwStartBlock+dwNumBlock-1, dwNumBlock));

		pLowFuncTbl = FIL_GetFuncTbl();

		pMBuf = WMRBuf;
		pSBuf = WMRBuf+BYTES_PER_MAIN_SUPAGE;

		dwBlock = dwStartBlock;

		while(dwNumBlock > 0)
		{
			if (dwBlock == (EBOOT_BLOCK+EBOOT_BLOCK_SIZE+EBOOT_BLOCK_RESERVED))
			{
				OALMSG(TRUE, (TEXT("Write RAW image to BootMedia Failed !!!\r\n")));
				OALMSG(TRUE, (TEXT("Too many Bad Block\r\n")));
				return(FALSE);
			}

			IS_CHECK_SPARE_ECC = FALSE32;
			pLowFuncTbl->Read(0, dwBlock*PAGES_PER_BLOCK+PAGES_PER_BLOCK-1, 0x0, enuBOTH_PLANE_BITMAP, NULL, pSBuf, TRUE32, FALSE32);
			IS_CHECK_SPARE_ECC = TRUE32;

			if (TWO_PLANE_PROGRAM == TRUE32)
			{
				if (pSBuf[0] == 0xff && pSBuf[BYTES_PER_SPARE_PAGE] == 0xff)
					bIsBadBlock = TRUE32;
			}
			else
			{
				if (pSBuf[0] == 0xff)
					bIsBadBlock = TRUE32;
			}

			if (bIsBadBlock)
			{
				pLowFuncTbl->Erase(0, dwBlock, enuBOTH_PLANE_BITMAP);
				nRet = pLowFuncTbl->Sync(0, &nSyncRet);
				if ( nRet != FIL_SUCCESS)
				{
					OALMSG(TRUE, (TEXT("[ERR] FIL Erase Error @ %d block, Skipped\r\n"), dwBlock));
					goto MarkAndSkipBadBlock;
				}

				for (dwPageOffset=0; dwPageOffset<PAGES_PER_BLOCK; dwPageOffset++)
				{
					pLowFuncTbl->Write(0, dwBlock*PAGES_PER_BLOCK+dwPageOffset, FULL_SECTOR_BITMAP_PAGE, enuBOTH_PLANE_BITMAP, pbBuffer+BYTES_PER_MAIN_SUPAGE*dwPageOffset, NULL);
					nRet = pLowFuncTbl->Sync(0, &nSyncRet);
					if (nRet != FIL_SUCCESS)
					{
						OALMSG(TRUE, (TEXT("[ERR] FIL Write Error @ %d Block %d Page, Skipped\r\n"), dwBlock, dwPageOffset));
						goto MarkAndSkipBadBlock;
					}

					nRet = pLowFuncTbl->Read(0, dwBlock*PAGES_PER_BLOCK+dwPageOffset, FULL_SECTOR_BITMAP_PAGE, enuBOTH_PLANE_BITMAP, pMBuf, NULL, FALSE32, FALSE32);
					if (nRet != FIL_SUCCESS)
					{
						OALMSG(TRUE, (TEXT("[ERR] FIL Read Error @ %d Block %d Page, Skipped\r\n"), dwBlock, dwPageOffset));
						goto MarkAndSkipBadBlock;
					}

					if (0 != memcmp(pbBuffer+BYTES_PER_MAIN_SUPAGE*dwPageOffset, pMBuf, BYTES_PER_MAIN_SUPAGE))
					{
						OALMSG(TRUE, (TEXT("[ERR] Verify Error @ %d Block %d Page, Skipped\r\n"), dwBlock, dwPageOffset));
						goto MarkAndSkipBadBlock;
					}
				}

				OALMSG(TRUE, (TEXT("[OK] Write %d th Block Success\r\n"), dwBlock));
				dwBlock++;
				dwNumBlock--;
				pbBuffer += BYTES_PER_MAIN_SUPAGE*PAGES_PER_BLOCK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -