📄 main.c
字号:
if ((OEMEthGetSecs() - dwNextBootme) >= ARP_RESPONSE_WAIT)
{
EdbgOutputDebugString("No ARP response in %d seconds, assuming ownership of %s\r\n",
ARP_RESPONSE_WAIT, inet_ntoa(MyAddr.dwIP));
dwIPState = IPSTATE_ARPED;
dwNextBootme = 0;
}
break;
case IPSTATE_ARPED:
if (!bLinkEstablished)
{
if (((pEbootCFG->numBootMe == 0) && (OEMEthGetSecs() >= dwNextBootme)) ||
((BootmeCnt < pEbootCFG->numBootMe) && ((BootmeCnt == 0) || (OEMEthGetSecs() >= dwNextBootme))))
{
// Send broadcast BOOTME packet to Eshell. Pass in NULL for device
// name - it will be constructed from our platform name and the last
// word of our MAC address (e.g. Odo23).
EbootSendBootme(&MyAddr, EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR,PLATFORM_STRING,NULL,EDBG_CPUID,0);
BootmeCnt++;
dwNextBootme = OEMEthGetSecs() + BOOTME_INTERVAL;
}
}
break;
case IPSTATE_RETRY:
EbootInitDHCP(&MyAddr);
dwIPState = IPSTATE_NONE;
break;
}
// Get a frame and pass it to the appropriate handler routine
wLen = sizeof(FrameBuffer);
if (OEMEthGetFrame(FrameBuffer, &wLen))
{
// Ethernet frame type is in 7th word of buffer
USHORT wFrameType = *(USHORT *)(FrameBuffer + 6*sizeof(USHORT));
switch (ntohs(wFrameType))
{
case 0x0806:
if (EbootProcessARP(&MyAddr,FrameBuffer) == PROCESS_ARP_RESPONSE)
{
switch (dwIPState)
{
// Someone has responded to our gratuitous ARP request so they have our IP address.
// We need to retry the DHCP request.
case IPSTATE_ARP:
case IPSTATE_GOTIP:
DHCPRetry++;
if (DHCPRetry > MAX_DHCP_RETRY)
{
EdbgOutputDebugString( "Some other station has IP Address: %s !!! Aborting.\r\n", inet_ntoa(MyAddr.dwIP));
goto FatalError;
}
EdbgOutputDebugString( "Some other station has IP Address: %s !!! Retrying.\r\n", inet_ntoa(MyAddr.dwIP));
dwIPState = IPSTATE_RETRY;
break;
}
}
break;
case 0x0800:
if (!EbootCheckUDP(&MyAddr, FrameBuffer, &wDestPort, &wSrcPort, &pwUDPData, &wUDPDataLen))
{
switch (dwIPState)
{
case IPSTATE_NONE:
if ((wDestPort == DHCP_CLIENT_PORT) && (wSrcPort == DHCP_SERVER_PORT))
{
EbootProcessDHCP(
&MyAddr,
&dwSubnetMask,
(BYTE *)pwUDPData,
wUDPDataLen,
&DHCPLeaseTime,
&fGotIP);
if (fGotIP)
{
dwIPState = IPSTATE_GOTIP;
}
}
break;
case IPSTATE_ARPED:
pCfgData = NULL;
if (EbootProcessEDBG(&MyAddr,&EshellHostAddr,FrameBuffer,pwUDPData, wUDPDataLen, &fGotJumpimg, &pCfgData))
{
if (pCfgData)
{
if (pCfgData->Flags & EDBG_FL_DBGMSG)
{
EdbgOutputDebugString("Enabling debug messages over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->DbgMsgIPAddr),ntohs(pCfgData->DbgMsgPort));
memcpy(&pDriverGlobals->eth.DbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pDriverGlobals->eth.DbgHostAddr.dwIP = pCfgData->DbgMsgIPAddr;
pDriverGlobals->eth.DbgHostAddr.wPort = pCfgData->DbgMsgPort;
}
if (pCfgData->Flags & EDBG_FL_PPSH)
{
EdbgOutputDebugString("Enabling CESH over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->PpshIPAddr),ntohs(pCfgData->PpshPort));
memcpy(&pDriverGlobals->eth.PpshHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pDriverGlobals->eth.PpshHostAddr.dwIP = pCfgData->PpshIPAddr;
pDriverGlobals->eth.PpshHostAddr.wPort = pCfgData->PpshPort;
}
if (pCfgData->Flags & EDBG_FL_KDBG)
{
EdbgOutputDebugString("Enabling KDBG over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->KdbgIPAddr),ntohs(pCfgData->KdbgPort));
memcpy(&pDriverGlobals->eth.KdbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pDriverGlobals->eth.KdbgHostAddr.dwIP = pCfgData->KdbgIPAddr;
pDriverGlobals->eth.KdbgHostAddr.wPort = pCfgData->KdbgPort;
}
pDriverGlobals->eth.etherFlags = pCfgData->Flags;
#ifndef _PB30_
pDriverGlobals->eth.KitlTransport = pCfgData->KitlTransport;
#endif
}
}
else
{
// TFTP routine returns non zero as long as a valid link is established. In this case,
// stop sending BOOTMEs.
if (EbootTFtpReceiver( &MyAddr, FrameBuffer, wDestPort, wSrcPort, pwUDPData, wUDPDataLen ))
{
bLinkEstablished = TRUE;
}
}
break;
} // switch (dwIPState)
}
break;
default:
break;
} // switch (wFrameType)
}
}
EdbgOutputDebugString("Network Transfer Complete\r\n" );
if (fileType & NB0_FILE_TYPE)
{
dwPhysLen = v_PacketNum * 512;
dwPhysStart = RAM_IMAGE_START;
EdbgOutputDebugString("Writing 0x%x bytes to Flash from RAM address 0x%x\r\n", dwPhysLen, dwPhysStart);
if (FlashWrite( dwPhysStart, dwPhysLen))
{
EdbgOutputDebugString("Flash programming Error. System halted!\r\n");
while (1);
}
EdbgOutputDebugString("Programming complete. Now reboot the system!\r\n");
while (1);
}
// Verify checksums for NK.BIN files only.
if (VerifyCheckSum() != 0)
{
EdbgOutputDebugString("Checksum failure! System halted!\r\n");
while (1);
}
if (fileType & BIN_FILE_TYPE)
{
// If the NK.BIN image is located to run out of SDRAM, and we want to store this
// image into flash, we'll configure that behavior now.
if ((!(fileType & FLASHTARGET)) && (fileType & NKBIN) && (pEbootCFG->bWriteBINToFlash))
{
fileType |= (SDRAMEXE | FLASHTARGET);
}
// Now program the image into flash if required.
if (fileType & FLASHTARGET)
{
// Check for pTOC signature ("CECE") here, after image in place
if (*(DWORD*)(dwPhysStart + 64) == 0x43454345)
{
EdbgOutputDebugString("Found pTOC signature in downloaded image.\n");
}
else
{
EdbgOutputDebugString("Image not found at 0x%x\r\n",dwPhysStart);
}
EdbgOutputDebugString("Preparing to write 0x%x bytes to flash from RAM address 0x%x\r\n", dwPhysLen, dwPhysStart);
if (FlashWrite( dwPhysStart, dwPhysLen))
{
EdbgOutputDebugString("Flash programming Error. System halted!\r\n");
while (1);
}
if (fileType & BOOTLOADER)
{
EdbgOutputDebugString("Image programming complete. Now reboot the system!\r\n");
// Boot loader image can be launched automatically by calling Launch2(0).
//msWait(2000);
//Launch2(0);
while (1);
}
EdbgOutputDebugString("Calculating CRC-32 ... ");
pEbootCFG->CRC = crc32((unsigned char *)RAM_IMAGE_START, dwPhysLen);
EdbgOutputDebugString("CRC-32 is 0x%x\r\n",pEbootCFG->CRC);
// Store dwLaunchAddr into the config space for later retrieval.
pEbootCFG->dwLaunchAddr = dwLaunchAddr;
// Required for launching images out of SDRAM when stored in flash
#ifdef MMXIP_MEMMAP
if ( (dwLaunchAddr & 0xF0000000) == 0x80000000)
#else
if ( (dwLaunchAddr & 0xF0000000) == 0x90000000)
#endif
{
pEbootCFG->dwPhysStart = dwPhysStart - offset; /// ONLY TRUE FOR FLASH NK.BIN FILES!!!!
}
else
{
pEbootCFG->dwPhysStart = dwPhysStart;
}
pEbootCFG->dwPhysLen = dwPhysLen;
}
}
// Update address info, in driver globals, and in EEPROM if necessary
memcpy(&pDriverGlobals->eth.TargetAddr,&MyAddr,sizeof(MyAddr));
pDriverGlobals->eth.SubnetMask = dwSubnetMask;
// Set address of host running Eshell
memcpy(&pDriverGlobals->eth.DownloadHostAddr,&EshellHostAddr,sizeof(EDBG_ADDR));
pDriverGlobals->eth.DHCPLeaseTime = DHCPLeaseTime;
pDriverGlobals->eth.EdbgFlags = EdbgFlags;
// if we are downloading, find pTOC
if (dwPhysLen > 0)
{
// Check for pTOC signature ("CECE") here, after image in place
if (*(DWORD*)(dwPhysStart - dwOffset + 64) == 0x43454345)
{
EdbgOutputDebugString("Found pTOC signature.\n");
}
else
{
EdbgOutputDebugString("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
EdbgOutputDebugString("! ERROR: Did not find pTOC signature. ABORTING. !\n");
EdbgOutputDebugString("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
// If no signature, we're going to fail anyway, so loop forever
while (1);
}
// Copy RomHdr from image
lpdwToc= (LPDWORD)(*(DWORD*)(dwPhysStart - dwOffset + 68));
memcpy((LPVOID)&RomHdr, (LPVOID)lpdwToc, sizeof(ROMHDR));
EdbgOutputDebugString("ROMHDR at Address 0x%x\r\n",lpdwToc);
EdbgOutputDebugString("RomHdr.ulRAMStart=0x%x RomHdr.physfirst=0x%x.\r\n",RomHdr.ulRAMStart,RomHdr.physfirst);
}
if (RomHdr.physfirst != -1)
{
if (pDriverGlobals->eth.etherFlags & EDBG_FL_CLEANBOOT)
{
//
// Check to see if the bootloader's image overlaps the real image's
// ram section. If so there might be a problem doing the cleanboot.
// Of course that means warm boots are never valid for this image/processor.
//
// RomHdr contains the real image's parameters
// pTOC contains the bootloader's parameters
//
if ((RomHdr.ulRAMStart < pTOC->physlast) && (RomHdr.ulRAMEnd > pTOC->physfirst))
{
//
// We have an overlap
//
EdbgOutputDebugString("WARNING! : Bootloader detected a possible overlap between the bootloader code\r\n");
EdbgOutputDebugString("and the image's RAM section. Ignoring the CLEANBOOT request.\r\n");
EdbgOutputDebugString(" Bootloader image => 0x%x - 0x%x\r\n",pTOC->physfirst,pTOC->physlast);
EdbgOutputDebugString(" NK RAM => 0x%x - 0x%x\r\n",RomHdr.ulRAMStart,RomHdr.ulRAMEnd);
}
else
{
EdbgOutputDebugString( "CLEANBOOT Clearing RAM from 0x%x-0x%x.\r\n",RomHdr.ulRAMStart,RomHdr.ulRAMEnd);
memset((LPVOID)RomHdr.ulRAMStart,0,RomHdr.ulRAMEnd-RomHdr.ulRAMStart);
}
}
}
// Launch the image just downloaded
if (fileType & FLASHTARGET)
{
memcpy(&pEbootCFG->DriverGlobals, (LPVOID)pDriverGlobals, sizeof(DRIVER_GLOBALS));
EdbgOutputDebugString("Storing driver globals to flash ...\r\n");
StoreEBootCFG(pEbootCFG);
EdbgOutputDebugString("Download successful! Jumping to image at 0x%x...\r\n",dwLaunchAddr);
msWait(500); // let the message display before we launch.
if (fileType & SDRAMEXE)
{
Launch(dwLaunchAddr);
}
Launch2(pEbootCFG->dwLaunchAddr-BOOT_FLASH_BASE_C_VIRTUAL);
}
else
{
msWait(500); // let the message display before we launch.
EdbgOutputDebugString("Download successful! Jumping to image at 0x%x...\r\n",dwLaunchAddr);
Launch(dwLaunchAddr);
}
FatalError:
// Some catastrophic error occurred
EdbgOutputDebugString("A fatal error has occured. Eboot has halted.\r\n");
while (1);
}
/* OEMEthGetFrame
*
* Check to see if a frame has been received, and if so copy to buffer. An optimization
* which may be performed in the Ethernet driver is to filter out all received broadcast
* packets except for ARPs. This is done in the NE2000 driver.
*
* Return Value:
* Return TRUE if frame has been received, FALSE if not.
*/
BOOL
OEMEthGetFrame(
BYTE *pData, // OUT - Receives frame data
UINT16 *pwLength) // IN - Length of Rx buffer
// OUT - Number of bytes received
{
return pfnEDbgGetFrame(pData, pwLength);
}
/* OEMEthSendFrame
*
* Send Ethernet frame.
*
* Return Value:
* TRUE if frame successfully sent, FALSE otherwise.
*/
BOOL
OEMEthSendFrame(
BYTE *pData, // IN - Data buffer
DWORD dwLength) // IN - Length of buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -