📄 main.c
字号:
/*
* 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 + -