//------------------------------------------------------------------------------ // // Function: OEMIsFlashAddr // // This function determines whether the address provided lies in a platform's // flash or RAM address range. // BOOL OEMIsFlashAddr(ULONG address) { BOOL rc; OALMSG(OAL_FUNC, (L"+OEMIsFlashAddr(0x%08x)\r\n", address)); rc = ( address >= (UINT32)OALPAtoCA(IMAGE_FLASH_PA_START) && address < (UINT32)OALPAtoCA(IMAGE_FLASH_PA_START + IMAGE_FLASH_SIZE) ); OALMSG(OAL_FUNC, (L"-OEMIsFlashAddr(rc = %d)\r\n", rc)); return rc; }
//------------------------------------------------------------------------------ // // Function: OEMStartEraseFlash // // This function is called by the bootloader to initiate the flash memory // erasing process. // BOOL OEMStartEraseFlash(ULONG address, ULONG size) { BOOL rc = FALSE; OALMSG(OAL_FUNC, ( L"+OEMStartEraseFlash(0x%08x, 0x%08x)\r\n", address, size )); if ( address < (UINT32)OALPAtoCA(IMAGE_FLASH_PA_START) || size > IMAGE_FLASH_SIZE ) { OALMSG(OAL_WARN, ( L"OEMStartEraseFlash: Invalid region (start 0x%08x size 0x%08x)\r\n", address, size )); goto cleanUp; } // Save address and size for later g_flashAddress = address; g_flashSize = size; rc = TRUE; cleanUp: OALMSG(OAL_FUNC, (L"-OEMStartEraseFlash(rc = %d)\r\n", rc)); return rc; }
//------------------------------------------------------------------------------ // // Function: OEMMultiBinNotify // VOID OEMMultiBinNotify( MultiBINInfo *pInfo ) { BOOL rc = FALSE; UINT32 base = OALVAtoPA((UCHAR*)IMAGE_WINCE_CODE_CA); UINT32 start, length; UINT32 ix; OALMSGS(OAL_FUNC, ( L"+OEMMultiBinNotify(0x%08x -> %d)\r\n", pInfo, pInfo->dwNumRegions )); OALMSG(OAL_INFO, ( L"Download file information:\r\n" )); OALMSG(OAL_INFO, ( L"-----------------------------------------------------------\r\n" )); // Copy information to EBOOT structure and set also save address g_eboot.numRegions = pInfo->dwNumRegions; for (ix = 0; ix < pInfo->dwNumRegions; ix++) { g_eboot.region[ix].start = pInfo->Region[ix].dwRegionStart; g_eboot.region[ix].length = pInfo->Region[ix].dwRegionLength; g_eboot.region[ix].base = base; base += g_eboot.region[ix].length; OALMSG(OAL_INFO, ( L"[%d]: Address=0x%08x Length=0x%08x Save=0x%08x\r\n", ix, g_eboot.region[ix].start, g_eboot.region[ix].length, g_eboot.region[ix].base )); } OALMSG(OAL_INFO, ( L"-----------------------------------------------------------\r\n" )); // Determine type of image downloaded if (g_eboot.numRegions > 1) { OALMSG(OAL_ERROR, (L"ERROR: MultiXIP image is not supported\r\n")); goto cleanUp; } base = g_eboot.region[0].base; start = g_eboot.region[0].start; length = g_eboot.region[0].length; if (start == IMAGE_XLDR_CODE_PA) { g_eboot.type = DOWNLOAD_TYPE_XLDR; memset(OALPAtoCA(base), 0xFF, length); } else if (start == IMAGE_EBOOT_CODE_CA) { g_eboot.type = DOWNLOAD_TYPE_EBOOT; memset(OALPAtoCA(base), 0xFF, length); } else if (start == (IMAGE_WINCE_CODE_CA + NAND_ROMOFFSET)) { g_eboot.type = DOWNLOAD_TYPE_FLASHNAND; memset(OALPAtoCA(base), 0xFF, length); } else if (start == (IMAGE_WINCE_CODE_CA + NOR_ROMOFFSET)) { g_eboot.type = DOWNLOAD_TYPE_FLASHNOR; memset(OALPAtoCA(base), 0xFF, length); } else if (start == 0) // Probably a NB0 file, let's fint out { // Convert the file name to lower case CHAR szFileName[MAX_PATH]; int i = 0; int fileExtPos = 0; while ((pInfo->Region[0].szFileName[i] != '\0') && (i < MAX_PATH)) { if((pInfo->Region[0].szFileName[i] >= 'A') && (pInfo->Region[0].szFileName[i] <= 'Z')) { szFileName[i] = (pInfo->Region[0].szFileName[i] - 'A' + 'a'); } else { szFileName[i] = pInfo->Region[0].szFileName[i]; } // Keep track of file extension position if (szFileName[i] == '.') { fileExtPos = i; } i++; } // Copy string terminator as well szFileName[i] = pInfo->Region[0].szFileName[i]; // Check if we support this file if (strncmp(szFileName, LOGO_NB0_FILE, LOGO_NB0_FILE_LEN) == 0) { // Remap the start address to the correct NAND location of the logo g_eboot.region[0].start = IMAGE_XLDR_BOOTSEC_NAND_SIZE + IMAGE_EBOOT_BOOTSEC_NAND_SIZE; g_eboot.type = DOWNLOAD_TYPE_LOGO; } else { OALMSG(OAL_ERROR, (L"Unsupported downloaded file\r\n")); goto cleanUp; } } else { g_eboot.type = DOWNLOAD_TYPE_RAM; } OALMSG(OAL_INFO, ( L"Download file type: %d\r\n", g_eboot.type )); rc = TRUE; cleanUp: if (!rc) { OALMSG(OAL_ERROR, (L"Spin for ever...\r\n")); for(;;); } OALMSGS(OAL_FUNC, (L"-OEMMultiBinNotify\r\n")); }
//------------------------------------------------------------------------------ // // Function: BLFlashDownload // // This function download image from flash memory to RAM. // UINT32 BLFlashDownload() { UINT32 rc = BL_ERROR; ROMHDR *pTOC; ULONG *pFlash; // Check if there is a valid image OALLog(L"INFO: Try Boot Image from flash memory\r\n"); // Make sure that there is image in flash memory pFlash = OALPAtoCA(IMAGE_FLASH_PA_START + ROM_SIGNATURE_OFFSET); if (*pFlash != ROM_SIGNATURE) { OALLog(L"ERROR: Image Signature in Flash Memory not found\r\n"); goto cleanUp; } // Get TOC pointer pFlash++; pTOC = (ROMHDR*)( *pFlash - IMAGE_WINCE_CODE_PA_START + IMAGE_FLASH_PA_START ); // Print out ROMHDR information OALLog(L"\r\n"); OALLog(L"ROMHDR (pTOC = 0x%08x) ---------------------\r\n", pTOC); OALLog(L" DLL First : 0x%08x\r\n", pTOC->dllfirst); OALLog(L" DLL Last : 0x%08x\r\n", pTOC->dlllast); OALLog(L" Physical First : 0x%08x\r\n", pTOC->physfirst); OALLog(L" Physical Last : 0x%08x\r\n", pTOC->physlast); OALLog(L" Num Modules : %10d\r\n", pTOC->nummods); OALLog(L" RAM Start : 0x%08x\r\n", pTOC->ulRAMStart); OALLog(L" RAM Free : 0x%08x\r\n", pTOC->ulRAMFree); OALLog(L" RAM End : 0x%08x\r\n", pTOC->ulRAMEnd); OALLog(L" Num Copy Entries : %10d\r\n", pTOC->ulCopyEntries); OALLog(L" Copy Entries Offset : 0x%08x\r\n", pTOC->ulCopyOffset); OALLog(L" Prof Symbol Length : 0x%08x\r\n", pTOC->ulProfileLen); OALLog(L" Prof Symbol Offset : 0x%08x\r\n", pTOC->ulProfileOffset); OALLog(L" Num Files : %10d\r\n", pTOC->numfiles); OALLog(L" Kernel Flags : 0x%08x\r\n", pTOC->ulKernelFlags); OALLog(L" FileSys RAM Percent : 0x%08x\r\n", pTOC->ulFSRamPercent); OALLog(L" Driver Glob Start : 0x%08x\r\n", pTOC->ulDrivglobStart); OALLog(L" Driver Glob Length : 0x%08x\r\n", pTOC->ulDrivglobLen); OALLog(L" CPU : 0x%04x\r\n", pTOC->usCPUType); OALLog(L" MiscFlags : 0x%04x\r\n", pTOC->usMiscFlags); OALLog(L" Extensions : 0x%08x\r\n", pTOC->pExtensions); OALLog(L" Tracking Mem Start : 0x%08x\r\n", pTOC->ulTrackingStart); OALLog(L" Tracking Mem Length : 0x%08x\r\n", pTOC->ulTrackingLen); OALLog(L"\r\n"); // Image base must be same as we expect if (pTOC->physfirst != (DWORD)OALPAtoCA(IMAGE_WINCE_CODE_PA_START)) { OALLog(L"ERROR: Image in flash memory has incorrect base\r\n"); goto cleanUp; } // Copy image it OALLog(L"Copy image from flash to memory..."); memcpy( OALPAtoCA(IMAGE_WINCE_CODE_PA_START), OALPAtoCA(IMAGE_FLASH_PA_START), pTOC->physlast - pTOC->physfirst ); OALLog(L" Done\r\n"); // Ok, lets jump to image rc = BL_JUMP; cleanUp: return rc; }