Implementing the OEMPreDownload Function (Windows Embedded CE 6.0)
1/5/2010
You need to implement the OEMPreDownload function to initialize the TFTP transport or Platform Builder download protocol on your development workstation. You can also implement OEMPreDownload to optionally obtain an IP address through DHCP; otherwise, you need a static address.
The following list shows the tasks that the OEMPreDownload function needs to perform:
- Generate a unique hardware platform name to be used by Platform Builder for downloads. The hardware platform name is typically a static text name combined with a derived NIC MAC address value.
- Obtain an IP address from a DHCP server or assign a static IP address.
- Initialize the TFTP transport or Platform Builder download protocol. You can do this by calling the EbootInitEtherTransport function defined in Eboot.lib; therefore, ensure that you include Eboot.lib in your boot loader sources file.
- If the address is obtained from a DHCP server, EbootInitEtherTransport returns the address and lease time information, which should be stored in the boot arguments, boot args.
- EbootInitEtherTransport also returns information from Platform Builder user settings such as whether to start a download process or jump to an existing boot loader image on the target. Depending on the value of the bGotJump parameter, either BL_JUMP or BL_DOWNLOAD is returned from the OEMPreDownload function.
For more information about the Eboot.lib support library, see Eboot Code Library.
To implement the OEMPreDownload function
Edit the file Main.c by adding the code necessary to fully implement the OEMPreDownload function.
The following code example shows the implementation of the OEMPreDownload function for the hardware platform used in this boot loader example.
DWORD OEMPreDownload(void) { CHAR szDeviceName[EDBG_MAX_DEV_NAMELEN]; BOOL bGotJump = FALSE; DWORD dwDHCPLeaseTime = 0; PDWORD pdwDHCPLeaseTime = &dwDHCPLeaseTime; DWORD dwBootFlags = 0; // If user wants to jump to existing image - skip download. // if (!g_bDownloadImage) { g_bWaitForConnect = FALSE; // Do not wait for desktop to connect. return(BL_JUMP); } // If the user wants to use a static IP address, do not request an address from a DHCP server. This is done by passing in a NULL for the DHCP lease time variable. // if (pDriverGlobals->eth.TargetAddr.dwIP && pDriverGlobals->eth.SubnetMask) { pdwDHCPLeaseTime = NULL; RETAILMSG(1, (TEXT("INFO: Using static IP address %s.\r\n"), inet_ntoa(pDriverGlobals->eth.TargetAddr.dwIP))); RETAILMSG(1, (TEXT("INFO: Using subnet mask %s.\r\n"), inet_ntoa(pDriverGlobals->eth.SubnetMask))); } // Create device name based on Ethernet address (this is how Platform Builder identifies this device). // memset(szDeviceName, 0, EDBG_MAX_DEV_NAMELEN); CreateDeviceName(&pDriverGlobals->eth.TargetAddr, szDeviceName, PLATFORM_STRING); EdbgOutputDebugString("INFO: Using device name: '%s'\n", szDeviceName); // Initialize the TFTP transport. // if (!EbootInitEtherTransport(&pDriverGlobals->eth.TargetAddr, &pDriverGlobals->eth.SubnetMask, &bGotJump, pdwDHCPLeaseTime, EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, PLATFORM_STRING, szDeviceName, EDBG_CPU_ARM720, dwBootFlags)) { return(BL_ERROR); } // Save the DHCP lease time (you could use a static IP in which case, the lease time does not matter). // pDriverGlobals->eth.DHCPLeaseTime = dwDHCPLeaseTime; return(bGotJump ? BL_JUMP : BL_DOWNLOAD); } static void itoa10( int n, char s[] ) { int i = 0; // Get absolute value of number. unsigned int val = (unsigned int)((n < 0) ? -n : n); // Extract digits in reverse order. do { s[i++] = (val % 10) + '0'; } while (val /= 10); // Add the minus sign if the number is negative. if (n < 0) s[i++] = '-'; s[i--] = '\0'; // Reverse string. for (n = 0; n < i; n++, i--) { char swap = s[n]; s[n] = s[i]; s[i] = swap; } } void CreateDeviceName(EDBG_ADDR *pMyAddr, char *szBuf, LPSTR szPlatformString) { // NOTE: ensure that the caller's buffer (szBuf) is big enough to // hold the static platform string and numerical suffix. strcpy(szBuf, szPlatformString); szBuf += strlen(szBuf); itoa10(((pMyAddr->wMAC[2]>>8) | ((pMyAddr->wMAC[2] & 0x00ff) << 8)), szBuf); }