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

📄 main.c

📁 windows wm5 下的bootloader代码
💻 C
字号:
//
// 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.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name: main.c

Abstract: OEM IPL routines for the Samsung SMDK2410 hardware platform.

Functions:

Notes:

--*/
#include <windows.h>
#include <iplcommon.h>
#include <bootpart.h>   // Needed for partition types...
#include <bsp.h>
#include <fmd.h>
#include <am29lv800.h>

// Version number
#define IPL_VERSION_MAJOR 1
#define IPL_VERSION_MINOR 2

// Virtual address of bootpart work buffer.
//
#define BPART_BUFFER_U_VIRTUAL    0xA0121000
#define BPART_BUFFER_LENGTH_BYTES 0x00020000

// Global variables.
//
// --- These are used by iplcommon (start) ---
UINT32 g_ulFlashBase        = 0;                            // Flash start and length.
UINT32 g_ulFlashLengthBytes = AMD_FLASH_SIZE - IMAGE_IPL_SIZE;

UINT32 g_ulBPartBase        = BPART_BUFFER_U_VIRTUAL;       // BootPart work buffer start and length.
UINT32 g_ulBPartLengthBytes = BPART_BUFFER_LENGTH_BYTES;
// --- These are used by iplcommon (end)   ---


// External variables.
//
extern PFN_MessageHandler g_pfnMessageHandler;

// Function prototypes.
//
void OEMInitDebugSerial(void);
void OEMWriteDebugString(unsigned short *str);
static void OEMMessageHandler(IPL_MESSAGE_CODE MessageCode, LPWSTR pMessageString);
void Launch(UINT32 ulLaunchAddr);
void InitBSPArgs();

void main(void)
{
    // Call into the IPLcommon main routine.
    //
    IPLmain();

}


static void OEMMessageHandler(IPL_MESSAGE_CODE MessageCode, LPWSTR pMessageString)
{

    // Write a hex LED code.
    //
    OEMWriteDebugString((UINT16 *)pMessageString);

}


/*
    @func   BOOL | ReadBootConfig | Read bootloader settings from flash.
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm   This routine came from eboot\main.c 
    @xref   
*/
static BOOL ReadBootConfig(PBOOT_CFG pBootCfg)
{
    BOOLEAN bResult = FALSE;

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

    // Valid caller buffer?
    if (!pBootCfg)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Bad caller buffer.\r\n")));
        goto CleanUp;
    }

    // Read settings from flash...
    //
    if (!AM29LV800_ReadFlash(EBOOT_CONFIG_OFFSET, (PBYTE)pBootCfg, sizeof(BOOT_CFG)))
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Flash read failed.\r\n")));
        goto CleanUp;
    }

    // Check configuration signature...
    //
    if (pBootCfg->Signature != CONFIG_SIGNATURE)
    {
        OALMSG(OAL_WARN, (TEXT("WARNING: Boot configuration signature invalid - choosing defaults...\r\n")));
        memset(pBootCfg, 0, sizeof(*pBootCfg));
        // We'll just treat all the settings as uninitialized.
    }

    bResult = TRUE;

CleanUp:

    OALMSG(OAL_FUNC, (TEXT("-ReadBootConfig.\r\n")));
    return(bResult);

}


#define COMPILE_TIME_ASSERT(condition) { int compile_time_assert[(condition)]; compile_time_assert; }


void InitBSPArgs()
{
    UINT8 maccount = 0;
    BSP_ARGS *pBSPArgs = ((BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START);
    BOOT_CFG BootCfg;

    // create the header
    pBSPArgs->header.signature       = OAL_ARGS_SIGNATURE;
    pBSPArgs->header.oalVersion      = OAL_ARGS_VERSION;
    pBSPArgs->header.bspVersion      = BSP_ARGS_VERSION;

    // store some KITL args
    pBSPArgs->kitl.flags = OAL_KITL_FLAGS_ENABLED | OAL_KITL_FLAGS_DHCP | OAL_KITL_FLAGS_VMINI;
    pBSPArgs->kitl.devLoc.IfcType = Internal;
    pBSPArgs->kitl.devLoc.BusNumber = 0;
    pBSPArgs->kitl.devLoc.LogicalLoc = BSP_BASE_REG_PA_CS8900A_IOBASE;
    pBSPArgs->kitl.ipAddress = 0;

    // Clear BSP Reserved Parameter.
    pBSPArgs->fUpdateMode = FALSE ;

    if (ReadBootConfig(&BootCfg)) 
    {
        COMPILE_TIME_ASSERT(sizeof(BootCfg.CS8900MAC) == sizeof(pBSPArgs->kitl.mac));
        memcpy(pBSPArgs->kitl.mac, BootCfg.CS8900MAC, sizeof(BootCfg.CS8900MAC));
    }

    // store a base name for the device and signal to KITL to extend it later
    strncpy(pBSPArgs->deviceId, BSP_DEVICE_PREFIX, OAL_KITL_ID_SIZE);
    pBSPArgs->kitl.flags |= OAL_KITL_FLAGS_EXTNAME;    
}



///////////////////////////////////////////////////////////////////////////////
// Required OEM IPL routines.
///////////////////////////////////////////////////////////////////////////////
// --- These are used by iplcommon (start) ---
BOOLEAN OEMIPLInit(void)
{

    // Initialize the UART.
    //
    OEMInitDebugSerial();

    OALLog(L"\r\nMicrosoft Windows CE IPL Version %d.%d for DeviceEmulator\r\n",IPL_VERSION_MAJOR,IPL_VERSION_MINOR);

    // Set the flash address
    g_ulFlashBase = AMD_FLASH_START_UA + IMAGE_IPL_SIZE;

    // Messaging handler callback.
    //
    g_pfnMessageHandler = OEMMessageHandler;

    return(TRUE);
}


BOOLEAN OEMGetUpdateMode(void)
{
    BOOL fUpdateMode = FALSE;
    BOOL *pfUpdateMode = NULL;

    // check the RAM flag
    pfUpdateMode = (BOOL *) OALArgsQuery(OAL_ARGS_QUERY_UPDATEMODE);
    if (pfUpdateMode == NULL)
    {
        OEMWriteDebugString(L"Invalid BSP Args - initializing to good values\r\n");
        InitBSPArgs();
    }
    else
    {
        fUpdateMode = *pfUpdateMode;
    }

    if (fUpdateMode)
    {
        OEMWriteDebugString(L"Update Mode RAM flag is set\r\n");
    }
    else
    {
        // RAM flag is not set - are we recovering from power failure?
        if (!BP_GetUpdateModeFlag(&fUpdateMode))
        {
            OEMWriteDebugString(L"Error in BP_GetUpdateModeFlag\r\n");
        }
        if (fUpdateMode)
        {
            OEMWriteDebugString(L"Update Mode Persistent flag is set\r\n");
        }
    }

    if (fUpdateMode)
    {
        OEMWriteDebugString(L"Launching the Update Loader\r\n");
    }
    
    return(fUpdateMode);
}


BOOLEAN OEMTranslateBaseAddress(UINT32 ulPartType, UINT32 ulAddr, UINT32 *pulTransAddr)
{

    if (pulTransAddr == NULL)
    {
        return(FALSE);
    }

    switch(ulPartType)
    {
    case PART_BOOTSECTION:
        // No translation.
        *pulTransAddr = ulAddr;
        break;
        
    case PART_XIP:
        *pulTransAddr = ulAddr | 0xa0000000;
        break;
        
    default:
        // No translation.
        *pulTransAddr = ulAddr;
        break;
    }

    return(TRUE);
}


void OEMLaunchImage(UINT32 ulLaunchAddr)
{
    UINT32 ulPhysicalJump = 0;

    // The IPL is running with the MMU on - before we jump to the loaded image, we need to convert
    // the launch address to a physical address and turn off the MMU.
    //

    // Convert jump address to a physical address.
    ulPhysicalJump = OALVAtoPA((void *)ulLaunchAddr);

    RETAILMSG(1, (TEXT("Jumping to VA 0x%x PA 0x%x...\r\n"), ulLaunchAddr, ulPhysicalJump));

    // Jump...
    Launch(ulPhysicalJump);
}

// --- These are used by iplcommon (end)   ---

⌨️ 快捷键说明

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