⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c.bak

📁 这个是嵌入式arm系列的一个bootloader程序。对需要编写bootloader的很有参考价值
💻 BAK
📖 第 1 页 / 共 4 页
字号:
                {
                    // 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;
                }
            }
        #endif
			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;
                                    pDriverGlobals->eth.KitlTransport = pCfgData->KitlTransport;
                                }
                            }
                            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" );

FLASHIMAGE:
#ifndef SABINAL
    //
    // No Flash writing for Sabinal
    //
#if defined ( RTECH_FLAG )
	if ((fileType & NB0_FILE_TYPE))
	{
		if(bEbootExternalDown && (MonitorFlag == 2))
			dwPhysLen = EBootImageLen;
		else
			dwPhysLen = v_PacketNum * 512;
			
		dwFlashCache = RAM_IMAGE_START;
		dwFlashStart = (DWORD)(FLASH_START + dwEBOOT_OFFSET);
		EdbgOutputDebugString("Writing 0x%x bytes to Flash from RAM address 0x%x\r\n", dwPhysLen, dwPhysStart);
		
		if ((fileType & BOOTLOADER ) && (!bEbootExternalDown))
		{
			EdbgOutputDebugString("Image Address conflict with Bootloader location or operation not allowable.\r\n");
			goto FatalError;
		}
				
		if (FlashWrite( dwFlashStart, dwFlashCache, dwPhysLen))
		{
			EdbgOutputDebugString("Flash programming Error.  System halted!\r\n");
			while(1);
		}
		if (bEbootExternalDown)
		{
			EdbgOutputDebugString("BootLoader Programming complete.\r\n");
			goto LaunchMonitor;
		}
		EdbgOutputDebugString("Programming complete.  Now reboot the system!\r\n");
		while(1);
	}
#else
	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);
	}
#endif
#endif

	// Verify checksums for NK.BIN files only.
	VerifyCheckSum();

LaunchAtaImage:
#ifndef SABINAL
    //
    // No Flash writing for Sabinal
    //


	if (fileType & BIN_FILE_TYPE)
	{

		// 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 defined ( RTECH_FLAG )
			if ((fileType & BOOTLOADER ) && (!bEbootExternalDown))
			{
				EdbgOutputDebugString("Image Address conflict with Bootloader location or operation is not allowable.\r\n");
				goto FatalError;
			}
			if (bEbootExternalDown && (dwLaunchAddr != (EBOOT_IMAGE_START + 0x1000)))
			{
				EdbgOutputDebugString("Not Bootloader Image!\r\n");
				while(1);			
			}
			dwFlashCache = dwPhysStart;
			dwFlashStart = (DWORD)(FLASH_START + dwEBOOT_OFFSET);
			if (FlashWrite( dwFlashStart, dwFlashCache, dwPhysLen))
			{
				EdbgOutputDebugString("Flash programming Error.  System halted!\r\n");
				while(1);
			}			
#else

			if (FlashWrite( dwPhysStart, dwPhysLen))
			{
				EdbgOutputDebugString("Flash programming Error.  System halted!\r\n");
				while(1);
			}
#endif

			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);
			}

			// Store dwLaunchAddr into the config space for later retrieval.  
			EdbgOutputDebugString("Storing image launch address to flash...\r\n");
			pEbootCFG->dwLaunchAddr = dwLaunchAddr;
			StoreEBootCFG(pEbootCFG);

			// Check for pTOC signature ("CECE") here, after image in place
			if (*(DWORD*)((pEbootCFG->dwLaunchAddr - 0x1000) + 64) == 0x43454345)
			{
				EdbgOutputDebugString("Found pTOC signature.\n");
			} else
			{
				EdbgOutputDebugString("Image not found at 0x%X\r\n",pEbootCFG->dwLaunchAddr);
				EdbgOutputDebugString("System halted!\r\n");
				while(1);
			}
		}
	}

#endif

    EdbgOutputDebugString("Download successful! Jumping to image at %Xh...\r\n",dwLaunchAddr);

    // 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 %Xh\r\n",lpdwToc);
		EdbgOutputDebugString("RomHdr.ulRAMStart=%Xh RomHdr.physfirst=%Xh.\r\n",RomHdr.ulRAMStart,RomHdr.physfirst);

		VerifyCheckSum();
	}

	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 %Xh-%Xh.\r\n",RomHdr.ulRAMStart,RomHdr.ulRAMEnd);
                memset((LPVOID)RomHdr.ulRAMStart,0,RomHdr.ulRAMEnd-RomHdr.ulRAMStart);
            }
		}
	}
	
	EdbgOutputDebugString("pDriverGlobals->eth.EdbgFlags( 0x%X : 0x%X)...\r\n", &pDriverGlobals->eth.EbootDevice, pDriverGlobals->eth.EbootDevice );
	EdbgOutputDebugString("Download successful! Jumping to image at %Xh...\r\n",dwLaunchAddr);
	msWait(500); // let the message display before we launch.

	// Launch the image just downloaded
	if (fileType & FLASHTARGET)
	{
		Launch2(pEbootCFG->dwLaunchAddr-BOOT_FLASH_BASE_C_VIRTUAL);
	} else
	{
		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
{
    int retries = 0;

    // Let's be persistant here
    while (retries++ < 4) 
    {
        if (!pfnEDbgSendFrame(pData, dwLength))
                return TRUE;
        EdbgOutputDebugString("!OEMEthSendFrame failure, retry %u\n",retries);
    }
    return FALSE;
}

/* OEMEthGetSecs
 *
 *  Return a count of seconds from some arbitrary time (the absolute value is not important,
 *  so long as it increments appropriately).
 */
DWORD OEMEthGetSecs(  ) {

    SYSTEMTIME st;
    OEMGetRealTime( &st );
    
    return ((60UL * (60UL * (24UL * (31UL * st.wMonth + st.wDay) + st.wHour) + st.wMinute)) + st.wSecond);
}


VOID SC_WriteDebugLED(WORD wIndex, DWORD dwPattern) 
{
    OEMWriteDebugLED(wIndex,dwPattern);
}

⌨️ 快捷键说明

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