main.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 385 行

C
385
字号
//------------------------------------------------------------------------------
//
//  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 <blcommon.h>
#include <halether.h>
#include <ceddk.h>
#include <ethdbg.h>
#include <nkintr.h>
#include <armintboot.h>
#include <sizes.h>
#include <platform.h>

#include "eboot.h"

#define BOOTARGS_BASE_ADDR	0x8000
#define DEFAULT_JUMP_ADDR       0x88901000

extern int GetPC(void);

// Can be used to turn on debug zones in eboot.lib and smc9000.lib functions
DWORD EdbgDebugZone;

//
static ETH_HARDWARE_INIT_ARGS InitArgs;
static EDBG_ADDR MyAddr;

extern unsigned int PciMemBase;
extern unsigned int PciCfgBase;
extern unsigned int PciV3Base;
extern unsigned int PciIOBase;

extern ROMHDR * volatile const pTOC;

typedef VOID (*PFN_LAUNCH)(VOID);

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

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 <= FLASH_BASE) || (pc >= 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 = 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 *)FLASH_BASE, len);

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


///////////////////////////////////////////////////////////////////
// Flash Routines
//
BOOL OEMWriteFlash(DWORD dwImageStart, DWORD dwImageLength)
{
    return(FALSE);
}

BOOL OEMFinishEraseFlash(void)
{
    return(FALSE);
}

void OEMContinueEraseFlash(void)
{
    return;
}

BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
{
    return(FALSE);
}

BOOL OEMIsFlashAddr (DWORD dwAddr)
{
    return(FALSE);
}
//
///////////////////////////////////////////////////////////////////



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


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

    // wait for the jump command from eshell unless user specify jump directly
    EdbgOutputDebugString("INFO: Download successful! Jumping to image at %Xh...\r\n", dwLaunchAddr);
    if (!(pCfgData = EbootWaitForHostConnect(&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 we have been configured by the host to clear RAM, do so now.  
    // The RAM addresses are hard coded and must match those in the 
    // config.bib file for the image.  Note that the stack and the driver 
    // globals memory are not in this range, and this will not hang if we 
    // run off the end of the memory actually present.
    //
    if (pRomHdr && (pBootArgs->ucEshellFlags & EDBG_FL_CLEANBOOT))
    {
        RETAILMSG(1, (TEXT("INFO: Clean boot requested, wiping memory from 0x%x to 0x%x\r\n"), pRomHdr->ulRAMFree, pRomHdr->ulRAMEnd));
        memset((ULONG *)pRomHdr->ulRAMFree, 0, pRomHdr->ulRAMEnd - pRomHdr->ulRAMFree);
    }
  
    // If no jump address is specified, choose the default.
    // 
    if (!dwLaunchAddr)
    {
        dwLaunchAddr = DEFAULT_JUMP_ADDR;

        RETAILMSG(1, (TEXT("INFO: No launch address specified - using default (0x%x).\r\n"), dwLaunchAddr));
    }


    ((PFN_LAUNCH)(dwLaunchAddr))();

    // Should never be reached...
    SpinForever();
}

void OEMShowProgress(DWORD dwPacketNum)
{
    return;
}


LPBYTE OEMMapMemAddr (DWORD dwImageStart, DWORD dwAddr)
{
    return((LPBYTE) dwAddr);
}

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;

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

    //
    // OEM initializes hardware and returns boot information.
    //
    PciMemBase = PHYS_PCI_MEM_BASE;
    PciCfgBase = PHYS_PCI_CONFIG_BASE;
    PciIOBase  = PHYS_PCI_IO_BASE;
    PciV3Base  = PHYS_PCI_V3_BASE;

    //
    // Set up PCI.
    //
    if (!PCI_InitHierarchy())
    {
        EdbgOutputDebugString("ERROR: Cannot set up PCI.\r\n");
        return(FALSE);
    } 

    fRet = OEMEthHardwareInit(&InitArgs, &MyAddr);

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

    pBootArgs = 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  = 0x10000;
    pBootArgs->dwLen            = sizeof(HARP_BOOT_ARGS);

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

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

    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 = InitArgs.pBootArgs;


    memset(szDeviceName, 0, EDBG_MAX_DEV_NAMELEN);

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

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

    //
    // Save the Ethernet address in boot args area.
    //
    memcpy(&(pBootArgs->EdbgAddr), &MyAddr, sizeof(MyAddr));


    // Static IP/subnet and DHCP lease value here...
    //
#if 0 
    DWORD dwStartTime;
    dwStartTime = OEMEthGetSecs();
    EdbgOutputDebugString("You have 10 seconds to prove that you exist "
                          "(via net or serial input)...\r\n" );
    EdbgOutputDebugString("Wait for DHCP, enter new IP address, or "
                          "CR to use existing IP: ");
if (EbootReadSerialIP(&MyAddr, &dwSubnetMask))
{
    pBootArgs->EdbgFlags |= EDBG_FLAGS_STATIC_IP;
    DHCPLeaseTime = DEFAULT_DHCP_LEASE;
}
#endif

    // Initialize the TFTP transport.
    if (!EbootInitEtherTransport(&MyAddr, 
                                 &dwSubnetMask, 
                                 &fGotJumpImg, 
                                 &DHCPLeaseTime, 
                                 EBOOT_VERSION_MAJOR, 
                                 EBOOT_VERSION_MINOR, 
                                 InitArgs.szPlatformString, 
                                 szDeviceName, 
                                 EDBG_CPU_ARM720, 
                                 dwBootFlags))
    {
        return(BL_ERROR);
    }

    // update BOOTARG with the info we got so far
    memcpy(&pBootArgs->EdbgAddr, &MyAddr, sizeof(MyAddr));
    pBootArgs->ucLoaderFlags = LDRFL_USE_EDBG | LDRFL_ADDR_VALID | LDRFL_JUMPIMG
;
    pBootArgs->DHCPLeaseTime = DHCPLeaseTime;

    return(fGotJumpImg? BL_JUMP : BL_DOWNLOAD);

}

/* EOF main.c */

⌨️ 快捷键说明

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