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 + -
显示快捷键?