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

📄 main.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*   The content of this file or document is CONFIDENTIAL and PROPRIETARY
*   to Jade Technologies Co., Ltd.  It is subjected to the terms of a
*   License Agreement between Licensee and Jade Technologies Co., Ltd.
*   restricting among other things, the use, reproduction, distribution
*   and transfer.  Each of the embodiments, including this information 
*   and any derivative work shall retain this copyright notice.
* 
*   Copyright (c) 2004 - 2005 Jade Technologies Co., Ltd. 
*   All rights reserved.
*/
// ----------------------------------------------------------------
// File:     main.c,v
// Revision: 1.0
// ----------------------------------------------------------------
// $
//
//------------------------------------------------------------------------------
//
//  Module Name:
//      main.c
//
//  Abstract:
//      Ethernet boot loader main module. This file contains the C main
//      for the boot loader.    NOTE: The firmware "entry" point (the real
//      entry point is _EntryPoint in init assembler file.
//
//      The Windows CE boot loader is the code that is executed on a Windows CE
//      development system at power-on reset and loads the Windows CE
//      operating system. The boot loader also provides code that monitors
//      the behavior of a Windows CE platform between the time the boot loader
//      starts running and the time the full operating system debugger is
//      available. Windows CE OEMs are supplied with sample boot loader code
//      that runs on a particular development platform and CPU.
//
//  Functions:
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <blcommon.h>
#include <halether.h>
#include <ceddk.h>
#include <ethdbg.h>
#include <nkintr.h>
#include <armintboot.h>
#include <sizes.h>
#include <platform.h>
#include <flash_lib.h>
#include <cdefs.h>
#include <oalfuncs.h>


#include "eboot.h"

//
// User-input definitions.
//
#define BACKSPACE           0x08
#define IPADDR_MAX          16      // strlen ("xxx.xxx.xxx.xxx") + NULL = 15

typedef VOID (*PFN_LAUNCH)(VOID);

DWORD EdbgDebugZone;
BLDR_SETTINGS g_BldrSettings;
static ETH_HARDWARE_INIT_ARGS g_InitArgs;
static EDBG_ADDR g_MyAddr;
static BOOL g_fWait = TRUE; // Wait for desktop?

//
// External definitions.
//
extern ROMHDR * volatile const pTOC;

//
// Function prototypes.
//
static BOOLEAN ReadFlashSettings(PBLDR_SETTINGS pSettings);
static BOOLEAN WriteFlashSettings(PBLDR_SETTINGS pSettings);
static BOOLEAN VerifyFlashSettings(PBLDR_SETTINGS pSettings);
static BOOLEAN WriteDefaultFlashSettings(void);
static BOOLEAN UserInterrupt(void);
static void LoaderMainMenu(void);

void CreateDeviceName(EDBG_ADDR *pMyAddr, char *szBuf, LPSTR szPlatformString);

static void SpinForever(void)
{
    EdbgOutputDebugString("SpinForever...\r\n");

    while(1)
    {
        ;
    }
}


int EverythingRelocate(void)
{
    int len;
    ROMHDR *ptoc;
    unsigned int pc, *toc, offset;

    /*
     * First make sure we're running in flash, in
     * which case we want to copy everything into
     * RAM.
     */
    pc = GetPC();
    if ((pc <= PHYS_FLASH_BASE) || (pc >= ARMVPB_FLASH_END))
        return -1;

    /*
     * This mess is because the eboot image is built
     * to run in RAM, but is currently stored in flash.
     * So we have to calculate the pTOC's address
     * relative to the flash address.
     */
    offset = BLDR_FLASH_BASE - ((unsigned int)(&pTOC) & 0xffff0000);
    toc = (unsigned int *)((int)(&pTOC) + offset);
    ptoc = (ROMHDR *)((int)(*toc) + offset);

    if (ptoc == (ROMHDR *)-1)
    {
        EdbgOutputDebugString("No TOC found!\r\n");
        SpinForever();
    }

    len = (ptoc->physlast - ptoc->physfirst);
    memcpy((void *)(ptoc->physfirst), (void *)BLDR_FLASH_BASE, len);

    return (ptoc->physfirst + 0x1000);
}


void
OEMLaunch(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, 
          const ROMHDR *pRomHdr)
{
    EDBG_OS_CONFIG_DATA *pCfgData;    
    EDBG_ADDR EshellHostAddr;
    HARP_BOOT_ARGS *pBootArgs = g_InitArgs.pBootArgs;

   // apCHARLCD_PrintXY(0, 0, "Go...       " );

    memset (&EshellHostAddr, 0, sizeof (EshellHostAddr));

    EdbgOutputDebugString("INFO: Preparing to launch\r\n");

    if (g_fWait)    // Wait for host connection?
    {
        if (!(pCfgData = EbootWaitForHostConnect(&g_MyAddr, &EshellHostAddr)))
        {
            EdbgOutputDebugString("ERROR: EbootWaitForHostConenct failed, spin forever\r\n");
            SpinForever();
        }

        // update service information
        if (pCfgData->Flags & EDBG_FL_DBGMSG)
        {
    
            EdbgOutputDebugString("INFO: Enabling debug messages over Ethernet, IP: %s, port:%u\n", 
                    inet_ntoa(pCfgData->DbgMsgIPAddr),ntohs(pCfgData->DbgMsgPort));
    
            memcpy(&pBootArgs->DbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
            pBootArgs->DbgHostAddr.dwIP  = pCfgData->DbgMsgIPAddr;
            pBootArgs->DbgHostAddr.wPort = pCfgData->DbgMsgPort;
        }
        if (pCfgData->Flags & EDBG_FL_PPSH)
        {
    
            EdbgOutputDebugString("INFO: Enabling CESH over Ethernet,           IP: %s, port:%u\n", 
                    inet_ntoa(pCfgData->PpshIPAddr),ntohs(pCfgData->PpshPort));
    
            memcpy(&pBootArgs->CeshHostAddr.wMAC,&EshellHostAddr.wMAC,6);
            pBootArgs->CeshHostAddr.dwIP  = pCfgData->PpshIPAddr;
            pBootArgs->CeshHostAddr.wPort = pCfgData->PpshPort;
        }
        if (pCfgData->Flags & EDBG_FL_KDBG)
        {
            EdbgOutputDebugString("INFO: Enabling KDBG over Ethernet,           IP: %s, port:%u\n", 
                    inet_ntoa(pCfgData->KdbgIPAddr),ntohs(pCfgData->KdbgPort));
        
            memcpy(&pBootArgs->KdbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
            pBootArgs->KdbgHostAddr.dwIP  = pCfgData->KdbgIPAddr;
            pBootArgs->KdbgHostAddr.wPort = pCfgData->KdbgPort;
        }
        pBootArgs->ucEshellFlags = pCfgData->Flags;
        pBootArgs->EdbgFlags = BOOTARG_SIG;
        memcpy (&pBootArgs->EshellHostAddr, &EshellHostAddr, sizeof(EDBG_ADDR));
    }

    // If a launch address wasn't specified - use the last known good address.
    // 
    if (!dwLaunchAddr)
    {
        dwLaunchAddr = g_BldrSettings.nJumpAddr;
    }
    else if (dwLaunchAddr != g_BldrSettings.nJumpAddr)
    {
        if( g_BldrSettings.nFlags & BLDR_SETTINGS_FLAGS_FSHDLOAD )
        {
            // Force a flash boot so use the bootloader settings
            dwLaunchAddr = g_BldrSettings.nJumpAddr;
            EdbgOutputDebugString("INFO: Forcing boot from flash\r\n");
        }
        else
        {
            // Have a new address to use
            g_BldrSettings.nJumpAddr = dwLaunchAddr;
        }
    }

    // Make suer the flash settings are up to date
    if (!WriteFlashSettings(&g_BldrSettings))
    {
        EdbgOutputDebugString("WARNING: Unable to save jump address in flash.\r\n");
    }
    
    EdbgOutputDebugString("INFO: Jumping to image (0x%x)...\r\n", dwLaunchAddr);

    ((PFN_LAUNCH)(dwLaunchAddr))();

    // Should never be reached...
  //  apCHARLCD_PrintXY(0, 0, "**" );
    SpinForever();
}


void OEMShowProgress(DWORD dwPacketNum)
{
    return;
}


BOOL OEMReadData(DWORD cbData, LPBYTE pbData)
{
    return(EbootEtherReadData(cbData, pbData));
}


void EbootMain(void)
{
    // Common bootloader main routine.
    BootloaderMain();

    // Should never get here.
    SpinForever();
}


// Callback to initialize serial debug hardware.
BOOL OEMDebugInit(void)
{
    // Initialize our debug UART.
    OEMInitDebugSerial();

    return(TRUE);
}


// Callback to initialize the platform.
BOOL OEMPlatformInit(void)
{
    HARP_BOOT_ARGS *pBootArgs = NULL;
    BOOL fRet = FALSE;
    UCHAR i = 0;

    EdbgOutputDebugString("JADE Windows CE Ethernet Bootloader %d.%d for Z228 (%s)\n",
                          EBOOT_VERSION_MAJOR,EBOOT_VERSION_MINOR, __DATE__);

    //
    // Initialize the local variable structures.
    //
    memset(&g_InitArgs, 0, sizeof(ETH_HARDWARE_INIT_ARGS));
    memset(&g_MyAddr, 0, sizeof(EDBG_ADDR));

   // apCHARLCD_SetUp();

    // Retrieve network settings from flash.  If the flash region hasn't been
    // prepared, choose and store default network settings.
    //
    memset(&g_BldrSettings, 0, sizeof(BLDR_SETTINGS));
    ReadFlashSettings(&g_BldrSettings);
    if (!VerifyFlashSettings(&g_BldrSettings))
    {
        EdbgOutputDebugString("INFO: Flash settings are bad - storing defaults...\r\n");
        if( WriteDefaultFlashSettings() )
        {
            if (!ReadFlashSettings(&g_BldrSettings))
            {
                EdbgOutputDebugString("ERROR: Unable to read settings from flash.\r\n");
                return(FALSE);
            }
        }
        else
        {
            EdbgOutputDebugString("ERROR: Failed to write settings to flash.\r\n");
            return(FALSE);
        }
    }
    //
    // Allow user to interrupt the loader to alter settings.
    //
    if (UserInterrupt())
    {
        LoaderMainMenu();
        //
        // User may have altered settings - re-read them.
        //
        if (!ReadFlashSettings(&g_BldrSettings))
        {
            EdbgOutputDebugString("ERROR: Unable to read settings from flash.\r\n");
            return(FALSE);
        }
	
    }
		 
    fRet = OEMEthHardwareInit(&g_InitArgs, &g_MyAddr);

    if (!fRet)
    {
        EdbgOutputDebugString("ERROR: Failed to initialize OEM Hardware!\r\n");
        return(FALSE);
    }

    pBootArgs = g_InitArgs.pBootArgs;
    if (pBootArgs == NULL)
    {
        //
        // OEM must supply some memory for boot args that the image can read.
        //
        EdbgOutputDebugString("ERROR: Failed to initialize BootArgs pointer!\r\n");
        SpinForever();
    }

    pBootArgs->dwSig            = BOOTARG_SIG;
    pBootArgs->dwEdbgDebugZone  = EDBG_PHYS_MEMORY_START;
    pBootArgs->dwLen            = sizeof(HARP_BOOT_ARGS);

    //
    // Copy the MAX address from g_InitArgs to local variable.
    //
    memcpy(g_InitArgs.wMAC, g_MyAddr.wMAC, sizeof(g_InitArgs.wMAC));

    EdbgOutputDebugString("INFO: Debug Ethernet MAC Address:%B:%B:%B:%B:%B:%B\r\n",
                          g_MyAddr.wMAC[0] & 0x00FF, g_MyAddr.wMAC[0] >> 8,
                          g_MyAddr.wMAC[1] & 0x00FF, g_MyAddr.wMAC[1] >> 8,
                          g_MyAddr.wMAC[2] & 0x00FF, g_MyAddr.wMAC[2] >> 8);

//ZQ add***********************************	
//Because EEPROM is bad, so NIC write MAC address into sdram 0x03EE0000
	*(PUSHORT)0x03EE0000 = g_MyAddr.wMAC[0] & 0xffff;
	*(PUSHORT)0x03EE0004 = g_MyAddr.wMAC[1] & 0xffff;
	*(PUSHORT)0x03EE0008 = g_MyAddr.wMAC[2] & 0xffff;
//***********************************

    return(TRUE);
}


DWORD OEMPreDownload(void)
{
    char szDeviceName[EDBG_MAX_DEV_NAMELEN];
    DWORD dwSubnetMask = 0;
    BOOL fGotJumpImg = FALSE;
    DWORD DHCPLeaseTime = DEFAULT_DHCP_LEASE;
    DWORD dwBootFlags = 0;
    HARP_BOOT_ARGS *pBootArgs = g_InitArgs.pBootArgs;
    DWORD *pDHCPLeaseTime = &DHCPLeaseTime;

   
    memset(szDeviceName, 0, EDBG_MAX_DEV_NAMELEN);

    //
    // Create device name based on Ethernet address.
    //
    CreateDeviceName(&g_MyAddr, szDeviceName, g_InitArgs.szPlatformString);

    EdbgOutputDebugString("INFO: Using device name: '%s'\n", szDeviceName);

    //
    // User select static IP instead of DHCP?
    //
    
    if (!(g_BldrSettings.nFlags & BLDR_SETTINGS_FLAGS_DHCP))
    {
        EdbgOutputDebugString("INFO: Using static IP.\r\n");

      g_MyAddr.dwIP           = g_BldrSettings.nIPAddress;
     dwSubnetMask          = g_BldrSettings.nSubnetMask;
 	
        pBootArgs->EdbgFlags |= EDBG_FLAGS_STATIC_IP;
        // A NULL DHCP lease time pointer tells EbootInitEtherTransport that
        // we're using static IP and don't want to talk to a DHCP server.
        pDHCPLeaseTime        = NULL;
    }

    if( !fGotJumpImg )
    {
    //    apCHARLCD_PrintXY(0, 0, "BootMe" );

        // Initialize the TFTP transport.
        // NOTE: This uses EDBG_CPU_ARM720, but this is really a generic ARM 
        //  flag which works with all ARM processors.
        if (!EbootInitEtherTransport(&g_MyAddr, 
                                     &dwSubnetMask, 
                                     &fGotJumpImg, 
                                     pDHCPLeaseTime, 
                                     EBOOT_VERSION_MAJOR, 
                                     EBOOT_VERSION_MINOR, 
                                     g_InitArgs.szPlatformString, 
                                     szDeviceName, 
                                     EDBG_CPU_ARM720, 
                                     dwBootFlags))
        {
    
            EdbgOutputDebugString("Error returned from EbootInitEtherTransport\r\n");
            return(BL_ERROR);
        }
        pBootArgs->ucLoaderFlags = LDRFL_ADDR_VALID | LDRFL_JUMPIMG;

    }
    // update BOOTARG with the info we got so far
    memcpy(&pBootArgs->EdbgAddr, &g_MyAddr, sizeof(g_MyAddr));
    if (pDHCPLeaseTime)
        pBootArgs->DHCPLeaseTime = *pDHCPLeaseTime; // DHCP
    else
        pBootArgs->DHCPLeaseTime = 0;           // Static IP

    // Are we enabling Kitl?
    if( !(g_BldrSettings.nFlags & BLDR_SETTINGS_FLAGS_NOKITL) )
        pBootArgs->ucLoaderFlags |= LDRFL_USE_EDBG;

    // Kitl in passive mode?        
    if( (g_BldrSettings.nFlags & BLDR_SETTINGS_FLAGS_PSVKITL) )
        pBootArgs->ucLoaderFlags |= LDRFL_KITL_PSV;
EdbgOutputDebugString("INFO: Downloading\n");

    return(fGotJumpImg? BL_JUMP : BL_DOWNLOAD);

}

//////////////////////////////////////////////////////////////////////
// Loader setting storage and retrieval functions
//
static BOOLEAN ReadFlashSettings(PBLDR_SETTINGS pSettings)
{
    if (!pSettings)
        return(FALSE);

    memset(pSettings, 0, sizeof(BLDR_SETTINGS));

    if (CFI_Read_Block((unsigned16*)BLDR_SETTINGS_FLASH_BASE, 
                       (unsigned16*)pSettings, sizeof(BLDR_SETTINGS)) != PASS)
    {
        EdbgOutputDebugString("ERROR: ReadFlashSettings failed.\r\n");
        return(FALSE);
    }

    return(TRUE);
}


static BOOLEAN WriteFlashSettings(PBLDR_SETTINGS pSettings)
{
    UCHAR nCount = 0;
    ULONG nCheckSum = 0;
    BOOLEAN bRet = TRUE;

    if (!pSettings)
        return(FALSE);

    //
    // Compute simple checksum.
    //
    pSettings->nCheckSum = 0;
    for (nCheckSum = 0, nCount = 0 ; nCount < sizeof(BLDR_SETTINGS) ; nCount++)
        nCheckSum += (UCHAR)*(((PUCHAR)pSettings) + nCount);
    pSettings->nCheckSum = nCheckSum;

    //
    // First, erase the flash block.

⌨️ 快捷键说明

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