fmd.cpp
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:30k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. //
  2. // Copyright (c) Microsoft Corporation.  All rights reserved.
  3. //
  4. //
  5. // Use of this source code is subject to the terms of the Microsoft end-user
  6. // license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
  7. // If you did not accept the terms of the EULA, you are not authorized to use
  8. // this source code. For a copy of the EULA, please see the LICENSE.RTF on your
  9. // install media.
  10. //
  11. /* ++
  12.     fmd.cpp
  13.     Bootloader support for NAND Boot & BinFS
  14. -- */
  15. extern "C" {
  16. #include <windows.h>
  17. #include <windef.h>
  18. #include <halether.h>
  19. #include <blcommon.h>
  20. #include <bootpart.h>
  21. #include <romldr.h>
  22. #include "warning.h"
  23. #include "loader.h"
  24. #ifdef SIMULATOR
  25. #include "......DRIVERSNandFlshFMDfmd.cpp"
  26. #else
  27. #include "....DRIVERSNandFlshFMDfmd.cpp"
  28. #endif
  29. LPBYTE OEMMapMemAddr(DWORD dwImageStart, DWORD dwAddr);
  30. extern DWORD        g_ImageType;
  31. extern UCHAR        g_TOC[SECTOR_SIZE];
  32. extern const PTOC   g_pTOC;
  33. extern DWORD        g_dwTocEntry;
  34. extern PBOOT_CFG    g_pBootCfg;
  35. extern BOOL         g_bBootMediaExist;
  36. extern MultiBINInfo g_BINRegionInfo;
  37. extern DWORD        g_dwImageStartBlock;
  38. extern BOOL         g_bWaitForConnect;
  39. }
  40. extern DWORD        g_dwLastWrittenLoc;                     //  Defined in bootpart.lib
  41. #include <drv_glob.h>
  42. //extern PDRIVER_GLOBALS pDriverGlobals;
  43. PDRIVER_GLOBALS pDriverGlobals = ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START);
  44. #pragma pack(1)
  45. static UCHAR toc[SECTOR_SIZE];
  46. #pragma pack()
  47. void BootConfigPrint(void)
  48. {
  49.     EdbgOutputDebugString( "BootCfg { rn");
  50.     EdbgOutputDebugString( "  ConfigFlags: 0x%xrn", g_pBootCfg->ConfigFlags);
  51.     EdbgOutputDebugString( "  BootDelay: 0x%xrn", g_pBootCfg->BootDelay);
  52.     EdbgOutputDebugString( "  ImageIndex: %d rn", g_pBootCfg->ImageIndex);
  53.     EdbgOutputDebugString( "  IP: %srn", inet_ntoa(g_pBootCfg->EdbgAddr.dwIP));
  54.     EdbgOutputDebugString( "  MAC Address: %B:%B:%B:%B:%B:%Brn",
  55.                            g_pBootCfg->EdbgAddr.wMAC[0] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[0] >> 8,
  56.                            g_pBootCfg->EdbgAddr.wMAC[1] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[1] >> 8,
  57.                            g_pBootCfg->EdbgAddr.wMAC[2] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[2] >> 8);
  58.     EdbgOutputDebugString( "  Port: %srn", inet_ntoa(g_pBootCfg->EdbgAddr.wPort));
  59.     EdbgOutputDebugString( "  SubnetMask: %srn", inet_ntoa(g_pBootCfg->SubnetMask));
  60.     EdbgOutputDebugString( "}rn");
  61. }
  62. // Set default boot configuration values
  63. static void BootConfigInit(DWORD dwIndex)
  64. {
  65. #ifdef SIMULATOR
  66.     char sMask[] = "255.255.255.255";
  67. #endif
  68.     EdbgOutputDebugString("+BootConfigInitrn");
  69.     g_pBootCfg = &g_pTOC->BootCfg;
  70.     memset(g_pBootCfg, 0, sizeof(BOOT_CFG));
  71.     g_pBootCfg->ImageIndex   = dwIndex;
  72.     g_pBootCfg->ConfigFlags  = BOOT_TYPE_MULTISTAGE | CONFIG_FLAGS_DHCP | CONFIG_FLAGS_DEBUGGER;
  73.     g_pBootCfg->BootDelay    = CONFIG_BOOTDELAY_DEFAULT;
  74. #ifdef SIMULATOR
  75.     g_pBootCfg->SubnetMask = inet_addr(sMask);
  76. #else
  77.     g_pBootCfg->SubnetMask = inet_addr("255.255.255.255");
  78. #endif
  79.     EdbgOutputDebugString("-BootConfigInitrn");
  80.     return;
  81. }
  82. void ID_Print(DWORD i) {
  83.     DWORD j;
  84.     EdbgOutputDebugString("ID[%u] {rn", i);
  85.     EdbgOutputDebugString("  dwVersion: 0x%xrn",  g_pTOC->id[i].dwVersion);
  86.     EdbgOutputDebugString("  dwSignature: 0x%xrn", g_pTOC->id[i].dwSignature);
  87.     EdbgOutputDebugString("  String: '%s'rn", g_pTOC->id[i].ucString);
  88.     EdbgOutputDebugString("  dwImageType: 0x%xrn", g_pTOC->id[i].dwImageType);
  89.     EdbgOutputDebugString("  dwTtlSectors: 0x%xrn", g_pTOC->id[i].dwTtlSectors);
  90.     EdbgOutputDebugString("  dwLoadAddress: 0x%xrn", g_pTOC->id[i].dwLoadAddress);
  91.     EdbgOutputDebugString("  dwJumpAddress: 0x%xrn", g_pTOC->id[i].dwJumpAddress);
  92.     EdbgOutputDebugString("  dwStoreOffset: 0x%xrn", g_pTOC->id[i].dwStoreOffset);
  93.     for (j = 0; j < MAX_SG_SECTORS; j++) {
  94.         if ( !g_pTOC->id[i].sgList[j].dwLength )
  95.             break;
  96.         EdbgOutputDebugString("  sgList[%u].dwSector: 0x%xrn", j, g_pTOC->id[i].sgList[j].dwSector);
  97.         EdbgOutputDebugString("  sgList[%u].dwLength: 0x%xrn", j, g_pTOC->id[i].sgList[j].dwLength);
  98.     }
  99.     EdbgOutputDebugString("}rn");
  100. }
  101. void TOC_Print(void)
  102. {
  103.     int i;
  104.     EdbgOutputDebugString("TOC {rn");
  105.     EdbgOutputDebugString("dwSignature: 0x%xrn", g_pTOC->dwSignature);
  106.     BootConfigPrint( );
  107.     for (i = 0; i < MAX_TOC_DESCRIPTORS; i++) {
  108.         if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[i]) )
  109.             break;
  110.         ID_Print(i);
  111.     }
  112.     //  Print out Chain Information
  113.     EdbgOutputDebugString("chainInfo.dwLoadAddress: 0X%Xrn", g_pTOC->chainInfo.dwLoadAddress);
  114.     EdbgOutputDebugString("chainInfo.dwFlashAddress: 0X%Xrn", g_pTOC->chainInfo.dwFlashAddress);
  115.     EdbgOutputDebugString("chainInfo.dwLength: 0X%Xrn", g_pTOC->chainInfo.dwLength);
  116. //    EdbgOutputDebugString("UDID: %B:%B:%B:%B:%B:%Brn", g_pTOC->udid[0], g_pTOC->udid[1], g_pTOC->udid[2], g_pTOC->udid[3], g_pTOC->udid[4], g_pTOC->udid[5]);
  117.     EdbgOutputDebugString("}rn");
  118. }
  119. // init the TOC to defaults
  120. BOOL TOC_Init(DWORD dwEntry, DWORD dwImageType, DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
  121. {
  122.     DWORD dwSig = 0;
  123.     EdbgOutputDebugString("TOC_Init: dwEntry:%u, dwImageType: 0x%x, dwImageStart: 0x%x, dwImageLength: 0x%x, dwLaunchAddr: 0x%xrn",
  124.         dwEntry, dwImageType, dwImageStart, dwImageLength, dwLaunchAddr);
  125.     if (0 == dwEntry) {
  126.         EdbgOutputDebugString("rn*** WARNING: TOC_Init blasting Eboot ***rn");
  127.         TEST_TRAP;
  128.     }
  129.     switch (dwImageType) {
  130.         case IMAGE_TYPE_LOADER:
  131.             dwSig = IMAGE_EBOOT_SIG;
  132.             break;
  133.         case IMAGE_TYPE_RAMIMAGE:
  134.             dwSig = IMAGE_RAM_SIG;
  135.             break;
  136.         case (IMAGE_TYPE_RAMIMAGE|IMAGE_TYPE_BINFS):
  137.             dwSig = IMAGE_BINFS_SIG;
  138.             break;
  139.         default:
  140.             EdbgOutputDebugString("ERROR: OEMLaunch: unknown image type: 0x%x rn", dwImageType);
  141.             return FALSE;
  142.     }
  143.     memset(g_pTOC, 0, sizeof(g_TOC));
  144.     // init boof cfg
  145.     BootConfigInit(dwEntry);
  146.     // update our index
  147.     g_dwTocEntry = dwEntry;
  148.     // debugger enabled?
  149.     g_bWaitForConnect = (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_DEBUGGER) ? TRUE : FALSE;
  150.     // init TOC...
  151.     //
  152.     g_pTOC->dwSignature = TOC_SIGNATURE;
  153.     //  init TOC entry for Eboot
  154.     //  Those are hard coded numbers from boot.bib
  155.     g_pTOC->id[0].dwVersion     = (EBOOT_VERSION_MAJOR << 16) | EBOOT_VERSION_MINOR;
  156.     g_pTOC->id[0].dwSignature   = IMAGE_EBOOT_SIG;
  157.     memcpy(g_pTOC->id[0].ucString, "eboot.nb0", sizeof("eboot.nb0")+1);   //  NUll terminate
  158.     g_pTOC->id[0].dwImageType   = IMAGE_TYPE_RAMIMAGE;
  159.     g_pTOC->id[0].dwLoadAddress = EBOOT_RAM_IMAGE_BASE;
  160.     g_pTOC->id[0].dwJumpAddress = EBOOT_RAM_IMAGE_BASE;
  161.     g_pTOC->id[0].dwTtlSectors  = FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE);
  162.     // 1 contigious segment
  163.     g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK);
  164.     g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;
  165.     // init the TOC entry
  166.     g_pTOC->id[dwEntry].dwVersion     = 0x001;
  167.     g_pTOC->id[dwEntry].dwSignature   = dwSig;
  168.     memset(g_pTOC->id[dwEntry].ucString, 0, IMAGE_STRING_LEN);
  169.     g_pTOC->id[dwEntry].dwImageType   = dwImageType;
  170.     g_pTOC->id[dwEntry].dwLoadAddress = dwImageStart;
  171.     g_pTOC->id[dwEntry].dwJumpAddress = dwLaunchAddr;
  172.     g_pTOC->id[dwEntry].dwStoreOffset = 0;
  173.     g_pTOC->id[dwEntry].dwTtlSectors  = FILE_TO_SECTOR_SIZE(dwImageLength);
  174.     // 1 contigious segment
  175.     g_pTOC->id[dwEntry].sgList[0].dwSector = BLOCK_TO_SECTOR(g_dwImageStartBlock);
  176.     g_pTOC->id[dwEntry].sgList[0].dwLength = g_pTOC->id[dwEntry].dwTtlSectors;
  177.     TOC_Print();
  178.     return TRUE;
  179. }
  180. //
  181. // Retrieve TOC from Nand.
  182. //
  183. BOOL TOC_Read(void)
  184. {
  185. SectorInfo si;
  186. EdbgOutputDebugString("TOC_Readrn");
  187. if ( !g_bBootMediaExist )
  188. {
  189. EdbgOutputDebugString("TOC_Read ERROR: no boot mediarn");
  190. return FALSE;
  191. }
  192. if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)g_pTOC, &si, 1) )
  193. {
  194. EdbgOutputDebugString("TOC_Read ERROR: Unable to read TOCrn");
  195. return FALSE;
  196. }
  197. // is it a valid TOC?
  198. if ( !VALID_TOC(g_pTOC) )
  199. {
  200. EdbgOutputDebugString("TOC_Read ERROR: INVALID_TOC Signature: 0x%xrn", g_pTOC->dwSignature);
  201. return FALSE;
  202. }
  203. // is it an OEM block?
  204. if ( (si.bBadBlock != BADBLOCKMARK) || !(si.bOEMReserved & (OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY)) )
  205. {
  206. EdbgOutputDebugString("TOC_Read ERROR: SectorInfo verify failed: %x %x %x %xrn",
  207. si.dwReserved1, si.bOEMReserved, si.bBadBlock, si.wReserved2);
  208. return FALSE;
  209. }
  210. // update our boot config
  211. g_pBootCfg = &g_pTOC->BootCfg;
  212. // update our index
  213. g_dwTocEntry = g_pBootCfg->ImageIndex;
  214. // debugger enabled?
  215. g_bWaitForConnect = (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_DEBUGGER) ? TRUE : FALSE;
  216. // cache image type
  217. g_ImageType = g_pTOC->id[g_dwTocEntry].dwImageType;
  218. TOC_Print( );
  219. EdbgOutputDebugString("-TOC_Readrn");
  220. return TRUE;
  221. }
  222. //
  223. // Store TOC to Nand
  224. // BUGBUG: only uses 1 sector for now.
  225. //
  226. BOOL TOC_Write(void)
  227. {
  228.     SectorInfo si, si2;
  229.     EdbgOutputDebugString("+TOC_Writern");
  230.     if ( !g_bBootMediaExist ) {
  231.         EdbgOutputDebugString("TOC_Write WARN: no boot mediarn");
  232.         return FALSE;
  233.     }
  234.     // is it a valid TOC?
  235.     if ( !VALID_TOC(g_pTOC) ) {
  236.         EdbgOutputDebugString("TOC_Write ERROR: INVALID_TOC Signature: 0x%xrn", g_pTOC->dwSignature);
  237.         return FALSE;
  238.     }
  239.     // is it a valid image descriptor?
  240.     if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) ) {
  241.         EdbgOutputDebugString("TOC_Write ERROR: INVALID_IMAGE[%u] Signature: 0x%xrn",
  242.             g_dwTocEntry, g_pTOC->id[g_dwTocEntry].dwSignature);
  243.         return FALSE;
  244.     }
  245.     // in order to write a sector we must erase the entire block first
  246. // !! BUGBUG: must cache the TOC first so we don't trash other image descriptors !!
  247.     RETAILMSG(1, (TEXT("Erasing Block: %urn"), TOC_BLOCK));
  248.     if ( !FMD_EraseBlock(TOC_BLOCK) ) {
  249.         RETAILMSG(1, (TEXT("TOC_Write ERROR: EraseBlock[%d] rn"), TOC_BLOCK));
  250.         return FALSE;
  251.     }
  252.     // setup our metadata so filesys won't stomp us
  253.     si.dwReserved1 = 0;
  254.     si.bOEMReserved = OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY;
  255.     si.bBadBlock = BADBLOCKMARK;
  256.     si.wReserved2 = 0;
  257.     // write the sector & metadata
  258.     RETAILMSG(1, (TEXT("FMD_WriteSector............. rn")));
  259.     if ( !FMD_WriteSector(TOC_SECTOR, (PUCHAR)&g_TOC, &si, 1) ) {
  260.         EdbgOutputDebugString("TOC_Write ERROR: Unable to save TOCrn");
  261.         return FALSE;
  262.     }
  263.     // read it back & verify both data & metadata
  264.     RETAILMSG(1, (TEXT("FMD_ReadSector............. rn")));
  265.     if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)&toc, &si2, 1) ) {
  266.         EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOCrn");
  267.         return FALSE;
  268.     }
  269.     RETAILMSG(1, (TEXT("memcmp............. rn")));
  270.     if ( 0 != memcmp(&g_TOC, &toc, SECTOR_SIZE) ) {
  271.         EdbgOutputDebugString("TOC_Write ERROR: TOC verify failedrn");
  272.         return FALSE;
  273.     }
  274.     if ( 0 != memcmp(&si, &si2, sizeof(si)) ) {
  275.         EdbgOutputDebugString("TOC_Write ERROR: SectorInfo verify failed: %x %x %x %xrn",
  276.             si.dwReserved1, si.bOEMReserved, si.bBadBlock, si.wReserved2);
  277.         return FALSE;
  278.     }
  279. TOC_Print();
  280.     EdbgOutputDebugString("-TOC_Writern");
  281.     return TRUE;
  282. }
  283. /*
  284.     @func   PVOID | GetKernelExtPointer | Locates the kernel region's extension area pointer.
  285.     @rdesc  Pointer to the kernel's extension area.
  286.     @comm
  287.     @xref
  288. */
  289. PVOID GetKernelExtPointer(DWORD dwRegionStart, DWORD dwRegionLength)
  290. {
  291.     DWORD dwCacheAddress = 0;
  292.     ROMHDR *pROMHeader;
  293.     DWORD dwNumModules = 0;
  294.     TOCentry *pTOC;
  295.     if (dwRegionStart == 0 || dwRegionLength == 0)
  296.         return(NULL);
  297.     if (*(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE)
  298.         return NULL;
  299.     // A pointer to the ROMHDR structure lives just past the ROM_SIGNATURE (which is a longword value).  Note that
  300.     // this pointer is remapped since it might be a flash address (image destined for flash), but is actually cached
  301.     // in RAM.
  302.     //
  303.     dwCacheAddress = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
  304.     pROMHeader     = (ROMHDR *) OEMMapMemAddr(dwRegionStart, dwCacheAddress);
  305.     // Make sure there are some modules in the table of contents.
  306.     //
  307.     if ((dwNumModules = pROMHeader->nummods) == 0)
  308.         return NULL;
  309.     // Locate the table of contents and search for the kernel executable and the TOC immediately follows the ROMHDR.
  310.     //
  311.     pTOC = (TOCentry *)(pROMHeader + 1);
  312.     while (dwNumModules--) {
  313.         LPBYTE pFileName = OEMMapMemAddr(dwRegionStart, (DWORD)pTOC->lpszFileName);
  314.         // EdbgOutputDebugString("GetKernelExtPointer: found module[%u]: %srn", dwNumModules, pFileName);
  315.         if (!strcmp((const char *)pFileName, "nk.exe")) {
  316.             return ((PVOID)(pROMHeader->pExtensions));
  317.         }
  318.         ++pTOC;
  319.     }
  320.     return NULL;
  321. }
  322. /*
  323.     @func   BOOL | WriteRegionsToBootMedia | Stores the image cached in RAM to the Boot Media.
  324.     The image may be comprised of one or more BIN regions.
  325.     @rdesc  TRUE = Success, FALSE = Failure.
  326.     @comm
  327.     @xref
  328. */
  329. BOOL WriteRegionsToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
  330. {
  331.     BYTE nCount;
  332.     DWORD dwNumExts;
  333.     PXIPCHAIN_SUMMARY pChainInfo = NULL;
  334.     EXTENSION *pExt = NULL;
  335.     DWORD dwBINFSPartLength = 0;
  336.     HANDLE hPart, hPartEx;
  337.     DWORD dwStoreOffset;
  338.     DWORD dwMaxRegionLength[BL_MAX_BIN_REGIONS] = {0};
  339.     DWORD dwChainStart, dwChainLength;
  340.     //  Initialize the variables
  341.     dwChainStart = dwChainLength = 0;
  342.     EdbgOutputDebugString("+WriteRegionsToBootMedia: ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%xrn",
  343.                             dwImageStart, dwImageLength, dwLaunchAddr);
  344.     if ( !g_bBootMediaExist ) {
  345.         EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: device doesn't exist.rn");
  346.         return(FALSE);
  347.     }
  348.     if ( !VALID_TOC(g_pTOC) ) {
  349.         EdbgOutputDebugString("WARN: WriteRegionsToBootMedia: INVALID_TOCrn");
  350.         if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) {
  351.             EdbgOutputDebugString("ERROR: INVALID_TOCrn");
  352.             return(FALSE);
  353.         }
  354.     }
  355.     if ( !(IMAGE_TYPE_BINFS & g_pTOC->id[g_dwTocEntry].dwImageType) ) {
  356.         EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: INVALID_IMAGE_TYPE: 0x%xrn",
  357.             g_pTOC->id[g_dwTocEntry].dwImageType);
  358.         return(FALSE);
  359.     }
  360.     // Look in the kernel region's extension area for a multi-BIN extension descriptor.
  361.     // This region, if found, details the number, start, and size of each BIN region.
  362.     //
  363.     //for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions) && !pChainInfo ; nCount++)
  364.     for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions); nCount++)
  365.     {
  366.         // Does this region contain nk.exe and an extension pointer?
  367.         //
  368.         pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart,
  369.                                                 g_BINRegionInfo.Region[nCount].dwRegionLength );
  370.         if ( pExt != NULL)
  371.         {
  372.             // If there is an extension pointer region, walk it until the end.
  373.             //
  374.             while (pExt)
  375.             {
  376.                 DWORD dwBaseAddr = g_BINRegionInfo.Region[nCount].dwRegionStart;
  377.                 pExt = (EXTENSION *)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt);
  378.                 EdbgOutputDebugString("INFO: OEMLaunch: Found chain extenstion: '%s' @ 0x%xrn", pExt->name, dwBaseAddr);
  379.                 if ((pExt->type == 0) && !strcmp(pExt->name, "chain information"))
  380.                 {
  381.                     pChainInfo = (PXIPCHAIN_SUMMARY) OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata);
  382.                     dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY));
  383.                     EdbgOutputDebugString("INFO: OEMLaunch: Found 'chain information' (pChainInfo=0x%x  Extensions=0x%x).rn", (DWORD)pChainInfo, dwNumExts);
  384.                     break;
  385.                 }
  386.                 pExt = (EXTENSION *)pExt->pNextExt;
  387.             }
  388.         }
  389.         else {
  390.             //  Search for Chain region. Chain region doesn't have the ROMSIGNATURE set
  391.             DWORD   dwRegionStart = g_BINRegionInfo.Region[nCount].dwRegionStart;
  392.             DWORD   dwSig = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET);
  393.             if ( dwSig != ROM_SIGNATURE) {
  394.                 //  It is the chain
  395.                 dwChainStart = dwRegionStart;
  396.                 dwChainLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
  397.                 EdbgOutputDebugString("Found the Chain region: StartAddress: 0x%X; Length: 0x%Xn", dwChainStart, dwChainLength);
  398.             }
  399.         }
  400.     }
  401.     // Determine how big the Total BINFS partition needs to be to store all of this.
  402.     //
  403.     if (pChainInfo && dwNumExts == g_BINRegionInfo.dwNumRegions)    // We're downloading all the regions in a multi-region image...
  404.     {
  405.         DWORD i;
  406.         EdbgOutputDebugString("Writing multi-regionsrn");
  407.         for (nCount = 0, dwBINFSPartLength = 0 ; nCount < dwNumExts ; nCount++)
  408.         {
  409.             dwBINFSPartLength += (pChainInfo + nCount)->dwMaxLength;
  410.             EdbgOutputDebugString("BINFSPartMaxLength[%u]: 0x%x, TtlBINFSPartLength: 0x%x rn",
  411.                 nCount, (pChainInfo + nCount)->dwMaxLength, dwBINFSPartLength);
  412.             // MultiBINInfo does not store each Regions MAX length, and pChainInfo is not in any particular order.
  413.             // So, walk our MultiBINInfo matching up pChainInfo to find each regions MAX Length
  414.             for (i = 0; i < dwNumExts; i++) {
  415.                 if ( g_BINRegionInfo.Region[i].dwRegionStart == (DWORD)((pChainInfo + nCount)->pvAddr) ) {
  416.                     dwMaxRegionLength[i] = (pChainInfo + nCount)->dwMaxLength;
  417.                     EdbgOutputDebugString("dwMaxRegionLength[%u]: 0x%x rn", i, dwMaxRegionLength[i]);
  418.                     break;
  419.                 }
  420.             }
  421.         }
  422.     }
  423.     else    // A single BIN file or potentially a multi-region update (but the partition's already been created in this latter case).
  424.     {
  425.         dwBINFSPartLength = g_BINRegionInfo.Region[0].dwRegionLength;
  426.         EdbgOutputDebugString("Writing single region/multi-region update, dwBINFSPartLength: %u rn", dwBINFSPartLength);
  427.     }
  428.     // Open/Create the BINFS partition where images are stored.  This partition starts immediately after the MBR on the Boot Media and its length is
  429.     // determined by the maximum image size (or sum of all maximum sizes in a multi-region design).
  430.     // Parameters are LOGICAL sectors.
  431.     //
  432. /*    hPart = BP_OpenPartition( NEXT_FREE_LOC,
  433.                               FILE_TO_SECTOR_SIZE(dwBINFSPartLength) + 1, // sizeof image + MBR sector
  434.                               PART_BINFS,
  435.                               TRUE,
  436.                               PART_OPEN_ALWAYS);
  437. */
  438.     hPart = BP_OpenPartition( (IMAGE_START_BLOCK+1)*PAGES_PER_BLOCK, // next block of MBR
  439.                               SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength))*PAGES_PER_BLOCK, // align to block
  440.                               PART_BINFS,
  441.                               TRUE,
  442.                               PART_OPEN_ALWAYS);
  443.     if (hPart == INVALID_HANDLE_VALUE )
  444.     {
  445.         EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: Failed to open/create BINFS partition.rn");
  446.         return(FALSE);
  447.     }
  448.     // Are there multiple BIN files in RAM (we may just be updating one in a multi-BIN solution)?
  449.     //
  450.     for (nCount = 0, dwStoreOffset = 0; nCount < g_BINRegionInfo.dwNumRegions ; nCount++)
  451.     {
  452.         DWORD dwRegionStart  = (DWORD)OEMMapMemAddr(0, g_BINRegionInfo.Region[nCount].dwRegionStart);
  453.         DWORD dwRegionLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
  454.         // Media byte offset where image region is stored.
  455.         dwStoreOffset += nCount ? dwMaxRegionLength[nCount-1] : 0;
  456.         EdbgOutputDebugString("dwRegionStart: 0x%x, dwRegionLength: 0x%x, dwStoreOffset: 0x%xrn",
  457.             dwRegionStart, dwRegionLength, dwStoreOffset);
  458.         // Set the file pointer (byte indexing) to the correct offset for this particular region.
  459.         //
  460.         if ( !BP_SetDataPointer(hPart, dwStoreOffset) )
  461.         {
  462.             EdbgOutputDebugString("ERROR: StoreImageToBootMedia: Failed to set data pointer in BINFS partition (offset=0x%x).rn", dwStoreOffset);
  463.             return(FALSE);
  464.         }
  465.         // Write the region to the BINFS partition.
  466.         //
  467.         if ( !BP_WriteData(hPart, (LPBYTE)dwRegionStart, dwRegionLength) )
  468.         {
  469.             EdbgOutputDebugString("ERROR: StoreImageToBootMedia: Failed to write region to BINFS partition (start=0x%x, length=0x%x).rn", dwRegionStart, dwRegionLength);
  470.             return(FALSE);
  471.         }
  472.         // update our TOC?
  473.         //
  474.         if ((g_pTOC->id[g_dwTocEntry].dwLoadAddress == g_BINRegionInfo.Region[nCount].dwRegionStart) &&
  475.              g_pTOC->id[g_dwTocEntry].dwTtlSectors == FILE_TO_SECTOR_SIZE(dwRegionLength) )
  476.         {
  477.             g_pTOC->id[g_dwTocEntry].dwStoreOffset = dwStoreOffset;
  478.             g_pTOC->id[g_dwTocEntry].dwJumpAddress = 0; // Filled upon return to OEMLaunch
  479.             g_pTOC->id[g_dwTocEntry].dwImageType = g_ImageType;
  480.             g_pTOC->id[g_dwTocEntry].sgList[0].dwSector = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
  481.             g_pTOC->id[g_dwTocEntry].sgList[0].dwLength = g_pTOC->id[g_dwTocEntry].dwTtlSectors;
  482.             // copy Kernel Region to SDRAM for jump
  483.             memcpy((void*)g_pTOC->id[g_dwTocEntry].dwLoadAddress, (void*)dwRegionStart, dwRegionLength);
  484.             EdbgOutputDebugString("Updateded TOC!rn");
  485.         } 
  486.         else if( (dwChainStart == g_BINRegionInfo.Region[nCount].dwRegionStart) &&
  487.                  (dwChainLength == g_BINRegionInfo.Region[nCount].dwRegionLength)) 
  488.         {
  489.             //  Update our TOC for Chain region
  490.             g_pTOC->chainInfo.dwLoadAddress = dwChainStart;
  491.             g_pTOC->chainInfo.dwFlashAddress = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
  492.             g_pTOC->chainInfo.dwLength = FILE_TO_SECTOR_SIZE(dwMaxRegionLength[nCount]);
  493.             EdbgOutputDebugString("Written Chain Region to the Flashn");
  494.             EdbgOutputDebugString("LoadAddress = 0x%X; FlashAddress = 0x%X; Length = 0x%Xn", 
  495.                                   g_pTOC->chainInfo.dwLoadAddress, 
  496.                                   g_pTOC->chainInfo.dwFlashAddress,
  497.                                   g_pTOC->chainInfo.dwLength);
  498.             // Now copy it to the SDRAM
  499.             memcpy((void *)g_pTOC->chainInfo.dwLoadAddress, (void *)dwRegionStart, dwRegionLength);
  500. //            memcpy((void *)0x8c050000, (void *)dwRegionStart, dwRegionLength);
  501.         }
  502.     }
  503.     // create extended partition in whatever is left
  504.     //
  505.     hPartEx = BP_OpenPartition( NEXT_FREE_LOC,
  506.                                 USE_REMAINING_SPACE,
  507.                                 PART_DOS32,
  508.                                 TRUE,
  509.                                 PART_OPEN_ALWAYS);
  510.     if (hPartEx == INVALID_HANDLE_VALUE )
  511.     {
  512.         EdbgOutputDebugString("*** WARN: StoreImageToBootMedia: Failed to open/create Extended partition ***rn");
  513.     }
  514.     EdbgOutputDebugString("-WriteRegionsToBootMediarn");
  515.     return(TRUE);
  516. }
  517. /*
  518.     @func   BOOL | ReadKernelRegionFromBootMedia |
  519.             BinFS support. Reads the kernel region from Boot Media into RAM.  The kernel region is fixed up
  520.             to run from RAM and this is done just before jumping to the kernel entry point.
  521.     @rdesc  TRUE = Success, FALSE = Failure.
  522.     @comm
  523.     @xref
  524. */
  525. BOOL ReadKernelRegionFromBootMedia( )
  526. {
  527.     HANDLE hPart;
  528.     SectorInfo si;
  529. DWORD  chainaddr, flashaddr;
  530. int i;
  531.     if (!g_bBootMediaExist) {
  532.         EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: device doesn't exist.rn");
  533.         return(FALSE);
  534.     }
  535.     if ( !VALID_TOC(g_pTOC) ) {
  536.         EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: INVALID_TOCrn");
  537.         return(FALSE);
  538.     }
  539.     if ( !(IMAGE_TYPE_BINFS & g_pTOC->id[g_dwTocEntry].dwImageType) ) {
  540.         EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: INVALID_IMAGE_TYPE: 0x%xrn",
  541.             g_pTOC->id[g_dwTocEntry].dwImageType);
  542.         return(FALSE);
  543.     }
  544.     if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) ) {
  545.         EdbgOutputDebugString("OEMPlatformInit: ERROR_INVALID_IMAGE_DESCRIPTOR: 0x%xrn",
  546.             g_pTOC->id[g_dwTocEntry].dwSignature);
  547.         return FALSE;
  548.     }
  549.     if ( !OEMVerifyMemory(g_pTOC->id[g_dwTocEntry].dwLoadAddress, sizeof(DWORD)) ||
  550.          !OEMVerifyMemory(g_pTOC->id[g_dwTocEntry].dwJumpAddress, sizeof(DWORD)) ||
  551.          !g_pTOC->id[g_dwTocEntry].dwTtlSectors )
  552.     {
  553.         EdbgOutputDebugString("OEMPlatformInit: ERROR_INVALID_ADDRESS: (address=0x%x, sectors=0x%x, launch address=0x%x)...rn",
  554.             g_pTOC->id[g_dwTocEntry].dwLoadAddress, g_pTOC->id[g_dwTocEntry].dwTtlSectors, g_pTOC->id[g_dwTocEntry].dwJumpAddress);
  555.         return FALSE;
  556.     }
  557.     EdbgOutputDebugString("INFO: Loading image from Boot Media to RAM (address=0x%x, sectors=0x%x, launch address=0x%x)...rn",
  558.         g_pTOC->id[g_dwTocEntry].dwLoadAddress, g_pTOC->id[g_dwTocEntry].dwTtlSectors, g_pTOC->id[g_dwTocEntry].dwJumpAddress);
  559.     // Open the BINFS partition (it must exist).
  560.     //
  561.     hPart = BP_OpenPartition( NEXT_FREE_LOC,
  562.                               USE_REMAINING_SPACE,
  563.                               PART_BINFS,
  564.                               TRUE,
  565.                               PART_OPEN_EXISTING);
  566.     if (hPart == INVALID_HANDLE_VALUE )
  567.     {
  568.         EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to open existing BINFS partition.rn");
  569.         return(FALSE);
  570.     }
  571.     // Set the partition file pointer to the correct offset for the kernel region.
  572.     //
  573.     if ( !BP_SetDataPointer(hPart, g_pTOC->id[g_dwTocEntry].dwStoreOffset) )
  574.     {
  575.         EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to set data pointer in BINFS partition (offset=0x%x).rn",
  576.             g_pTOC->id[g_dwTocEntry].dwStoreOffset);
  577.         return(FALSE);
  578.     }
  579.     // Read the kernel region from the Boot Media into RAM.
  580.     //
  581.     if ( !BP_ReadData( hPart,
  582.                        (LPBYTE)(g_pTOC->id[g_dwTocEntry].dwLoadAddress),
  583.                        SECTOR_TO_FILE_SIZE(g_pTOC->id[g_dwTocEntry].dwTtlSectors)) )
  584.     {
  585.         EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to read kernel region from BINFS partition.rn");
  586.         return(FALSE);
  587.     }
  588.     EdbgOutputDebugString("g_pTOC->chainInfo.dwLength=0x%xrn", g_pTOC->chainInfo.dwLength);
  589. chainaddr = g_pTOC->chainInfo.dwLoadAddress;
  590. flashaddr = g_pTOC->chainInfo.dwFlashAddress;
  591. for ( i = 0; i < (g_pTOC->chainInfo.dwLength); i++ )
  592. {
  593.     EdbgOutputDebugString("chainaddr=0x%x, flashaddr=0x%xrn", chainaddr, flashaddr+i);
  594. if ( !FMD_ReadSector(flashaddr+i, (PUCHAR)(chainaddr), &si, 1) ) {
  595. EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOCrn");
  596. return FALSE;
  597. }
  598. chainaddr += 512;
  599. }
  600. {
  601. int i;
  602. for ( i = 0; i < 60; i++ )
  603. EdbgOutputDebugString("[0x%x]0x%x ", g_pTOC->chainInfo.dwLoadAddress + i, *(LPBYTE)(g_pTOC->chainInfo.dwLoadAddress + i));
  604. }
  605.     return(TRUE);
  606. }
  607. BOOL ReadRamImageFromBootMedia( )
  608. {
  609.     DWORD dwSectorsNeeded;
  610.     DWORD dwSector, dwLength;   // Start Sector & Length
  611.     DWORD dwLoadAddress, dwJumpAddr, i;
  612.     if ( !TOC_Read( ) ) { // should already be read
  613.         return FALSE;
  614.     }
  615.     // is this a RAM image?
  616.     // N.B: we can't read BinFS regions because we don' know where they are in g_pTOC->id[dwEntry].sgList[i].dwSector
  617.     if ( g_pTOC->id[g_dwTocEntry].dwImageType != IMAGE_TYPE_RAMIMAGE ) {
  618.         EdbgOutputDebugString("ReadRamImageFromBootMedia ERROR: TOC[%u] not a RAM image: 0x%xrn",
  619.             g_dwTocEntry, g_pTOC->id[g_dwTocEntry].dwImageType);
  620.         return FALSE;
  621.     }
  622.     dwSectorsNeeded = g_pTOC->id[g_dwTocEntry].dwTtlSectors;
  623.     dwLoadAddress   = g_pTOC->id[g_dwTocEntry].dwLoadAddress;
  624.     dwJumpAddr      = g_pTOC->id[g_dwTocEntry].dwJumpAddress ? g_pTOC->id[g_dwTocEntry].dwJumpAddress :
  625.                                                           g_pTOC->id[g_dwTocEntry].dwLoadAddress;
  626.     EdbgOutputDebugString("dwSectorsNeeded: 0x%x,  dwLoadAddress: 0x%x, dwJumpAddr: 0x%xrn",
  627.         dwSectorsNeeded, dwLoadAddress, dwJumpAddr);
  628.     //
  629.     // Load the disk image directly into RAM
  630.     // BUGBUG: recover from read failures
  631.     //
  632.     i = 0;
  633. while (dwSectorsNeeded && i < MAX_SG_SECTORS)
  634. {
  635.         dwSector = g_pTOC->id[g_dwTocEntry].sgList[i].dwSector;
  636.         dwLength = g_pTOC->id[g_dwTocEntry].sgList[i].dwLength;
  637.         // read each sg segment
  638.         while (dwLength) {
  639.             if ( !FMD_ReadSector(dwSector, (LPBYTE)dwLoadAddress, NULL, 1) ) {
  640.                 EdbgOutputDebugString("ReadRamImageFromBootMedia ERROR reading sector: 0x%xrn", dwSector);
  641.                 return FALSE;
  642.             }
  643.      dwSector++;
  644.      dwLength--;
  645.             dwLoadAddress += SECTOR_SIZE;
  646.         }
  647.         dwSectorsNeeded -= dwLength;
  648.         i++;
  649.     }
  650.     return TRUE;
  651. }
  652. BOOL WriteRamImageToBootMedia(DWORD dwEntry)
  653. {
  654.     EdbgOutputDebugString("*** ERROR: WriteRamImageToBootMedia: NOT IMPLEMENTED *** rn");
  655.     return FALSE;
  656. }