Implementing the OEMLaunch Function (Windows CE 5.0)
The OEMLaunch function collects post-download connection information from Platform Builder and jumps to the newly downloaded boot loader image.
The following list shows the tasks that the OEMLaunch function needs to perform:
- Wait for Platform Builder to send information about what services to start and from which ports to start the services. OEMLaunch can use the EbootWaitForHostConnect function, which is defined in Eboot.lib. You can copy the implementation of EbootWaitForHostConnect from an existing hardware platform.
- Check the arguments returned from EbootWaitForHostConnect and then save the port or IP information in the DriverGlobals parameter, which the OAL uses later.
- Jump to the first instruction specified by the dwLaunchAddr parameter, which is the boot loader image StartUp function.
After implementing OEMLaunch, the boot loader is essentially complete.
For more information about the Eboot.lib support library, see Eboot Code Library.
To implement the OEMLaunch function
Edit the file Main.c by adding the code necessary to fully implement the OEMLaunch function.
The following code example shows the implementation of the OEMLaunch function for the hardware platform used in this boot loader example.
void OEMLaunch(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr) { DWORD dwPhysLaunchAddr; EDBG_OS_CONFIG_DATA *pCfgData; EDBG_ADDR EshellHostAddr; EBOOT_CFG EbootCfg; memset(&EshellHostAddr, 0, sizeof(EDBG_ADDR)); memset(&EbootCfg, 0, sizeof(EBOOT_CFG)); // Get Eboot configuration settings from flash. // ReadEbootConfig(&EbootCfg); // Wait for Platform Builder to connect after the download and send IP and port settings for service // connections, as well as KITL flags. This information is used later by the OS (KITL). // if (g_bWaitForConnect) { if (!(pCfgData = EbootWaitForHostConnect(&pDriverGlobals->eth.TargetAddr, &EshellHostAddr))) { EdbgOutputDebugString("ERROR: OEMLaunch: EbootWaitForHostConenct failed.\r\n"); SpinForever(); } // Update service information. if (pCfgData->Flags & EDBG_FL_DBGMSG) { EdbgOutputDebugString("INFO: Enabling debug messages over Ethernet (IP:%s port:%u)\r\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("INFO: Enabling Target Control over Ethernet (IP: %s port:%u)\r\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("INFO: Enabling KDBG over Ethernet (IP: %s port:%u)\r\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; } memcpy(&pDriverGlobals->eth.DownloadHostAddr, &EshellHostAddr, sizeof(EDBG_ADDR)); pDriverGlobals->eth.etherFlags = pCfgData->Flags; pDriverGlobals->eth.KitlTransport = pCfgData->KitlTransport; } // Remember kernel launch address or recall stored address if this download did not provide one (that is, the kernel region was not downloaded). // if (dwLaunchAddr && (EbootCfg.NKRegion.LaunchAddress != dwLaunchAddr)) { EbootCfg.NKRegion.LaunchAddress = dwLaunchAddr; WriteEbootConfig(&EbootCfg); } else { dwLaunchAddr= EbootCfg.NKRegion.LaunchAddress; } // Jump to downloaded image (physical address). Launch(dwPhysLaunchAddr); // Should never return. // SpinForever(); }
See Also
Send Feedback on this topic to the authors