Exemplo n.º 1
0
//------------------------------------------------------------------------------
//
//  Function:  OEMWriteFlash
//
//  This function is called by the bootloader to write the image that may
//  be stored in a RAM file cache area to flash memory.
//
BOOL OEMWriteFlash(ULONG address, ULONG size) 
{
    BOOL rc = FALSE;
    VOID *pSource;

    OALMSG(OAL_FUNC, (L"+OEMWriteFlash(0x%08x, 0x%08x\r\n", address, size));

    // First get location where data are    
    pSource = OEMMapMemAddr(address, address);
    if (pSource == NULL) {
        OALMSG(OAL_ERROR, (
            L"ERROR: OEMMapMemAddr failed for 0x%08x\r\n", address
        ));
        goto cleanUp;
    }        

    OALMSG(OAL_WARN, (
        L"Write flash memory at 0x%08x size 0x%08x...", address, size
    ));

    rc = OALFlashWrite(
        OALPAtoUA(IMAGE_FLASH_PA_START), OALPAtoUA((VOID*)address), size, pSource
    );
    if (!rc) {
        OALMSG(OAL_ERROR, (L"\r\nERROR: Flash write failed\r\n"));
        goto cleanUp;
    }

    OALMSG(OAL_WARN, (L" Done\r\n"));
    
cleanUp:
    OALMSG(OAL_FUNC, (L"-OEMWriteFlash(rc = %d)\r\n", rc));
    return rc;
}
BOOL
WriteFlashNK(
    UINT32 address,
    UINT32 size
    )
{
	BOOL rc = FALSE;
	UCHAR *pData;
	void *pBase = OALPAtoVA(g_ulFlashBase, FALSE);
	void *pStart = (void *)((UINT32)pBase + IMAGE_WINCE_NOR_OFFSET);

	OALLog(L"\r\nWriting NK image to flash memory\r\n");

	// Get data location
	pData = OEMMapMemAddr(address, address);

	// Verify that we get CE image
	if (!VerifyImage(pData, NULL))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: NK image signature not found\r\n"));
		goto cleanUp;
	}

	// Unlock blocks
	if (!OALFlashLock(pBase, pStart, size, FALSE))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: NK blocks could not be unlocked\r\n"));
		goto cleanUp;
	}

	// Erase blocks
	if (!OALFlashErase(pBase, pStart, size))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: NK blocks could not be erased\r\n"));
		goto cleanUp;
	}

	// Write blocks
	if (!OALFlashWrite(pBase, pStart, size, pData))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: NK blocks could not be written\r\n"));
		goto cleanUp;
	}

	OALLog(L"NK image written\r\n");

	// Change boot device to NOR
	g_bootCfg.bootDevLoc.IfcType = Internal;
	g_bootCfg.bootDevLoc.LogicalLoc = BSP_NOR_REGS_PA;

	// Done
	rc = TRUE;

cleanUp:
	return rc;
}
Exemplo n.º 3
0
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
	DWORD dwBlock = 0;
	DWORD dwNumBlocks = 0;
	LPBYTE pbBuffer;
       SectorInfo si;
	//unsigned int sectorchk;
	unsigned int sectorcnt = 0;
	unsigned int areachange = 0;

    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(dwLaunchAddr==0x10)
		{
		dwBlock = LOGO_BLOCK;
		//dwImageLength = UPLDR_RAM_IMAGE_SIZE;
		g_ImageType=IMAGE_TYPE_RAWBIN;
		}else{

	if (g_ImageType == IMAGE_TYPE_LOADER)
	{
		dwBlock = EBOOT_BLOCK;
	    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_STEPLDR)
	{
		dwBlock = STEPLDR_BLOCK;
		dwImageStart += dwLaunchAddr;
		//dwImageLength = 0x2050; //step loader can support 8k bytes.
		//dwImageLength = STEPLDR_RAM_IMAGE_SIZE; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block
	}
	else if (g_ImageType == IMAGE_TYPE_DIONB0)
	{
		dwBlock = DIONB0_BLOCK;
		dwImageStart += dwLaunchAddr;
		dwImageLength -= (dwImageLength / (g_FlashInfo.wDataBytesPerSector + 8))*8;
	}
	else if (g_ImageType == IMAGE_TYPE_UPLDR)
	{
		dwBlock = UPLDR_BLOCK;
		dwImageStart += dwLaunchAddr;
		dwImageLength = UPLDR_RAM_IMAGE_SIZE; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block
	}
	else if (g_ImageType == IMAGE_TYPE_FLASHBIN)
	{
		dwBlock = FLASHBIN_BLOCK;
//		dwImageStart += dwLaunchAddr;
//		dwImageLength = dwImageLength; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block
	}
			}
		if(dwLaunchAddr==0x10)
			pbBuffer=(LPBYTE)dwImageStart;
		else
	pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart);
	 
    // Compute number of blocks.
    dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0);
    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(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock));
	    OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock));
	    OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock));

        if (!FMD_EraseBlock(dwBlock)) 
        {
            OALMSG(TRUE, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock));
			++dwBlock;
			++dwNumBlocks;		  // Compensate for fact that we didn't write any blocks.
			continue;
        }

//		FMD_GetBlockStatus(dwBlock);
        if ((FMD_GetBlockStatus(dwBlock) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))&&dwBlock!=0) {
		    OALMSG(TRUE, (TEXT("FMD_GetBlockStatus Error \r\n")));
            ++dwBlock;
            ++dwNumBlocks;        // Compensate for fact that we didn't write any blocks.
            continue;
        }

		//FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1);
		if (!FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1)) 
		{
		    OALMSG(TRUE, (TEXT("FMD_ReadSector : Failed to get block(0x%x)'s sector info.\r\n"), dwBlock));
            ++dwBlock;
            ++dwNumBlocks;        // Compensate for fact that we didn't write any blocks.
            continue;
		}

		// Stepldr & Eboot image in nand flash
		// block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD
        if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=0xfc )&&dwBlock!=0)
        {
            OALMSG(TRUE, (TEXT("si.bBadBlock failed, si.bOEMReserved %x,si.bBadBlock %x.\r\n"),si.bOEMReserved, si.bBadBlock));
            ++dwBlock;
            ++dwNumBlocks;        // Compensate for fact that we didn't write any blocks.
            continue;
        }
        if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) 
        {
		    OALMSG(TRUE, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock));
            return(FALSE);
        }


		if (g_ImageType == IMAGE_TYPE_DIONB0)
		{
			for ( int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector ++ )
			{
				if (!WritePage(dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, pbBuffer, (PSectorInfo)(pbBuffer+g_FlashInfo.wDataBytesPerSector) )) 
				{
					OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
					return(FALSE);
				}
				pbBuffer += (g_FlashInfo.wDataBytesPerSector + 8);
			}

			++dwBlock;
		}
		else if (g_ImageType == IMAGE_TYPE_FLASHBIN)
		{
			for ( int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector ++ )
			{
				//RETAILMSG(1, (TEXT("WriteData: (0x%x)(0x%x,0x%x,0x%x).\r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, g_pSectorInfoBuf->dwReserved1, g_pSectorInfoBuf->bOEMReserved, g_pSectorInfoBuf->wReserved2));

				if (!WritePage(dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, pbBuffer, (PSectorInfo)(pbBuffer+g_FlashInfo.wDataBytesPerSector) )) 
				{
					OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
                    #ifdef IROMBOOT
					FMD_EraseBlock(dwBlock);		
							 
					// this block is actually considered to bad block.
					// because it may be erased initial bad block information. 
					si.bOEMReserved = 0xff;
					si.bBadBlock    = BADBLOCKMARK;
					si.dwReserved1  = 0xffffffff;
					si.wReserved2   = 0xffff;

					FMD_WriteSector(BLOCK_TO_SECTOR(dwBlock), NULL, &si, 1);
					pbBuffer -= (g_FlashInfo.wDataBytesPerSector + 8)*iSector;
					iSector = 0;
					break;					
                    
                    #else
					return(FALSE);

                    #endif  // !IROMBOOT
				}
				pbBuffer += (g_FlashInfo.wDataBytesPerSector + 8);
			}

			++dwBlock;
		}
		else
		{
			OALMSG(TRUE, (TEXT(" Write Reserved Area \n")));

			if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)) 
			{
				OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
				return(FALSE);
			}

			++dwBlock;
			OALMSG(TRUE, (TEXT("pbBuffer + %x .\r\n"), SECTOR_SIZE/*SECTORS_PER_PAGE*/*PAGES_PER_BLOCK));
            #ifdef IROMBOOT
			pbBuffer += (SECTOR_SIZE/*SECTORS_PER_PAGE*/*PAGES_PER_BLOCK);

            #else
			pbBuffer += 0x4000;

            #endif  // !IROMBOOT
		}
    }
	
	if (g_ImageType == IMAGE_TYPE_LOADER)
	{
    	g_pTOC->id[0].dwLoadAddress = dwImageStart;
    	g_pTOC->id[0].dwJumpAddress = 0;
    	g_pTOC->id[0].dwTtlSectors  = FILE_TO_SECTOR_SIZE(dwImageLength);
    	g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK);
    	g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;
    }

    OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n")));
	return TRUE;
}
Exemplo n.º 4
0
/*
    @func   BOOL | WriteOSImageToBootMedia | Stores the image cached in RAM to the Boot Media.
    The image may be comprised of one or more BIN regions.
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm
    @xref
*/
BOOL WriteOSImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
    BYTE nCount;
    DWORD dwNumExts;
    PXIPCHAIN_SUMMARY pChainInfo = NULL;
    EXTENSION *pExt = NULL;
    DWORD dwBINFSPartLength = 0;
    HANDLE hPart, hPartEx;
    DWORD dwStoreOffset;
    DWORD dwMaxRegionLength[BL_MAX_BIN_REGIONS] = {0};
    DWORD dwChainStart, dwChainLength;
    
    //  Initialize the variables
    dwChainStart = dwChainLength = 0;

    OALMSG(OAL_FUNC, (TEXT("+WriteOSImageToBootMedia\r\n")));
    OALMSG(OAL_INFO, (TEXT("+WriteOSImageToBootMedia: g_dwTocEntry =%d, ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%x\r\n"),
                            g_dwTocEntry, dwImageStart, dwImageLength, dwLaunchAddr));

    if ( !g_bBootMediaExist ) 
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: device doesn't exist.\r\n")));
        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));
    }

    // 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( (IMAGE_START_BLOCK)*PAGES_PER_BLOCK,	// MBR block
                              SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength))*PAGES_PER_BLOCK, // align to block
                              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);
    }

    // Are there multiple BIN files in RAM (we may just be updating one in a multi-BIN solution)?
    //
    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;

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

        // Set the file pointer (byte indexing) to the correct offset for this particular region.
        //
        if ( !BP_SetDataPointer(hPart, dwStoreOffset) )
        {
            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);
        }
        
		RETAILMSG(TRUE, (TEXT("g_pTOC->id[g_dwTocEntry].dwLoadAddress = 0x%x \r\n"), g_pTOC->id[g_dwTocEntry].dwLoadAddress));
		RETAILMSG(TRUE, (TEXT("g_BINRegionInfo.Region[nCount].dwRegionStart = 0x%x \r\n"), g_BINRegionInfo.Region[nCount].dwRegionStart));
		RETAILMSG(TRUE, (TEXT("g_pTOC->id[g_dwTocEntry].dwTtlSectors = 0x%x \r\n"), g_pTOC->id[g_dwTocEntry].dwTtlSectors));
		RETAILMSG(TRUE, (TEXT("FILE_TO_SECTOR_SIZE(dwRegionLength) = 0x%x \r\n"), FILE_TO_SECTOR_SIZE(dwRegionLength)));

        // 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) )
        {
			OALMSG(TRUE, (TEXT("if \r\n")));
            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)) 
        {
			OALMSG(TRUE, (TEXT("else if \r\n")));
            //  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));
            // Now copy it to the SDRAM
            memcpy((void *)g_pTOC->chainInfo.dwLoadAddress, (void *)dwRegionStart, dwRegionLength);
        }
		OALMSG(TRUE, (TEXT("pass \r\n")));
    }

    // create extended partition in whatever is left
    //
    hPartEx = BP_OpenPartition( NEXT_FREE_LOC,
                                USE_REMAINING_SPACE,
                                PART_DOS32,
                                TRUE,
                                PART_OPEN_ALWAYS);

    if (hPartEx == INVALID_HANDLE_VALUE )
    {
        OALMSG(OAL_WARN, (TEXT("*** WARN: StoreImageToBootMedia: Failed to open/create Extended partition ***\r\n")));
    }

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

    return(TRUE);
}
Exemplo n.º 5
0
//------------------------------------------------------------------------------
//
//  Function:  OEMLaunch
//
//  This function is the last one called by the boot framework and it is
//  responsible for to launching the image.
//
VOID
OEMLaunch(
   ULONG start, 
   ULONG size, 
   ULONG launch, 
   const ROMHDR *pRomHeader
    )
{
    BSP_ARGS *pArgs = OALCAtoUA(IMAGE_SHARE_ARGS_CA);

	UNREFERENCED_PARAMETER(size);
	UNREFERENCED_PARAMETER(pRomHeader);

    OALMSG(OAL_FUNC, (
        L"+OEMLaunch(0x%08x, 0x%08x, 0x%08x, 0x%08x - %d/%d)\r\n", start, size,
        launch, pRomHeader, g_eboot.bootDeviceType, g_eboot.type
        ));

    // Depending on protocol there can be some action required
    switch (g_eboot.bootDeviceType)
        {
#if BUILDING_EBOOT_SD
        case BOOT_SDCARD_TYPE:            
            switch (g_eboot.type)
                {
#if 0
/*
                case DOWNLOAD_TYPE_FLASHRAM:
                    if (BLFlashDownload(&g_bootCfg, g_kitlDevices) != BL_JUMP)
                        {
                        OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: "
                            L"Image load from flash memory failed\r\n"
                            ));
                        goto cleanUp;
                        }
                    launch = g_eboot.launchAddress;
                    break;
*/
#endif
                case DOWNLOAD_TYPE_RAM:
                    launch = (UINT32)OEMMapMemAddr(start, launch);
                    break;
					
                case DOWNLOAD_TYPE_FLASHNAND:
                    if (BLFlashDownload(&g_bootCfg, g_kitlDevices) != BL_JUMP)
                        {
                        OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: "
                            L"Image load from flash memory failed\r\n"
                            ));
                        goto cleanUp;
                        }
                    launch = g_eboot.launchAddress;
                    break;
					
#if 0
/*
                case DOWNLOAD_TYPE_EBOOT:
                case DOWNLOAD_TYPE_XLDR:
                    OALMSG(OAL_INFO, (L"INFO: "
                        L"XLDR/EBOOT/IPL downloaded, spin forever\r\n"
                        ));
                    while (TRUE);
                    break;
*/
#endif
                default:
                    OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: Unknown download type, spin forever\r\n"));
                    for(;;);
                    break;
                }
            break;

#endif

        case OAL_KITL_TYPE_ETH:
            BLEthConfig(pArgs);
            switch (g_eboot.type)
                {
                case DOWNLOAD_TYPE_FLASHNAND:
				case DOWNLOAD_TYPE_FLASHNOR:
                    if (BLFlashDownload(&g_bootCfg, g_kitlDevices) != BL_JUMP)
                        {
                        OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: "
                            L"Image load from flash memory failed\r\n"
                            ));
                        goto cleanUp;
                        }
                    launch = g_eboot.launchAddress;
                    break;

                case DOWNLOAD_TYPE_RAM:
                    launch = (UINT32)OEMMapMemAddr(start, launch);
                    break;

                case DOWNLOAD_TYPE_EBOOT:
                case DOWNLOAD_TYPE_XLDR:
                    OALMSG(OAL_INFO, (L"INFO: "
                        L"XLDR/EBOOT/IPL downloaded, spin forever\r\n"
                        ));
                    for(;;);
                    break;

				case DOWNLOAD_TYPE_LOGO:
                    OALMSG(OAL_INFO, (L"INFO: "
                        L"Splashcreen logo downloaded, spin forever\r\n"
                        ));
                    for(;;);
                    break;

                default:
                    OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: Unknown download type, spin forever\r\n"));
                    for(;;);
                    break;
                }
            break;

        default:        
            launch = g_eboot.launchAddress;
            break;
        }

#ifndef BSP_NO_NAND_IN_SDBOOT
    if ((g_bootCfg.flashNKFlags & ENABLE_FLASH_NK) &&       
        /* if loading from NAND then do not need to flash NAND again */      
        (g_eboot.bootDeviceType != OAL_KITL_TYPE_FLASH) && 
	    (start != (IMAGE_WINCE_CODE_CA + NAND_ROMOFFSET)) &&
	    (start != (IMAGE_WINCE_CODE_CA + NOR_ROMOFFSET))) {
            if( !WriteFlashNK(start, size))
	            OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: "
	                L"Flash NK.bin failed, start=%x\r\n", start
	                ));
    	}
#endif

    // Check if we get launch address
    if (launch == (UINT32)INVALID_HANDLE_VALUE)
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: "
            L"Unknown image launch address, spin forever\r\n"
            ));
        for(;;);
        }        

    // Print message, flush caches and jump to image
    OALLog(
        L"Launch Windows CE image by jumping to 0x%08x...\r\n\r\n", launch
        );

	OEMDeinitDebugSerial();
    OEMPlatformDeinit();
    JumpTo(OALVAtoPA((UCHAR*)launch));

cleanUp:
    return;
}
BOOL
WriteFlashLogo(
    UINT32 address,
    UINT32 size
    )
{
    BOOL rc = FALSE;
    HANDLE hFlash = NULL;
    UINT8 *pData;
    UINT32 offset;

    OALMSG(OAL_INFO, (L"\r\nWriting Splashcreen image to flash memory\r\n"));

    // Open flash storage
    hFlash = OALFlashStoreOpen(g_ulFlashBase);
    if (hFlash == NULL)
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"OALFlashStoreOpen call failed!\r\n"
            ));
        goto cleanUp;
        }

    // Check if image fit (last sector used for configuration)
    if (size > (IMAGE_BOOTLOADER_BITMAP_SIZE - OALFlashStoreSectorSize(hFlash)))
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"Logo image too big (size 0x%08x, maximum size 0x%08x)\r\n",
            size, IMAGE_BOOTLOADER_BITMAP_SIZE - OALFlashStoreBlockSize(hFlash)
            ));
        goto cleanUp;
        }

    // Get data location
    pData = OEMMapMemAddr(address, address);

    // Fill unused space with 0xFF
    if (size < IMAGE_BOOTLOADER_BITMAP_SIZE)
        {
        memset(pData + size, 0xFF, IMAGE_BOOTLOADER_BITMAP_SIZE - size);
        }

    offset = IMAGE_XLDR_BOOTSEC_NAND_SIZE + IMAGE_EBOOT_BOOTSEC_NAND_SIZE;
    if (!OALFlashStoreWrite(
            hFlash, offset, pData, IMAGE_BOOTLOADER_BITMAP_SIZE, FALSE, FALSE
            ))
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"OALFlashStoreWrite at relative address 0x%08x failed\r\n", offset
            ));
        goto cleanUp;
        }

    OALMSG(OAL_INFO, (L"Splashcreen image written\r\n"));

    // Done
    rc = TRUE;

cleanUp:
    if (hFlash != NULL) OALFlashStoreClose(hFlash);
    return rc;
}
BOOL
WriteFlashNK(
    UINT32 address,
    UINT32 size
    )
{
    BOOL rc = FALSE;
    BOOL bExt = FALSE;

    HANDLE hPartition;
    UCHAR *pData;
    PCI_REG_INFO regInfo;

    memset(&regInfo, 0, sizeof(PCI_REG_INFO));
    regInfo.MemBase.Num    = 1;
    regInfo.MemLen.Num     = 1;
    regInfo.MemBase.Reg[0] = g_ulFlashBase;
    regInfo.MemLen.Reg[0]  = g_ulFlashLengthBytes;


    // Get data location
    pData = OEMMapMemAddr(address, address);

#ifdef IMGMULTIXIP
    // Checking if this is an EXT region
    if((address == (IMAGE_WINCE_EXT_CA + NAND_ROMOFFSET)) || (address == IMAGE_WINCE_EXT_CA) )
    {
        bExt = TRUE;
        OALLog(L"\r\nWriting EXT image to OS partition, address=%x, SIZE=%x\r\n", address, size);
    }
    else if ((address == (IMAGE_WINCE_CODE_CA + NAND_ROMOFFSET) )|| (address == IMAGE_WINCE_CODE_CA))
#endif		
		
    {
        OALLog(L"\r\nWriting NK image to OS partition address=%x, SIZE=%x\r\n", address, size);
    }
	
    // Verify that we get CE image.
    if (!VerifyImage(pData, NULL))
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"NK image signature not found\r\n"
            ));
        rc = TRUE;
        goto cleanUp;
        }

    // Initialize boot partition library
    if (!BP_Init((LPBYTE)g_ulBPartBase, g_ulBPartLengthBytes, NULL, &regInfo, NULL))
    {
        OALLog(L"WriteFlashNK: Error initializing bootpart library!!\r\n");
        goto cleanUp;
    }
    
    // Open partition based on region type 
    hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, bExt ? PART_BINFS : PART_BOOTSECTION, FALSE, PART_OPEN_EXISTING);

    if (hPartition == INVALID_HANDLE_VALUE)
    {
        OALMSG(OAL_ERROR, (L"ERROR: OS partition not found!\r\n"));
        goto cleanUp;
    }
    
    // Check length against size of partition
    if (!BP_SetDataPointer(hPartition, size))
    {
        OALMSG(OAL_ERROR, (L"ERROR: OS partition too small!  Aborting...\r\n"));
        goto cleanUp;
    }
    
    // Write image to partition
    BP_SetDataPointer(hPartition, 0);
    if (!BP_WriteData(hPartition, pData, size))
    {
        OALMSG(OAL_ERROR, (L"ERROR: Failed writing to OS partition!\r\n"));
        goto cleanUp;
    }
    
    //OALLog(L"%s image written\r\n", bExt ? L"EXT" :L"nk");

    // Change boot device to NAND
    g_bootCfg.bootDevLoc.IfcType = Internal;
    g_bootCfg.bootDevLoc.LogicalLoc = BSP_NAND_REGS_PA + 0x20;

    // Done
    rc = TRUE;

cleanUp:
    return rc;
}
BOOL
WriteFlashXLDR(
    UINT32 address,
    UINT32 size
    )
{
    BOOL rc = FALSE;
    HANDLE hFlash = NULL;
    ROMHDR *pTOC;
    UINT32 offset, xldrSize, blocknum, blocksize;
    UINT8 *pData;

	UNREFERENCED_PARAMETER(size);

    OALMSG(OAL_INFO, (L"\r\nWriting XLDR image to flash memory\r\n"));

    // Open flash storage
    hFlash = OALFlashStoreOpen(g_ulFlashBase);
    if (hFlash == NULL)
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"OALFlashStoreOpen call failed!\r\n"
            ));
        goto cleanUp;
        }

    // Get data location
    pData = OEMMapMemAddr(address, address);

    // Verify image
    if (!VerifyImage(pData, &pTOC))
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"XLDR image signature not found\r\n"
            ));
        }

    // Verify that this is XLDR image
    if (pTOC->numfiles > 0 || pTOC->nummods > 1)
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"XLDR image must have only one module and no file\r\n"
            ));
        goto cleanUp;
        }

    // Check for maximal XLRD size
    xldrSize = pTOC->physlast - pTOC->physfirst;
    if (xldrSize > (IMAGE_XLDR_CODE_SIZE - 2*sizeof(DWORD)) )
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"XLDR image size 0x%04x doesn't fit to limit 0x%04x\r\n", size, IMAGE_XLDR_CODE_SIZE - 2*sizeof(DWORD)
            ));
        goto cleanUp;
        }
        
    blocksize = OALFlashStoreBlockSize(hFlash);
    
    if (blocksize < IMAGE_XLDR_CODE_SIZE)
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"XLDR image size 0x%04x doesn't fit to flash block size 0x%04x\r\n", IMAGE_XLDR_CODE_SIZE, blocksize
            ));
        goto cleanUp;
        }

    // First we have to offset image by 2 DWORDS to insert BootROM header 
    memmove(pData + 2*sizeof(DWORD), pData, xldrSize);
    
    // Insert BootROM header
    ((DWORD*)pData)[0] = IMAGE_XLDR_CODE_SIZE - 2*sizeof(DWORD);    // Max size of image
    ((DWORD*)pData)[1] = IMAGE_XLDR_CODE_PA;                        // Load address

    // Now copy into first four blocks per boot ROM requirement.
    // Internal boot ROM expects the loader to be duplicated in the first 4 blocks for
    // data redundancy. Note that block size of memory used on this platform is larger 
    // than xldr size so there will be a gap in each block.
    offset = 0;
    for (blocknum = 0; blocknum < 4; blocknum++)
        {
        if (!OALFlashStoreWrite(
                hFlash, offset, pData, IMAGE_XLDR_CODE_SIZE, FALSE, FALSE
                ))
            {
            OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
                L"OALFlashStoreWrite at relative address 0x%08x failed\r\n",
                offset
                ));
            }
        offset += blocksize;
        }

    OALMSG(OAL_INFO, (L"XLDR image written\r\n"));

    // Done
    rc = TRUE;

cleanUp:
    if (hFlash != NULL) OALFlashStoreClose(hFlash);
    return rc;
}
BOOL
WriteFlashEXT(
    UINT32 address,
    UINT32 size
    )
{
    BOOL rc = FALSE;
    HANDLE hPartition;
    UCHAR *pData;
    PCI_REG_INFO regInfo;

    memset(&regInfo, 0, sizeof(PCI_REG_INFO));
    regInfo.MemBase.Num    = 1;
    regInfo.MemLen.Num     = 1;
    regInfo.MemBase.Reg[0] = g_ulFlashBase;
    regInfo.MemLen.Reg[0]  = g_ulFlashLengthBytes;


    // Get data location
    pData = OEMMapMemAddr(address, address);

    // Verify that we get CE image.
    if (!VerifyImage(pData, NULL))
        {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"EXT image signature not found\r\n"
            ));
        rc = TRUE;
        goto cleanUp;
        }

    // Initialize boot partition library
    if (!BP_Init((LPBYTE)g_ulBPartBase, g_ulBPartLengthBytes, NULL, &regInfo, NULL))
    {
        OALLog(L"WriteFlashEXT: Error initializing bootpart library!!\r\n");
        goto cleanUp;
    }
    
    // Open partition 
    hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, PART_BINFS,  FALSE, PART_OPEN_EXISTING);
    if (hPartition == INVALID_HANDLE_VALUE)
    {
        OALMSG(OAL_ERROR, (L"ERROR: OS partition not found!\r\n"));
        goto cleanUp;
    }
    
    // Check length against size of partition
    if (!BP_SetDataPointer(hPartition, size))
    {
        OALMSG(OAL_ERROR, (L"ERROR: OS partition too small!  Aborting...\r\n"));
        goto cleanUp;
    }
    
    // Write image to partition
    BP_SetDataPointer(hPartition, 0);
    if (!BP_WriteData(hPartition, pData, size))
    {
        OALMSG(OAL_ERROR, (L"ERROR: Failed writing to OS partition!\r\n"));
        goto cleanUp;
    }
    
    OALLog(L"EXT image written, spin for ever!\r\n");
    OALLog(L"EXT image written, spin for ever!\r\n");
    for(;;);

    // Done
    //rc = TRUE;

cleanUp:
    return rc;
}
BOOL
WriteFlashEBOOT(
    UINT32 address,
    UINT32 size
    )
{
	void *pData;
	void *pBase = OALPAtoVA(g_ulFlashBase, FALSE);
	void *pStart = (void *)((UINT32)pBase + IMAGE_EBOOT_NOR_OFFSET);
	BOOL rc = FALSE;

    OALMSG(OAL_INFO, (L"\r\nWriting EBOOT image to flash memory\r\n"));

    // Check if image fit (last sector used for configuration)
    if (size > IMAGE_EBOOT_CODE_SIZE)
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT image too big (size 0x%08x, maximum size 0x%08x)\r\n", size, IMAGE_EBOOT_CODE_SIZE));
		goto cleanUp;
	}

	// Get data location
	pData = OEMMapMemAddr(address, address);

	// Verify that we get CE image
	if (!VerifyImage(pData, NULL))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT image signature not found\r\n"));
		goto cleanUp;
	}

	// Fill unused space with 0xFF
	if (size < IMAGE_EBOOT_CODE_SIZE)
	{
		memset((void *)((UINT32)pData + size), 0xFF, IMAGE_EBOOT_CODE_SIZE - size);
	}

	// Unlock blocks
	if (!OALFlashLock(pBase, pStart, size, FALSE))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT blocks could not be unlocked\r\n"));
		goto cleanUp;
	}

	// Erase blocks
	if (!OALFlashErase(pBase, pStart, size))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT blocks could not be erased\r\n"));
		goto cleanUp;
	}

	// Write blocks
	if (!OALFlashWrite(pBase, pStart, size, pData))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: EBOOT blocks could not be written\r\n"));
		goto cleanUp;
	}

	OALMSG(OAL_INFO, (L"EBOOT image written\r\n"));

    // Done
    rc = TRUE;

cleanUp:
    return rc;
}
BOOL
WriteFlashXLDR(
    UINT32 address,
    UINT32 size
    )
{
	ROMHDR *pTOC;
	UINT8 *pData;
	void *pBase = OALPAtoVA(g_ulFlashBase, FALSE);
	void *pStart = (void *)((UINT32)pBase + IMAGE_XLDR_NOR_OFFSET);
	UINT32 xldrSize;
	BOOL rc = FALSE;

	OALMSG(OAL_INFO, (L"\r\nWriting XLDR image to flash memory\r\n"));

	// Get data location
	pData = OEMMapMemAddr(address, address);

	// Verify image
	if (!VerifyImage(pData, &pTOC))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR image signature not found\r\n"));
		goto cleanUp;
	}

	// Verify that this is XLDR image
	if (pTOC->numfiles > 0 || pTOC->nummods > 1)
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR image must have only one module and no file\r\n"));
		goto cleanUp;
	}

	// Check for maximal XLRD size
	xldrSize = pTOC->physlast - pTOC->physfirst;
	if (xldrSize > IMAGE_XLDR_CODE_SIZE)
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR image size 0x%04x doesn't fit to limit 0x%04x\r\n", size, IMAGE_XLDR_CODE_SIZE));
		goto cleanUp;
	}

	// Unlock blocks
	if (!OALFlashLock(pBase, pStart, size, FALSE))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR blocks could not be unlocked\r\n"));
		goto cleanUp;
	}

	// Erase blocks
	if (!OALFlashErase(pBase, pStart, size))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR blocks could not be erased\r\n"));
		goto cleanUp;
	}

	// Write blocks
	if (!OALFlashWrite(pBase, pStart, size, pData))
	{
		OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: XLDR blocks could not be written\r\n"));
		goto cleanUp;
	}

    // Done
    rc = TRUE;

cleanUp:
    return rc;
}
Exemplo n.º 12
0
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(&sectorInfo, 0xFF, sizeof(sectorInfo));
            sectorInfo.dwReserved1 = 0;
            sectorInfo.wReserved2 = 0;

            // Write sector
            if (!(ok = WriteSector(
                block * sectorsPerBlock + sector, pData + count, &sectorInfo
            ))) 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;
}
Exemplo n.º 13
0
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
    DWORD dwBlock,dwNumBlocks;
    LPBYTE pbBuffer;
    SectorInfo si;

    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)
    {
        dwBlock = EBOOT_BLOCK;
        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_STEPLDR)
    {
        dwBlock = NBOOT_BLOCK;
        dwImageStart += dwLaunchAddr;
        dwImageLength = STEPPINGSTONE_SIZE; //step loader can support 8k bytes.
    }

    pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart);

    // Compute number of blocks.
    //dwNumBlocks = (dwImageLength / 0x4000) + 1;
    dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0);
    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(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock));
        OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock));
        OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock));

        FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1);

        // Stepldr & Eboot image in nand flash
        // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD
        if ((si.bBadBlock == BADBLOCKMARK) && (si.bOEMReserved != 0xFC ))
        {
            ++dwBlock;
            ++dwNumBlocks;        // Compensate for fact that we didn't write any blocks.
            continue;
        }

        if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf))
        {
            OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock));
            return(FALSE);
        }

        if (!FMD_EraseBlock(dwBlock))
        {
            OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock));
            return FALSE;
        }

        if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf))
        {
            OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
            return(FALSE);
        }

        ++dwBlock;
        pbBuffer += g_FlashInfo.dwBytesPerBlock;    //c ksk 20060311
        OALMSG(TRUE, (TEXT("dwBytesPerBlock : %d\r\n"), g_FlashInfo.dwBytesPerBlock));
    }

    if (g_ImageType == IMAGE_TYPE_LOADER)
    {
        g_pTOC->id[0].dwLoadAddress = dwImageStart;
        g_pTOC->id[0].dwJumpAddress = 0;
        g_pTOC->id[0].dwTtlSectors  = FILE_TO_SECTOR_SIZE(dwImageLength);
        g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK);
        g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;
    }

    OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n")));

    return TRUE;
}
Exemplo n.º 14
0
VOID BLWriteFlashNK(OAL_BLMENU_ITEM *pMenu)
{
	DWORD i = 0;
	UCHAR ch;
	DWORD       dwImageStart, dwImageLength, dwRecAddr, dwRecLen, dwRecChk;
	DWORD       dwRecNum = 0;
	LPBYTE      lpDest = NULL;
	OAL_KITL_TYPE bkType;
	
	wcscpy(g_bootCfg.filename, L"nk.bin");

	if (BL_ERROR == BLSDCardDownload(g_bootCfg.filename))
	{
		OALLog(TEXT("SD boot failed to open file\r\n"));
		goto CleanUp;
	}

	bkType = g_eboot.type;
	g_eboot.bootDeviceType = BOOT_SDCARD_TYPE;

	
	g_eboot.type = DOWNLOAD_TYPE_RAM;
	
	for (i=0; i < 7; i++) OEMReadData(1, &ch);
	
	if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageStart)
        || !OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageLength))
    {
        KITLOutputDebugString ("Unable to read image start/length\r\n");
        return ;
    }
	while ( OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr)  &&
            OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen)   &&
            OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk) )
    {
        KITLOutputDebugString(" <> Record [ %d ] dwRecAddr = 0x%x, dwRecLen = 0x%x\r\n", 
            dwRecNum, dwRecAddr, dwRecLen);

		dwRecNum++;

        // last record of .bin file uses sentinel values for address and checksum.
        if (!dwRecAddr && !dwRecChk)
        {
            break;
        }

        // map the record address (FLASH data is cached, for example)
        lpDest = OEMMapMemAddr (dwImageStart, dwRecAddr);

        // read data block
        if (!OEMReadData (dwRecLen, lpDest))
        {
            KITLOutputDebugString ("****** Data record %d corrupted, ABORT!!! ******\r\n", dwRecNum);
            return ;
        }

        if (!VerifyChecksum (dwRecLen, lpDest, dwRecChk))
        {
            KITLOutputDebugString ("****** Checksum failure on record %d, ABORT!!! ******\r\n", dwRecNum);
            return ;
        }

        // Look for ROMHDR to compute ROM offset.  NOTE: romimage guarantees that the record containing
        // the TOC signature and pointer will always come before the record that contains the ROMHDR contents.
        //
        if (dwRecLen == sizeof(ROMHDR) && (*(LPDWORD) OEMMapMemAddr(dwImageStart, dwImageStart+ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE))
        {
            DWORD dwTempOffset = (dwRecAddr - *(LPDWORD)OEMMapMemAddr(dwImageStart, dwImageStart+ ROM_SIGNATURE_OFFSET + sizeof(ULONG)));
            ROMHDR *pROMHdr = (ROMHDR *)lpDest;

            // Check to make sure this record really contains the ROMHDR.
            //
            if ((pROMHdr->physfirst == (dwImageStart - dwTempOffset)) &&
                (pROMHdr->physlast  == (dwImageStart - dwTempOffset + dwImageLength)) &&
                (DWORD)(HIWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast) &&
                (DWORD)(LOWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast))
            {
                KITLOutputDebugString("rom_offset=0x%x.\r\n", dwTempOffset); 
            }
        }
    }  // while( records remaining )
	

	g_eboot.bootDeviceType = bkType;
	//g_eboot.type = DOWNLOAD_TYPE_RAM;
	g_eboot.type = DOWNLOAD_TYPE_FLASHNAND;
	if (OEMWriteFlash(dwImageStart, dwImageLength))
		OALLog(L"BLWriteFlashNK success..\n");
	else
		OALLog(L"BLWriteFlashNK fail..\n");

	//write boot device for nand flash
	if (BLWriteBootCfg(&g_bootCfg)) {
       	 OALLog(L" Current settings has been saved\r\n");
  	  } else {        
        	OALLog(L"ERROR: Settings save failed!\r\n");
    }
	
CleanUp:
	return;
}