Beispiel #1
0
/*
    @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()
{
    HANDLE hPart;
    SectorInfo si;
	DWORD 	chainaddr, flashaddr;
	DWORD i;

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

    if (!g_bBootMediaExist)
    {
	    OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: 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;
    }

    // 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), &si, 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);
}
static
UINT32
ReadFlashNK(
    )
{
    UINT32 rc = (UINT32) BL_ERROR;
    HANDLE hPartition;
    ROMHDR *pTOC;
    ULONG offset, size;
    UCHAR *pData;
    DWORD *pInfo;
    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;


    // Check if there is a valid image
    OALMSG(OAL_INFO, (L"\r\nLoad NK image from flash memory\r\n"));

    // Initialize boot partition library
    if (!BP_Init((LPBYTE)g_ulBPartBase, g_ulBPartLengthBytes, NULL, &regInfo, NULL))
    {
        OALLog(L"ReadFlashNK: Error initializing bootpart library!!\r\n");
        goto cleanUp;
    }
    
    // Open OS boot partition
    hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, PART_BOOTSECTION, FALSE, PART_OPEN_EXISTING);
    if (hPartition == INVALID_HANDLE_VALUE)
    {
        OALMSG(OAL_ERROR, (L"ERROR: OS partition not found!\r\n"));
        goto cleanUp;
    }
    
    BP_SetDataPointer(hPartition, 0);
    
    // Set address where to place image
    pData = (UCHAR*)IMAGE_WINCE_CODE_CA;


    // First read 4kB with pointer to TOC
    offset = 0;
    size = 4096;
    if (!BP_ReadData(hPartition, pData + offset, size))
    {
        OALMSG(OAL_ERROR, (L"ERROR: Error reading OS partition!\r\n"));
        goto cleanUp;
    }

    // Verify that we get CE image
    pInfo = (DWORD*)(pData + ROM_SIGNATURE_OFFSET);
    if (*pInfo != ROM_SIGNATURE)
        {
        OALMSG(OAL_ERROR, (L"ERROR: "
            L"Image signature not found\r\n"
            ));
        goto cleanUp;
        }

    // Read image up through actual TOC
    offset = size;
    size = pInfo[2] - size + sizeof(ROMHDR);
    if (!BP_ReadData(hPartition, pData + offset, size))
    {
        OALMSG(OAL_ERROR, (L"ERROR: "
            L"BP_ReadData call failed!\r\n"
            ));
        goto cleanUp;
     }

    // Verify image
    if (!VerifyImage(pData, &pTOC))
        {
        OALMSG(OAL_ERROR, (L"ERROR: "
            L"NK image doesn't have ROM signature\r\n"
            ));
        goto cleanUp;
        }

    // Read remainder of image
    offset += size;
    size = pTOC->physlast - pTOC->physfirst - offset;
    if (!BP_ReadData(hPartition, pData + offset, size))
    {
        OALMSG(OAL_ERROR, (L"ERROR: "
            L"BP_ReadData call failed!\r\n"
            ));
        goto cleanUp;
    }

    OALMSG(OAL_INFO, (L"NK Image Loaded\r\n"));

    // Done
    g_eboot.launchAddress = OALVAtoPA((UCHAR*)IMAGE_WINCE_CODE_CA);
    rc = BL_JUMP;

cleanUp:
    return rc;
}