main.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 876 行 · 第 1/3 页

C
876
字号
/*++
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.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.

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:


Notes: 

--*/

#include <windows.h>
#include <ethdbg.h>
#include <nkintr.h>
#include <halether.h>
#include <bootarg.h>

#include "eboot.h"
#include "ethdown.h"
#include <pc.h>
#include <pci.h>
#include <ceddk.h>
#include <pehdr.h>
#include <romldr.h>
#include <rtl8139.h>


#define BOOT_ARG_PTR_LOCATION_NP    0x001FFFFC
#define BOOT_ARG_LOCATION_NP        0x001FFF00

//
// Function pointers to the support library functions of the currently installed debug ethernet controller.
//
PFN_EDBG_INIT             pfnEDbgInit;
PFN_EDBG_ENABLE_INTS      pfnEDbgEnableInts;
PFN_EDBG_DISABLE_INTS     pfnEDbgDisableInts;
PFN_EDBG_GET_PENDING_INTS pfnEDbgGetPendingInts;
PFN_EDBG_GET_FRAME        pfnEDbgGetFrame;
PFN_EDBG_SEND_FRAME       pfnEDbgSendFrame;
PFN_EDBG_READ_EEPROM      pfnEDbgReadEEPROM;
PFN_EDBG_WRITE_EEPROM     pfnEDbgWriteEEPROM;


#define pDriverGlobals ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)

// Constants that control operation of bootloader. All times in seconds
#define BOOTME_INTERVAL    3    // Interval between BOOTMEs
#define MAX_BOOTME_CNT     10   // Max number of BOOTMEs sent

// Well known DHCP ports for use with UDP
#define DHCP_SERVER_PORT 0x4300
#define DHCP_CLIENT_PORT 0x4400

static BYTE FrameBuffer[ETHER_MTU];

extern DWORD dwLaunchAddr;

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

typedef volatile unsigned int *VPDWORD;

ROMHDR * const pTOC = (ROMHDR *)-1;     // Gets replaced by RomLoader with real address
void KernelRelocate(void);
BOOL InitNetCard();
BOOL PrintPCIConfig();
DWORD FindPCINetCard(BYTE bIRQ);

typedef volatile unsigned int *VPDWORD;
#if 0
unsigned int ulRamBufStart;             // starting address of available RAM
unsigned int ulRamBufEnd;               // ending address of available RAM
#endif

unsigned int vAddr;

typedef struct vendorid {
    DWORD dwUpperMAC; // first 3 bytes of ethernet address
    char  *szAbbrev;
} VENDORID;

static const VENDORID VendorIds[] = {
    {0x00006E, "AE" }, // Artisoft
    {0x000094, "AS" }, // ASANTE
    {0x0000E8, "AC" }, // Accton Technology
    {0x004005, "LS" }, // LinkSys
    {0x004033, "AD" }, // Addtron Technology
    {0x004092, "ASP"}, // ASP Computer Products
    {0x00800F, "SMC"}, // SMC
    {0x008048, "CPX"}, // Compex
    {0x0080AD, "CN" }, // CNET Technologies
    {0x0080C8, "DL" }, // D-Link
    {0x00A0D2, "AT" }, // Allied TeleSyn
    {0x00C00D, "ALR"}, // Advanced Logic Research
    {0x00C06D, "BR" }, // Boca Research
    {0x00C0DF, "GE" }, // Kye International GENIUS GE2000 series
    {0x00C0F0, "KS" }, // Kingston
    {0x4854E8, "WB" }  // WinBond Electronics Corp
};

#define NUM_VENDORIDS (sizeof(VendorIds)/sizeof(VENDORID))

#define PLATFORM_STRING "CEPC"




typedef void (*PFN_LAUNCH)();



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SpinForever(void)
{
    EdbgOutputDebugString("SpinForever...\r\n");
    while(1);
}



//------------------------------------------------------------------------------
//
// Relocate the kernel
//
//------------------------------------------------------------------------------
void KernelRelocate(void){
    unsigned int loop;
    COPYentry *cptr;
    DWORD dwCopyOffset;

    if (pTOC == (ROMHDR *)-1) {
        OEMWriteDebugByte('!');
        SpinForever();
    }
    
    for (loop = 0; (unsigned)loop < (unsigned)pTOC->ulCopyEntries; loop++) {
        cptr = (COPYentry *)(pTOC->ulCopyOffset + loop*sizeof(COPYentry));
        dwCopyOffset = pTOC->ulCopyOffset;

        if (cptr->ulCopyLen) {
            memcpy((void *)cptr->ulDest, (void *)cptr->ulSource, cptr->ulCopyLen);
        }
        if (cptr->ulCopyLen != cptr->ulDestLen) {
            memset((void *)(cptr->ulDest + cptr->ulCopyLen), 0, cptr->ulDestLen - cptr->ulCopyLen);
        }
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static void
itoa10(
    int i,
    char * a
    )
{
    char * p = a;
    int c = 0;
    int n = i;
    char swap;

    //
    // Build the ascii string in reverse digit order
    //
    while (n) {
        *p = (char)(n % 10) + '0';
        n /= 10;
        p++;
        c++;
    }
    *p = 0;
    c--;

    //
    // Reverse the string in place to correct order
    //
    for (n = 0; n < c; n++, c--) {
        swap = a[n];
        a[n] = a[c];
        a[c] = swap;
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static DWORD
UpperDWFromMAC(EDBG_ADDR * pAddr)
{
    DWORD ret;

    //
    // The WORDs in wMAC field are in net order, so we need to do some
    // serious shifting around.
    // A hex ethernet address of 12 34 56 78 9a bc is stored in wMAC array as
    // wMAC[0] = 3412, wMAC[1] = 7856, wMAC[2] = bc9a.
    // The 4 byte return value should look like 0x00123456
    //
    ret = (pAddr->wMAC[0] & 0x00ff) << 16;
    ret |= pAddr->wMAC[0] & 0xff00;
    ret |= pAddr->wMAC[1] & 0x00ff;
    return ret;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static void
CreateDeviceName(EDBG_ADDR *pMyAddr, char *szBuf)
{
    int i;
    DWORD dwUpperMAC = UpperDWFromMAC(pMyAddr);

    strcpy(szBuf,PLATFORM_STRING);
    szBuf += strlen(szBuf);

    for (i=0;i<NUM_VENDORIDS;i++) {
        if (dwUpperMAC == VendorIds[i].dwUpperMAC) {
            strcat(szBuf,VendorIds[i].szAbbrev);
            szBuf += strlen(szBuf);
            break;
        }
    }
    itoa10(((pMyAddr->wMAC[2]>>8) | ((pMyAddr->wMAC[2] & 0x00ff) << 8)), szBuf);
}


#define IPSTATE_NONE    0
#define IPSTATE_GOTIP   1
#define IPSTATE_ARP     2
#define IPSTATE_ARPED   3
#define IPSTATE_RETRY   4

#define MAX_DHCP_RETRY  3

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
EbootMain(void)
{
    BOOT_ARGS *pBootArgs;
    EDBG_ADDR MyAddr;
    DWORD dwSubnetMask;
    DWORD dwStartTime;
    BOOL  fGotJumpimg, fGotIP, fDownloading;
    DWORD dwIPState = IPSTATE_NONE;
    EDBG_ADDR EshellHostAddr;
    EDBG_OS_CONFIG_DATA *pCfgData;    
    DWORD dwNextBootme;   // Time of next bootme
    UCHAR BootmeCnt;      // # of bootmes sent so far
    char szDeviceName[EDBG_MAX_DEV_NAMELEN];
    DWORD DHCPLeaseTime;
    DWORD EdbgFlags = 0;
    int DHCPRetry=0;
    DWORD dwBootFlags = 0;

    //
    // Initialize the monitor port (for development system)
    // This should be done first since otherwise we can not
    // print any message onto the monitor
    //
    OEMInitDebugSerial();

    // move writeable data to RAM
    KernelRelocate();
    
    EdbgOutputDebugString("Microsoft Windows CE Ethernet Bootloader %d.%d for CE/PC (%s)\n",

⌨️ 快捷键说明

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