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

📄 fmd.cpp

📁 WINDOWS CE BSP用于SBC2440开发板
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        ++pTOC;
    }

    return NULL;
}


/*
    @func   BOOL | WriteRegionsToBootMedia | 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 WriteRegionsToBootMedia(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;

    EdbgOutputDebugString("+WriteRegionsToBootMedia: ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%x\r\n",
                            dwImageStart, dwImageLength, dwLaunchAddr);

    if ( !g_bBootMediaExist ) {
        EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: device doesn't exist.\r\n");
        return(FALSE);
    }

    if ( !VALID_TOC(g_pTOC) ) {
        EdbgOutputDebugString("WARN: WriteRegionsToBootMedia: INVALID_TOC\r\n");
        if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) {
            EdbgOutputDebugString("ERROR: INVALID_TOC\r\n");
            return(FALSE);
        }
    }

    if ( !(IMAGE_TYPE_BINFS & g_pTOC->id[g_dwTocEntry].dwImageType) ) {
        EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: INVALID_IMAGE_TYPE: 0x%x\r\n",
            g_pTOC->id[g_dwTocEntry].dwImageType);
        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) && !pChainInfo ; nCount++)
    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);
                EdbgOutputDebugString("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));
                    EdbgOutputDebugString("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;
                EdbgOutputDebugString("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;
        EdbgOutputDebugString("Writing multi-regions\r\n");

        for (nCount = 0, dwBINFSPartLength = 0 ; nCount < dwNumExts ; nCount++)
        {
            dwBINFSPartLength += (pChainInfo + nCount)->dwMaxLength;
            EdbgOutputDebugString("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;
                    EdbgOutputDebugString("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;
        EdbgOutputDebugString("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( NEXT_FREE_LOC,
                              FILE_TO_SECTOR_SIZE(dwBINFSPartLength) + 1, // sizeof image + MBR sector
                              PART_BINFS,
                              TRUE,
                              PART_OPEN_ALWAYS);
*/

    hPart = BP_OpenPartition( (IMAGE_START_BLOCK+1)*PAGES_PER_BLOCK,	// next block of MBR
                              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 )
    {
        EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: Failed to open/create BINFS 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;

        EdbgOutputDebugString("dwRegionStart: 0x%x, dwRegionLength: 0x%x, dwStoreOffset: 0x%x\r\n",
            dwRegionStart, dwRegionLength, dwStoreOffset);

        // Set the file pointer (byte indexing) to the correct offset for this particular region.
        //
        if ( !BP_SetDataPointer(hPart, dwStoreOffset) )
        {
            EdbgOutputDebugString("ERROR: StoreImageToBootMedia: Failed to set data pointer in BINFS 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);

            EdbgOutputDebugString("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]);

            EdbgOutputDebugString("Written Chain Region to the Flash\n");
            EdbgOutputDebugString("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);
//            memcpy((void *)0x8c050000, (void *)dwRegionStart, dwRegionLength);
        }
    }

    // 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 )
    {
        EdbgOutputDebugString("*** WARN: StoreImageToBootMedia: Failed to open/create Extended partition ***\r\n");
    }

    EdbgOutputDebugString("-WriteRegionsToBootMedia\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 ReadKernelRegionFromBootMedia( )
{
    HANDLE hPart;
    SectorInfo si;
	DWORD 	chainaddr, flashaddr;
	int i;

    if (!g_bBootMediaExist) {
        EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: device doesn't exist.\r\n");
        return(FALSE);
    }

    if ( !VALID_TOC(g_pTOC) ) {
        EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: INVALID_TOC\r\n");
        return(FALSE);
    }

    if ( !(IMAGE_TYPE_BINFS & g_pTOC->id[g_dwTocEntry].dwImageType) ) {
        EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: INVALID_IMAGE_TYPE: 0x%x\r\n",
            g_pTOC->id[g_dwTocEntry].dwImageType);
        return(FALSE);
    }

    if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) ) {
        EdbgOutputDebugString("OEMPlatformInit: 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 )
    {
        EdbgOutputDebugString("OEMPlatformInit: 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;
    }

    EdbgOutputDebugString("INFO: Loading image from Boot Media to RAM (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);

    // 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 )
    {
        EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to open existing BINFS 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) )
    {
        EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to set data pointer in BINFS 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)) )
    {
        EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to read kernel region from BINFS partition.\r\n");
        return(FALSE);
    }



    EdbgOutputDebugString("g_pTOC->chainInfo.dwLength=0x%x\r\n", g_pTOC->chainInfo.dwLength);

	chainaddr = g_pTOC->chainInfo.dwLoadAddress;
	flashaddr = g_pTOC->chainInfo.dwFlashAddress;
	for ( i = 0; i < (g_pTOC->chainInfo.dwLength); i++ )
	{
	    EdbgOutputDebugString("chainaddr=0x%x, flashaddr=0x%x\r\n", chainaddr, flashaddr+i);

		if ( !FMD_ReadSector(flashaddr+i, (PUCHAR)(chainaddr), &si, 1) ) {
			EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOC\r\n");
			return FALSE;
		}
		chainaddr += 512;
	}
	{
		int i;
		for ( i = 0; i < 60; i++ )
			EdbgOutputDebugString("[0x%x]0x%x ", g_pTOC->chainInfo.dwLoadAddress + i, *(LPBYTE)(g_pTOC->chainInfo.dwLoadAddress + i));
	}

    return(TRUE);
}


BOOL ReadRamImageFromBootMedia( )
{
    DWORD dwSectorsNeeded;
    DWORD dwSector, dwLength;   // Start Sector & Length
    DWORD dwLoadAddress, dwJumpAddr, i;

    if ( !TOC_Read( ) ) { // should already be read
        return FALSE;
    }

    // is this a RAM image?
    // N.B: we can't read BinFS regions because we don' know where they are in g_pTOC->id[dwEntry].sgList[i].dwSector
    if ( g_pTOC->id[g_dwTocEntry].dwImageType != IMAGE_TYPE_RAMIMAGE ) {
        EdbgOutputDebugString("ReadRamImageFromBootMedia ERROR: TOC[%u] not a RAM image: 0x%x\r\n",
            g_dwTocEntry, g_pTOC->id[g_dwTocEntry].dwImageType);
        return FALSE;
    }

    dwSectorsNeeded = g_pTOC->id[g_dwTocEntry].dwTtlSectors;
    dwLoadAddress   = g_pTOC->id[g_dwTocEntry].dwLoadAddress;
    dwJumpAddr      = g_pTOC->id[g_dwTocEntry].dwJumpAddress ? g_pTOC->id[g_dwTocEntry].dwJumpAddress :
                                                          g_pTOC->id[g_dwTocEntry].dwLoadAddress;

    EdbgOutputDebugString("dwSectorsNeeded: 0x%x,  dwLoadAddress: 0x%x, dwJumpAddr: 0x%x\r\n",
        dwSectorsNeeded, dwLoadAddress, dwJumpAddr);

    //
    // Load the disk image directly into RAM
    // BUGBUG: recover from read failures
    //
    i = 0;
	while (dwSectorsNeeded && i < MAX_SG_SECTORS)
	{
        dwSector = g_pTOC->id[g_dwTocEntry].sgList[i].dwSector;
        dwLength = g_pTOC->id[g_dwTocEntry].sgList[i].dwLength;

        // read each sg segment
        while (dwLength) {

            if ( !FMD_ReadSector(dwSector, (LPBYTE)dwLoadAddress, NULL, 1) ) {
                EdbgOutputDebugString("ReadRamImageFromBootMedia ERROR reading sector: 0x%x\r\n", dwSector);
                return FALSE;
            }

    		dwSector++;
    		dwLength--;
            dwLoadAddress += SECTOR_SIZE;
        }

        dwSectorsNeeded -= dwLength;
        i++;
    }

    return TRUE;
}

BOOL WriteRamImageToBootMedia(DWORD dwEntry)
{
    EdbgOutputDebugString("*** ERROR: WriteRamImageToBootMedia: NOT IMPLEMENTED *** \r\n");
    return FALSE;
}

⌨️ 快捷键说明

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