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

📄 iplmain.c

📁 三星2440原版bsp
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <pehdr.h>
#include <romldr.h>
#include <bootpart.h>
#include <iplcommon.h>
#include <bsp.h>
#include <fmd.h>
#include <cecompress.h>
#include <fallite.h>
#include <image_cfg.h>

// the minimum data we need from the first page of a partition
#define PARTITION_HEADER_BYTES     ROM_TOC_OFFSET_OFFSET + sizeof(DWORD)

// Globals.
//
// The IPL's table of contents pointer.
extern ROMHDR * volatile const pTOC;
extern Launch(DWORD dwLaunchAddr);

// Message handler callback function pointer.
PFN_MessageHandler g_pfnMessageHandler = NULL;
// Compressed Partition flag
BOOL g_fCompressed = FALSE;
// Compression Decoder Stream
CeCompressDecodeStream g_DecodeStream = NULL;
// Compression Header
PCOMPRESSED_RAMIMAGE_HEADER g_CompressionHeader = NULL;
// buffer for reading compression data
BYTE CompressedData[RAMIMAGE_COMPRESSION_BLOCK_SIZE];

// External variable definitions.
//
UINT32 g_ulFlashBase = 0x90E00000;          // Flash start and length.
UINT32 g_ulFlashLengthBytes = NAND_FLASH_SIZE - IMAGE_IPL_SIZE;

// Functions used for compression
BOOL InitDecompressor(HANDLE hPartition, DWORD dwHeaderSize);
VOID DeInitDecompressor();
LPVOID MyAlloc(LPVOID pIgnored, DWORD dwAllocSize);
VOID MyDeAlloc(LPVOID pIgnored, LPVOID pAddress);
BOOL CopyToRAM(HANDLE hPartition, DWORD dwPartitionBase);

// Local variables.
//
static UINT16 g_wSectorSize;
static void *g_pMessageTable[] = 
{
    TEXT("ERROR: Unable to find IPL table of contents.\0"),              // IPL_ERROR_BAD_IPLTOC
    TEXT("ERROR: Failed to initialize bootpart library.\0"),             // IPL_ERROR_BPINIT_FAILED
    TEXT("ERROR: Failed to open storage partition.\0"),                  // IPL_ERROR_OPENPARTITION_FAILED
    TEXT("ERROR: Failed to get storage type information.\0"),            // IPL_ERROR_GETSTRORAGETYPE_FAILED
    TEXT("ERROR: Failed to retrieve stored image information.\0"),       // IPL_ERROR_GETIMAGEINFO_FAILED
    TEXT("ERROR: Failed to translate image address.\0"),                 // IPL_ERROR_TRANSLATEADDR_FAILED
    TEXT("ERROR: Failed to read image data from storage partition.\0"),  // IPL_ERROR_READDATA_FAILED
    TEXT("ERROR: Failed to jump to loaded image.\0"),                    // IPL_ERROR_JUMP_FAILED
    TEXT("INFO: Loading image ...\r\n\0"),                               // IPL_INFO_LOADING_IMAGE
    TEXT("INFO: Jumping to image...\r\n\0")                              // IPL_INFO_JUMPING_IMAGE
};


/*
    @func   void | SpinForever | Halts execution.
    @rdesc  None.
    @comm    
    @xref   
*/
static void SpinForever(void)
{
    while(1)
    {
        // Do nothing.
    }
}


/*
    @func   void | MessageDispatch | Dispatches debug messages to the OEM message handler.
    @rdesc  None.
    @comm    
    @xref   
*/
static void MessageDispatch(IPL_MESSAGE_CODE MessageCode)
{
    // Dispatch the message to the OEM-provided message handler (if there is one).
    //
    if (g_pfnMessageHandler)
    {
        // Make sure we don't overstep the array boundary.
        //
        if (MessageCode >= (sizeof(g_pMessageTable)/sizeof(g_pMessageTable[0])))
        {
            return;
        }

        // Call the OEM's messange handler routine.
        //
        g_pfnMessageHandler(MessageCode, g_pMessageTable[MessageCode]);
    }

}


/*
    @func   BOOLEAN | SetupCopySection | Copies the IPL image's copy section data (initialized globals) to the correct fix-up location.  Once completed, the IPLs initialized globals are valid.
    @rdesc  TRUE == Success and FALSE == Failure.
    @comm    
    @xref   
*/
static BOOLEAN SetupCopySection(ROMHDR *const pTOC)
{
    UINT32 ulLoop;
    COPYentry *pCopyEntry;

    if (pTOC == (ROMHDR *const) -1)
    {
        return(FALSE);
    }

    // This is where the data sections become valid... don't read globals until after this
    //
    for (ulLoop = 0; ulLoop < pTOC->ulCopyEntries; ulLoop++)
    {
        pCopyEntry = (COPYentry *)(pTOC->ulCopyOffset + ulLoop*sizeof(COPYentry));
        if (pCopyEntry->ulCopyLen)
        {
            memcpy((LPVOID)pCopyEntry->ulDest, (LPVOID)pCopyEntry->ulSource, pCopyEntry->ulCopyLen);
        }
        if (pCopyEntry->ulCopyLen != pCopyEntry->ulDestLen)
        {
            memset((LPVOID)(pCopyEntry->ulDest+pCopyEntry->ulCopyLen), 0, pCopyEntry->ulDestLen-pCopyEntry->ulCopyLen);
        }
    }

    return(TRUE);

}


/*
    @func   BOOLEAN | ReadTOC | Locates the load image's table of contents (TOC) and reads the TOC into the caller-provided buffer.
    @rdesc  TRUE == Success and FALSE == Failure.
    @comm    
    @xref   
*/
static BOOLEAN ReadTOC(HANDLE hPartition, ROMHDR *pTOC)
{
    // TODO: statically allocate some big sector buffer size on the stack...
    BYTE SectorData[PARTITION_HEADER_BYTES];
    UINT32 TOCoffset = 0; 

    if (hPartition == INVALID_HANDLE_VALUE || pTOC == NULL)
    {
        return(FALSE);
    }

    // Restore the file pointer to the start of the partition.
    //
    if (!BP_SetDataPointer(hPartition, 0))
    {
        return(FALSE);
    }

    // Read the first sector - this contains the address of the table of contents.
    //
    if (!BP_ReadData(hPartition, SectorData, PARTITION_HEADER_BYTES))
    {
        return(FALSE);
    }

    // Valid table of contents address signature?
    //
    if (*(UINT32 *)(&SectorData[ROM_SIGNATURE_OFFSET]) != ROM_SIGNATURE)
    {
        return(FALSE);
    }
    TOCoffset = (*(UINT32 *)(&SectorData[ROM_TOC_OFFSET_OFFSET]));

    // Move the file pointer to the correct offset.
    //
    if (!BP_SetDataPointer(hPartition, TOCoffset))
    {
        return(FALSE);
    }
    
    // Read the table of contents.
    //
    if (!BP_ReadData(hPartition, (BYTE *)pTOC, sizeof(ROMHDR)))
    {
        return(FALSE);
    }

    // Restore the file pointer to the start of the partition.
    //
    if (!BP_SetDataPointer(hPartition, 0))
    {
        return(FALSE);
    }
    
    return(TRUE);

}


/*
    @func   BOOLEAN | GetImageInfo | Uses the image's table of contents (TOC) to locate the image start address, length, and jump address.
    @rdesc  TRUE == Success and FALSE == Failure.
    @comm    
    @xref   
*/
static BOOLEAN GetImageInfo(HANDLE hPartition, UINT32 *ulImageStartAddr)
{
    BYTE SectorData[PARTITION_HEADER_BYTES];
    PCOMPRESSED_RAMIMAGE_HEADER pCompHeader = NULL;
    DWORD dwTocLoc = 0, dwTocOffset = 0, dwBytesRead = 0;
    WORD wBlockSize = 0;

    if (hPartition == INVALID_HANDLE_VALUE || ulImageStartAddr == NULL)
    {
        return(FALSE);
    }

    // set the pointer to the beginning of the partition
    if (!BP_SetDataPointer(hPartition, 0))
    {
        return(FALSE);
    }

    // read the first page
    if (!BP_ReadData(hPartition, SectorData, PARTITION_HEADER_BYTES))
    {
        return(FALSE);
    }
    
    // is the partition compressed?
    pCompHeader = (PCOMPRESSED_RAMIMAGE_HEADER) SectorData;
    if ((pCompHeader->dwSignature == RAMIMAGE_COMPRESSION_SIGNATURE) &&
        (pCompHeader->dwVersion == RAMIMAGE_COMPRESSION_VERSION) &&
        (pCompHeader->dwCompressedBlockSize == RAMIMAGE_COMPRESSION_BLOCK_SIZE))
    {
        // initialize the compressor
        if (!InitDecompressor(hPartition, pCompHeader->dwHeaderSize))
        {
            return(FALSE);
        }

        // update the global "partition is compressed" flag
        g_fCompressed = TRUE;
        
        // set the data pointer to the first byte after the compressed header
        if (!BP_SetDataPointer(hPartition, g_CompressionHeader->dwHeaderSize))
        {
            return(FALSE);
        }

        // the compressed size of the first block is stored in pCompHeader
        wBlockSize = g_CompressionHeader->wBlockSizeTable[0];

        // read the first page into our compressed data buffer
        if (!BP_ReadData(hPartition, CompressedData, wBlockSize))
        {
            return(FALSE);
        }

        // if block size = max size, this block is not compressed
        if (wBlockSize == RAMIMAGE_COMPRESSION_BLOCK_SIZE)
        {
            // just copy data over into SectorData
            memcpy(SectorData, CompressedData, PARTITION_HEADER_BYTES);
        }
        else
        {
            // decompress the first page back into SectorData
            dwBytesRead = CeCompressDecode(g_DecodeStream, SectorData, RAMIMAGE_COMPRESSION_BLOCK_SIZE, PARTITION_HEADER_BYTES, CompressedData, wBlockSize);
            if (dwBytesRead != PARTITION_HEADER_BYTES)
            {
                return(FALSE);
            }
        }
    }

    // Valid table of contents address signature?
    if (*(UINT32 *)(&SectorData[ROM_SIGNATURE_OFFSET]) != ROM_SIGNATURE)
    {
        return(FALSE);
    }

    // Extract the start address, length, and jump address from the table of contents.
    //
    dwTocLoc = *(UINT32 *)(&SectorData[ROM_TOC_POINTER_OFFSET]);
    dwTocOffset= *(UINT32 *)(&SectorData[ROM_TOC_OFFSET_OFFSET]);        
    *ulImageStartAddr = dwTocLoc - dwTocOffset;

    return(TRUE);

⌨️ 快捷键说明

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