www.pudn.com > iMx31_WCE600.rar > eboot.c
// // Copyright (c) Microsoft Corporation. All rights reserved. // // // Use of this source code is subject to the terms of the Microsoft end-user // license agreement (EULA) under which you licensed this SOFTWARE PRODUCT. // If you did not accept the terms of the EULA, you are not authorized to use // this source code. For a copy of the EULA, please see the LICENSE.RTF on your // install media. // //------------------------------------------------------------------------------ // // Copyright (C) 2004-2006, 2007 Freescale Semiconductor, Inc. All Rights Reserved. // THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS // AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT // //------------------------------------------------------------------------------ // // File: eboot.c // // Core routines for the Ethernet bootloader. // //----------------------------------------------------------------------------- #include "bsp.h" #include#pragma warning(push) #pragma warning(disable: 4115) #include #pragma warning(pop) #include "loader.h" //----------------------------------------------------------------------------- // External Functions //----------------------------------------------------------------------------- // External Variables extern BOOL g_DownloadImage; extern BOOT_CFG g_BootCFG; extern BOOT_BINDIO_CONTEXT g_BinDIO; extern BSP_ARGS *g_pBSPArgs; extern PFN_EDBG_INIT pfnEDbgInit; extern PFN_EDBG_GET_FRAME pfnEDbgGetFrame; extern PFN_EDBG_SEND_FRAME pfnEDbgSendFrame; extern PFN_EDBG_ENABLE_INTS pfnEDbgEnableInts; extern PFN_EDBG_DISABLE_INTS pfnEDbgDisableInts; extern PFN_EDBG_GET_PENDING_INTS pfnEDbgGetPendingInts; extern PFN_EDBG_READ_EEPROM pfnEDbgReadEEPROM; extern PFN_EDBG_WRITE_EEPROM pfnEDbgWriteEEPROM; extern PFN_EDBG_SET_OPTIONS pfnEDbgSetOptions; //----------------------------------------------------------------------------- // Defines //----------------------------------------------------------------------------- // Types //----------------------------------------------------------------------------- // Global Variables DWORD EdbgDebugZone; EDBG_ADDR g_DeviceAddr; // NOTE: global used so it remains in scope throughout download process // since eboot library code keeps a global pointer to the variable provided. INT32 EthDevice = -1; // To determine if Ethernet has been initailized for download/KITL usage //----------------------------------------------------------------------------- // Local Variables //------------------------------------------------------------------------------ // Local Functions // void ResetDefaultBootCFG(BOOT_CFG *pBootCFG); //------------------------------------------------------------------------------ // // Function: OEMBootInit // // Parameters: // None. // // Returns: // TRUE indicates success. FALSE indicates failure. //------------------------------------------------------------------------------ void OEMBootInit (void) { KITLOutputDebugString("Microsoft Windows CE Ethernet Bootloader %d.%d for MX32 ADS (%s %s)\r\n", EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, __DATE__, __TIME__); return; } //------------------------------------------------------------------------------ // // Function: OEMGetMagicNumber // // Parameters: // None. // // Returns: // Magic number of EBOOT version. //------------------------------------------------------------------------------ UINT32 OEMGetMagicNumber() { return EBOOT_CFG_MAGIC_NUMBER; } //------------------------------------------------------------------------------ // // Function: GetPreDownloadInfo // // Parameters: // None. // // Returns: // TRUE for Download/FALSE for jump to resident OS image //------------------------------------------------------------------------------ BOOL GetPreDownloadInfo (PBOOT_CFG p_bootCfg) { BOOL fGotJumpImg = FALSE; UINT32 DHCPLeaseTime = 0; UINT32 *pDHCPLeaseTime = &DHCPLeaseTime; UINT32 SubnetMask; UINT32 BootFlags = 0; // Check if the user wants to use DHCP // if (p_bootCfg->DHCPEnable == FALSE) { pDHCPLeaseTime = NULL; g_pBSPArgs->kitl.ipAddress = p_bootCfg->IP; g_pBSPArgs->kitl.ipMask = p_bootCfg->subnetMask; g_pBSPArgs->kitl.flags &= ~OAL_KITL_FLAGS_DHCP; } // Initialize Ethernet transport if we are in active KITL mode or we // need to download the image if (g_DownloadImage) { // Initialize the TFTP transport. memcpy(g_DeviceAddr.wMAC, g_pBSPArgs->kitl.mac, (sizeof(UINT16) * 3)); g_DeviceAddr.dwIP = g_pBSPArgs->kitl.ipAddress; g_DeviceAddr.wPort = 0; SubnetMask = g_pBSPArgs->kitl.ipMask; if (!EbootInitEtherTransport(&g_DeviceAddr, (LPDWORD)&SubnetMask, &fGotJumpImg, (DWORD *)pDHCPLeaseTime, EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, BSP_DEVICE_PREFIX, (CHAR *)g_pBSPArgs->deviceId, EDBG_CPU_ARM720, BootFlags)) { return(FALSE); } // If the user wanted a DHCP address, save the values obtained in the init call above. // if (p_bootCfg->DHCPEnable == TRUE) { g_pBSPArgs->kitl.ipAddress = g_DeviceAddr.dwIP; g_pBSPArgs->kitl.ipMask = SubnetMask; g_pBSPArgs->kitl.flags |= OAL_KITL_FLAGS_DHCP; } } return(fGotJumpImg); } //------------------------------------------------------------------------------ // // Function: GetLaunchInfo // // Parameters: // None. // // Returns: // None. //------------------------------------------------------------------------------ void GetLaunchInfo (void) { EDBG_OS_CONFIG_DATA *pCfgData; EDBG_ADDR EshellHostAddr; memset(&EshellHostAddr, 0, sizeof(EDBG_ADDR)); KITLOutputDebugString("INFO: EbootWaitForHostConnect (IP = %s, MAC = %x-%x-%x-%x-%x-%x, Port = 0x%x)\r\n", inet_ntoa(g_DeviceAddr.dwIP), g_DeviceAddr.wMAC[0] & 0x00FF, g_DeviceAddr.wMAC[0] >> 8, g_DeviceAddr.wMAC[1] & 0x00FF, g_DeviceAddr.wMAC[1] >> 8, g_DeviceAddr.wMAC[2] & 0x00FF, g_DeviceAddr.wMAC[2] >> 8, g_DeviceAddr.wPort); #if 0 // Remove-W4: Warning C4706 workaround if (!(pCfgData = EbootWaitForHostConnect(&g_DeviceAddr, &EshellHostAddr))) #else if ((pCfgData = EbootWaitForHostConnect(&g_DeviceAddr, &EshellHostAddr)) == 0) #endif { KITLOutputDebugString("ERROR: EbootWaitForHostConnect failed!\r\n"); SpinForever(); } // If the user selected "passive" KITL (i.e., don't connect to the target at boot time), set the // flag in the args structure so the OS image can honor it when it boots. // if (pCfgData && (pCfgData->KitlTransport & KTS_SERIAL)) { g_pBSPArgs->kitl.devLoc.PhysicalLoc = (PVOID)BSP_BASE_REG_PA_SERIALKITL;; } else if ( (pCfgData && (pCfgData->KitlTransport & KTS_ETHER)) && (EthDevice == -1) ) { EthDevice = InitSpecifiedEthDevice(&g_pBSPArgs->kitl, ETH_DEVICE_CS8900A); if (EthDevice == -1) { // No device was found ... // KITLOutputDebugString("ERROR: Failed to detect and initialize Ethernet controller.\r\n"); return; } } if (pCfgData && (pCfgData->KitlTransport & KTS_PASSIVE_MODE)) { g_pBSPArgs->kitl.flags = OAL_KITL_FLAGS_PASSIVE; } return; } //----------------------------------------------------------------------------- // // Function: OEMReadData // // This function reads data from the transport during the download process. // It is called by the BLCOMMON framework. // // Parameters: // cbData // [in] Amount of data, in bytes, to read. // // pbData // [out] Pointer to read buffer. // // Returns: // TRUE for success/FALSE for failure. // //----------------------------------------------------------------------------- BOOL OEMReadData(DWORD cbData, LPBYTE pbData) { BOOL bRet = TRUE; // TODO: increment bytes read to track download progress. // Save read data size and location. It is used in workaround // for download BIN DIO images larger than RAM. g_BinDIO.readSize = cbData; g_BinDIO.pReadBuffer = pbData; bRet = EbootEtherReadData(cbData, pbData); return bRet; } //------------------------------------------------------------------------------ // // Function: ResetDefaultBootCFG // // Resets the debug bootloader configuration information (menu settings, etc.). // // Parameters: // BootCfg // [out] Points to bootloader configuration that will be filled with // default data. // // Returns: // TRUE indicates success. FALSE indicates failure. // //----------------------------------------------------------------------------- void ResetDefaultBootCFG(BOOT_CFG *pBootCFG) { #ifdef DEBUG // Remove-W4: Warning C4189 workaround BOOT_CFG BootCfg = {0}; #endif KITLOutputDebugString("\r\nResetting factory default configuration...\r\n"); pBootCFG->autoDownloadImage = BOOT_CFG_AUTODOWNLOAD_NONE; pBootCFG->dwLaunchAddr = (DWORD)OALPAtoCA(IMAGE_BOOT_NKIMAGE_RAM_PA_START); pBootCFG->dwPhysStart = 0; pBootCFG->dwPhysLen = 0; pBootCFG->mac[0] = 0x0000; pBootCFG->mac[1] = 0x0000; pBootCFG->mac[2] = 0x0000; pBootCFG->ConfigMagicNumber = EBOOT_CFG_MAGIC_NUMBER; pBootCFG->numBootMe = 50; pBootCFG->delay = 3; pBootCFG->IP = inet_addr("0.0.0.0"); pBootCFG->subnetMask = inet_addr("0.0.0.0"); pBootCFG->DHCPEnable = TRUE; // save it back to flash if (!FlashStoreBootCFG((BYTE*) pBootCFG, sizeof(BOOT_CFG))) { KITLOutputDebugString("ERROR: ResetDefaultBootCFG: failed to store configuration to flash.\r\n"); } #ifdef DEBUG else { KITLOutputDebugString("INFO: ResetDefaultBootCFG: factory default configuration saved to flash.\r\n"); // DEBUG // read it back to verify if (!FlashLoadBootCFG((BYTE*) &BootCfg, sizeof(BOOT_CFG))) { KITLOutputDebugString("WARNING: ResetDefaultBootCFG: failed to load configuration for double check.\r\n"); } else { if (0 != memcmp((const void *)&BootCfg, (const void*)pBootCFG, sizeof(BOOT_CFG))) { KITLOutputDebugString("WARNING: ResetDefaultBootCFG: saved and retrieved data not equal.\r\n"); } else { KITLOutputDebugString("INFO: ResetDefaultBootCFG: factory default configuration verified in flash.\r\n"); } } // END DEBUG } #endif } //----------------------------------------------------------------------------- // // Function: OEMEthGetFrame // // Reads data from the Ethernet device. // // Parameters: // pData // [out] Ptr to the receive buffer. // // pwLength // [in] Length of data in the receiving buffer. // // Returns: // FALSE if no frame has been received // //----------------------------------------------------------------------------- BOOL OEMEthGetFrame(PUCHAR pData, PUSHORT pwLength) { return(pfnEDbgGetFrame(pData, pwLength)); } //----------------------------------------------------------------------------- // // Function: OEMEthGetFrame // // Function checks if a frame has been received, and if so copy it to buffer. // // Parameters: // pData // [in] Ptr to the send buffer. // // pwLength // [in] Length of data to be sent. // // Returns: // FALSE on failure // //----------------------------------------------------------------------------- BOOL OEMEthSendFrame(PUCHAR pData, DWORD dwLength) { BYTE Retries = 0; while (Retries++ < 4) { if (!pfnEDbgSendFrame(pData, dwLength)) return(TRUE); KITLOutputDebugString("INFO: OEMEthSendFrame: retrying send (%u)\r\n", Retries); } return(FALSE); }