📄 main.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.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
// File: main.c
//
// Core routines for the Plato bootloader.
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <ethdbg.h>
#include <fmd.h>
#include "bsp.h"
#include "loader.h"
//-----------------------------------------------------------------------------
// External Functions
extern BOOL NANDLoadIPL(VOID);
extern BOOL NANDLoadNK(VOID);
extern BOOL FlashLoadEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize);
extern BOOL FlashStoreEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize);
extern void Launch(unsigned int uAddr);
extern BOOL BLMenu();
//-----------------------------------------------------------------------------
// External Variables
extern PCSP_PBC_REGS g_pPBC;
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
// Global Variables
DWORD EdbgDebugZone;
BSP_ARGS *g_pBSPArgs;
EDBG_ADDR g_DeviceAddr; // NOTE: global used so it remains in scope throughout download process
// since eboot library code keeps a global pointer to the variable provided.
IMAGE_TYPE g_ImageType;
IMAGE_MEMORY g_ImageMemory;
EBOOT_CFG g_EbootCFG;
BOOL g_DownloadImage = TRUE;
UCHAR *g_DefaultRamAddress;
BOOL g_bNandBootloader;
BOOL g_bNandExist;
// Used to save information about downloaded DIO mage
EBOOT_BINDIO_CONTEXT g_BinDIO;
//-----------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
// Local Functions
//
BOOL LoadEBootCFG(EBOOT_CFG *EBootCFG);
BOOL StoreEBootCFG(EBOOT_CFG *EBootCFG);
void ResetDefaultEBootCFG(EBOOT_CFG *pEbootCFG);
BOOL OEMVerifyMemory(DWORD dwStartAddr, DWORD dwLength);
void OEMMultiBINNotify(const PMultiBINInfo pInfo);
//------------------------------------------------------------------------------
//
// Function: main
//
// Bootloader main routine.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void main(void)
{
// Common boot loader (blcommon) main routine.
//
BootloaderMain();
// Should never get here.
//
SpinForever();
}
//------------------------------------------------------------------------------
//
// Function: OEMDebugInit
//
// This function is the first called by the BLCOMMON framework when a boot
// loader starts. This function initializes the debug transport, usually just
// initializing the debug serial universal asynchronous receiver-transmitter
// (UART).
//
// Parameters:
// None.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//------------------------------------------------------------------------------
BOOL OEMDebugInit (void)
{
OEMInitDebugSerial();
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: OEMPlatformInit
//
// This function initializes the platform and is called by the BLCOMMON
// framework.
//
// Parameters:
// None.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//------------------------------------------------------------------------------
BOOL OEMPlatformInit (void)
{
PCSP_CCM_REGS pCCM;
UINT32 rcsr;
KITLOutputDebugString("Microsoft Windows CE Ethernet Bootloader %d.%d for MX31 ADS (%s %s)\r\n",
EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, __DATE__, __TIME__);
// Get reset status from CCM
pCCM = (PCSP_CCM_REGS) OALPAtoUA(CSP_BASE_REG_PA_CCM);
rcsr = INREG32(&pCCM->RCSR);
// Determine boot mode
switch(CSP_BITFEXT(rcsr, CCM_RCSR_BTP))
{
// BOOT[4:0] configured for NAND boot
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x10:
case 0x11:
case 0x12:
case 0x13:
g_bNandBootloader = TRUE;
KITLOutputDebugString("INFO: Bootloader launched from NAND\r\n");
break;
// Otherwise assume NOR bootloader
default:
KITLOutputDebugString("INFO: Bootloader launched from NOR\r\n");
g_bNandBootloader = FALSE;
break;
}
// Check for image reflash flag from RVD
if (CSP_BITFEXT(rcsr, CCM_RCSR_GPF) == 0xF)
{
KITLOutputDebugString("Reflash request detected!\r\n");
// Write out the image previously downloaded into SDRAM
// by RVD
OEMWriteFlash((DWORD) OALPAtoCA(IMAGE_BOOT_NORDEV_NOR_PA_START), IMAGE_BOOT_NORDEV_NOR_SIZE);
// EBOOT download is unnecessary since RVD downloaded image via JTAG
g_DownloadImage = FALSE;
// Jump to OS image
OEMLaunch(0, 0, (DWORD) OALPAtoCA(IMAGE_BOOT_NKIMAGE_NOR_PA_START), NULL);
}
// Attempt to initialize the NAND flash driver
if (!FMD_Init(NULL, NULL, NULL))
{
KITLOutputDebugString("WARNING: OEMPlatformInit: Failed to initialize NAND flash device.\r\n");
g_bNandExist = FALSE;
}
else
{
KITLOutputDebugString("INFO: OEMPlatformInit: Initialized NAND flash device.\r\n");
g_bNandExist = TRUE;
}
// Load eboot configuration
//
if (!LoadEBootCFG(&g_EbootCFG))
{
// Load default bootloader configuration settings.
KITLOutputDebugString("ERROR: flash initialization failed - loading bootloader defaults...\r\n");
ResetDefaultEBootCFG(&g_EbootCFG);
}
// Set up optional bootloader function pointers.
//
g_pOEMMultiBINNotify = OEMMultiBINNotify;
g_pOEMVerifyMemory = OEMVerifyMemory;
// Initialize the BSP args structure.
//
g_pBSPArgs = (BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START;
if ((g_pBSPArgs->header.signature != OAL_ARGS_SIGNATURE) ||
(g_pBSPArgs->header.oalVersion != OAL_ARGS_VERSION) ||
(g_pBSPArgs->header.bspVersion != BSP_ARGS_VERSION))
{
memset((LPVOID)g_pBSPArgs, 0, sizeof(BSP_ARGS));
g_pBSPArgs->header.signature = OAL_ARGS_SIGNATURE;
g_pBSPArgs->header.oalVersion = OAL_ARGS_VERSION;
g_pBSPArgs->header.bspVersion = BSP_ARGS_VERSION;
g_pBSPArgs->kitl.flags = (OAL_KITL_FLAGS_ENABLED | OAL_KITL_FLAGS_VMINI);
g_pBSPArgs->kitl.devLoc.IfcType = Internal;
g_pBSPArgs->kitl.devLoc.BusNumber = 0;
g_pBSPArgs->kitl.devLoc.LogicalLoc = BSP_BASE_REG_PA_CS8900A_IOBASE;
g_pBSPArgs->updateMode = FALSE;
}
// Update global BSP args struct with user switches on ADS board
OALBspArgsInit(g_pBSPArgs);
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: OEMPreDownload
//
// This function is called by the BLCOMMON framework prior to download and can
// be customized to prompt for user feedback, such as obtaining a static IP
// address or skipping the download and jumping to a flash-resident run-time
// image.
//
// Parameters:
// None.
//
// Returns:
// Possible return values for OEMPreDownload:
//
// Value Description
// ----- -----------
// BL_DOWNLOAD = 0 Download the OS image from the host machine.
// BL_JUMP = 1 Skip the download and jump to a resident OS image.
// BL_ERROR = -1 Image download is unsuccessful.
//------------------------------------------------------------------------------
DWORD OEMPreDownload(void)
{
UINT32 rc = BL_ERROR;
UINT32 SubnetMask;
BOOL fGotJumpImg = FALSE, fGotIP = FALSE;
UINT32 DHCPLeaseTime = 0;
UINT32 *pDHCPLeaseTime = &DHCPLeaseTime;
UINT32 BootFlags = 0;
// User menu code...
//
if (!BLMenu())
{
return (BL_ERROR);
}
// Create device name based on Ethernet address (this is how Platform Builder identifies this device).
//
OALKitlCreateName(BSP_DEVICE_PREFIX, g_pBSPArgs->kitl.mac, g_pBSPArgs->deviceId);
KITLOutputDebugString("INFO: Using device name: '%s'\n", g_pBSPArgs->deviceId);
// Check if the user wants to use DHCP
//
if (g_EbootCFG.DHCPEnable == FALSE)
{
pDHCPLeaseTime = NULL;
g_pBSPArgs->kitl.ipAddress = g_EbootCFG.IP;
g_pBSPArgs->kitl.ipMask = g_EbootCFG.subnetMask;
g_pBSPArgs->kitl.flags &= ~OAL_KITL_FLAGS_DHCP;
}
// Initialize Ethernet transport if we are in active KITL mode or we
// need to download the image
if (g_DownloadImage)
{
// Initialize the TFTP transport.
memcpy(g_DeviceAddr.wMAC, g_pBSPArgs->kitl.mac, (sizeof(UINT16) * 3));
g_DeviceAddr.dwIP = g_pBSPArgs->kitl.ipAddress;
g_DeviceAddr.wPort = 0;
SubnetMask = g_pBSPArgs->kitl.ipMask;
if (!EbootInitEtherTransport(&g_DeviceAddr,
&SubnetMask,
&fGotJumpImg,
pDHCPLeaseTime,
EBOOT_VERSION_MAJOR,
EBOOT_VERSION_MINOR,
BSP_DEVICE_PREFIX,
g_pBSPArgs->deviceId,
EDBG_CPU_ARM720,
BootFlags))
{
return(BL_ERROR);
}
// If the user wanted a DHCP address, save the values obtained in the init call above.
//
if (g_EbootCFG.DHCPEnable == TRUE)
{
g_pBSPArgs->kitl.ipAddress = g_DeviceAddr.dwIP;
g_pBSPArgs->kitl.ipMask = SubnetMask;
g_pBSPArgs->kitl.flags |= OAL_KITL_FLAGS_DHCP;
}
}
if (!g_DownloadImage || // this gets set in the BLMenu() function
fGotJumpImg) // this gets set in EbootInitEtherTransport
{
switch(g_EbootCFG.autoDownloadImage)
{
case EBOOT_CFG_AUTODOWNLOAD_NK_NOR:
rc = BL_JUMP;
break;
case EBOOT_CFG_AUTODOWNLOAD_NK_NAND:
if (NANDLoadNK())
{
rc = BL_JUMP;
}
else
{
KITLOutputDebugString("ERROR: Failed to load OS image from NAND.\r\n");
}
break;
case EBOOT_CFG_AUTODOWNLOAD_IPL_NAND:
if (NANDLoadIPL())
{
rc = BL_JUMP;
}
else
{
KITLOutputDebugString("ERROR: Failed to load IPL image from NAND.\r\n");
}
break;
}
// Set the clean boot flag so that OAL will let the kernel know that
// it needs a clean boot
//
// g_pBSPArgs->bCleanBootFlag = TRUE;
}
else if (g_DownloadImage)
{
rc = BL_DOWNLOAD;
}
return(rc);
}
//------------------------------------------------------------------------------
//
// Function: OEMLaunch
//
// This function launches the run-time image. It is the last one called by
// the BLCOMMON framework.
//
// Parameters:
// dwImageStart
// [in] Starting address of OS image.
//
// dwImageLength
// [in] Length, in bytes, of the OS image.
//
// dwLaunchAddr
// [in] First instruction of the OS image.
//
// pRomHdr
// [out] Pointer to the ROM header structure.
//
// Returns:
// None.
//------------------------------------------------------------------------------
void OEMLaunch (DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr)
{
EDBG_OS_CONFIG_DATA *pCfgData;
EDBG_ADDR EshellHostAddr;
UINT32 PhysAddress;
switch(g_EbootCFG.autoDownloadImage)
{
case EBOOT_CFG_AUTODOWNLOAD_NK_NOR:
// Set launch address for NOR OS image. OS executes-in-place from NOR.
PhysAddress = IMAGE_BOOT_NKIMAGE_NOR_PA_START;
break;
case EBOOT_CFG_AUTODOWNLOAD_NK_NAND:
// Set launch address for NAND OS image. OS is copied into RAM for execution.
PhysAddress = IMAGE_BOOT_NKIMAGE_RAM_PA_START;
break;
case EBOOT_CFG_AUTODOWNLOAD_IPL_NAND:
// Set launch address for NAND IPL image. IPL is copied into RAM for execution.
PhysAddress = IMAGE_BOOT_IPLIMAGE_RAM_START;
break;
default:
// If a launch address wasn't specified - use the last known good address.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -