fmd.cpp
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:30k
源码类别:
Windows CE
开发平台:
Windows_Unix
- //
- // 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.
- //
- /* ++
- fmd.cpp
- Bootloader support for NAND Boot & BinFS
- -- */
- extern "C" {
- #include <windows.h>
- #include <windef.h>
- #include <halether.h>
- #include <blcommon.h>
- #include <bootpart.h>
- #include <romldr.h>
- #include "warning.h"
- #include "loader.h"
- #ifdef SIMULATOR
- #include "......DRIVERSNandFlshFMDfmd.cpp"
- #else
- #include "....DRIVERSNandFlshFMDfmd.cpp"
- #endif
- LPBYTE OEMMapMemAddr(DWORD dwImageStart, DWORD dwAddr);
- extern DWORD g_ImageType;
- extern UCHAR g_TOC[SECTOR_SIZE];
- extern const PTOC g_pTOC;
- extern DWORD g_dwTocEntry;
- extern PBOOT_CFG g_pBootCfg;
- extern BOOL g_bBootMediaExist;
- extern MultiBINInfo g_BINRegionInfo;
- extern DWORD g_dwImageStartBlock;
- extern BOOL g_bWaitForConnect;
- }
- extern DWORD g_dwLastWrittenLoc; // Defined in bootpart.lib
- #include <drv_glob.h>
- //extern PDRIVER_GLOBALS pDriverGlobals;
- PDRIVER_GLOBALS pDriverGlobals = ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START);
- #pragma pack(1)
- static UCHAR toc[SECTOR_SIZE];
- #pragma pack()
- void BootConfigPrint(void)
- {
- EdbgOutputDebugString( "BootCfg { rn");
- EdbgOutputDebugString( " ConfigFlags: 0x%xrn", g_pBootCfg->ConfigFlags);
- EdbgOutputDebugString( " BootDelay: 0x%xrn", g_pBootCfg->BootDelay);
- EdbgOutputDebugString( " ImageIndex: %d rn", g_pBootCfg->ImageIndex);
- EdbgOutputDebugString( " IP: %srn", inet_ntoa(g_pBootCfg->EdbgAddr.dwIP));
- EdbgOutputDebugString( " MAC Address: %B:%B:%B:%B:%B:%Brn",
- g_pBootCfg->EdbgAddr.wMAC[0] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[0] >> 8,
- g_pBootCfg->EdbgAddr.wMAC[1] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[1] >> 8,
- g_pBootCfg->EdbgAddr.wMAC[2] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[2] >> 8);
- EdbgOutputDebugString( " Port: %srn", inet_ntoa(g_pBootCfg->EdbgAddr.wPort));
- EdbgOutputDebugString( " SubnetMask: %srn", inet_ntoa(g_pBootCfg->SubnetMask));
- EdbgOutputDebugString( "}rn");
- }
- // Set default boot configuration values
- static void BootConfigInit(DWORD dwIndex)
- {
- #ifdef SIMULATOR
- char sMask[] = "255.255.255.255";
- #endif
- EdbgOutputDebugString("+BootConfigInitrn");
- g_pBootCfg = &g_pTOC->BootCfg;
- memset(g_pBootCfg, 0, sizeof(BOOT_CFG));
- g_pBootCfg->ImageIndex = dwIndex;
- g_pBootCfg->ConfigFlags = BOOT_TYPE_MULTISTAGE | CONFIG_FLAGS_DHCP | CONFIG_FLAGS_DEBUGGER;
- g_pBootCfg->BootDelay = CONFIG_BOOTDELAY_DEFAULT;
- #ifdef SIMULATOR
- g_pBootCfg->SubnetMask = inet_addr(sMask);
- #else
- g_pBootCfg->SubnetMask = inet_addr("255.255.255.255");
- #endif
- EdbgOutputDebugString("-BootConfigInitrn");
- return;
- }
- void ID_Print(DWORD i) {
- DWORD j;
- EdbgOutputDebugString("ID[%u] {rn", i);
- EdbgOutputDebugString(" dwVersion: 0x%xrn", g_pTOC->id[i].dwVersion);
- EdbgOutputDebugString(" dwSignature: 0x%xrn", g_pTOC->id[i].dwSignature);
- EdbgOutputDebugString(" String: '%s'rn", g_pTOC->id[i].ucString);
- EdbgOutputDebugString(" dwImageType: 0x%xrn", g_pTOC->id[i].dwImageType);
- EdbgOutputDebugString(" dwTtlSectors: 0x%xrn", g_pTOC->id[i].dwTtlSectors);
- EdbgOutputDebugString(" dwLoadAddress: 0x%xrn", g_pTOC->id[i].dwLoadAddress);
- EdbgOutputDebugString(" dwJumpAddress: 0x%xrn", g_pTOC->id[i].dwJumpAddress);
- EdbgOutputDebugString(" dwStoreOffset: 0x%xrn", g_pTOC->id[i].dwStoreOffset);
- for (j = 0; j < MAX_SG_SECTORS; j++) {
- if ( !g_pTOC->id[i].sgList[j].dwLength )
- break;
- EdbgOutputDebugString(" sgList[%u].dwSector: 0x%xrn", j, g_pTOC->id[i].sgList[j].dwSector);
- EdbgOutputDebugString(" sgList[%u].dwLength: 0x%xrn", j, g_pTOC->id[i].sgList[j].dwLength);
- }
- EdbgOutputDebugString("}rn");
- }
- void TOC_Print(void)
- {
- int i;
- EdbgOutputDebugString("TOC {rn");
- EdbgOutputDebugString("dwSignature: 0x%xrn", g_pTOC->dwSignature);
- BootConfigPrint( );
- for (i = 0; i < MAX_TOC_DESCRIPTORS; i++) {
- if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[i]) )
- break;
- ID_Print(i);
- }
- // Print out Chain Information
- EdbgOutputDebugString("chainInfo.dwLoadAddress: 0X%Xrn", g_pTOC->chainInfo.dwLoadAddress);
- EdbgOutputDebugString("chainInfo.dwFlashAddress: 0X%Xrn", g_pTOC->chainInfo.dwFlashAddress);
- EdbgOutputDebugString("chainInfo.dwLength: 0X%Xrn", g_pTOC->chainInfo.dwLength);
- // 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]);
- EdbgOutputDebugString("}rn");
- }
- // init the TOC to defaults
- BOOL TOC_Init(DWORD dwEntry, DWORD dwImageType, DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
- {
- DWORD dwSig = 0;
- EdbgOutputDebugString("TOC_Init: dwEntry:%u, dwImageType: 0x%x, dwImageStart: 0x%x, dwImageLength: 0x%x, dwLaunchAddr: 0x%xrn",
- dwEntry, dwImageType, dwImageStart, dwImageLength, dwLaunchAddr);
- if (0 == dwEntry) {
- EdbgOutputDebugString("rn*** WARNING: TOC_Init blasting Eboot ***rn");
- TEST_TRAP;
- }
- switch (dwImageType) {
- case IMAGE_TYPE_LOADER:
- dwSig = IMAGE_EBOOT_SIG;
- break;
- case IMAGE_TYPE_RAMIMAGE:
- dwSig = IMAGE_RAM_SIG;
- break;
- case (IMAGE_TYPE_RAMIMAGE|IMAGE_TYPE_BINFS):
- dwSig = IMAGE_BINFS_SIG;
- break;
- default:
- EdbgOutputDebugString("ERROR: OEMLaunch: unknown image type: 0x%x rn", dwImageType);
- return FALSE;
- }
- memset(g_pTOC, 0, sizeof(g_TOC));
- // init boof cfg
- BootConfigInit(dwEntry);
- // update our index
- g_dwTocEntry = dwEntry;
- // debugger enabled?
- g_bWaitForConnect = (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_DEBUGGER) ? TRUE : FALSE;
- // init TOC...
- //
- g_pTOC->dwSignature = TOC_SIGNATURE;
- // init TOC entry for Eboot
- // Those are hard coded numbers from boot.bib
- g_pTOC->id[0].dwVersion = (EBOOT_VERSION_MAJOR << 16) | EBOOT_VERSION_MINOR;
- g_pTOC->id[0].dwSignature = IMAGE_EBOOT_SIG;
- memcpy(g_pTOC->id[0].ucString, "eboot.nb0", sizeof("eboot.nb0")+1); // NUll terminate
- g_pTOC->id[0].dwImageType = IMAGE_TYPE_RAMIMAGE;
- g_pTOC->id[0].dwLoadAddress = EBOOT_RAM_IMAGE_BASE;
- g_pTOC->id[0].dwJumpAddress = EBOOT_RAM_IMAGE_BASE;
- g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE);
- // 1 contigious segment
- g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK);
- g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;
- // init the TOC entry
- g_pTOC->id[dwEntry].dwVersion = 0x001;
- g_pTOC->id[dwEntry].dwSignature = dwSig;
- memset(g_pTOC->id[dwEntry].ucString, 0, IMAGE_STRING_LEN);
- g_pTOC->id[dwEntry].dwImageType = dwImageType;
- g_pTOC->id[dwEntry].dwLoadAddress = dwImageStart;
- g_pTOC->id[dwEntry].dwJumpAddress = dwLaunchAddr;
- g_pTOC->id[dwEntry].dwStoreOffset = 0;
- g_pTOC->id[dwEntry].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
- // 1 contigious segment
- g_pTOC->id[dwEntry].sgList[0].dwSector = BLOCK_TO_SECTOR(g_dwImageStartBlock);
- g_pTOC->id[dwEntry].sgList[0].dwLength = g_pTOC->id[dwEntry].dwTtlSectors;
- TOC_Print();
- return TRUE;
- }
- //
- // Retrieve TOC from Nand.
- //
- BOOL TOC_Read(void)
- {
- SectorInfo si;
- EdbgOutputDebugString("TOC_Readrn");
- if ( !g_bBootMediaExist )
- {
- EdbgOutputDebugString("TOC_Read ERROR: no boot mediarn");
- return FALSE;
- }
- if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)g_pTOC, &si, 1) )
- {
- EdbgOutputDebugString("TOC_Read ERROR: Unable to read TOCrn");
- return FALSE;
- }
- // is it a valid TOC?
- if ( !VALID_TOC(g_pTOC) )
- {
- EdbgOutputDebugString("TOC_Read ERROR: INVALID_TOC Signature: 0x%xrn", g_pTOC->dwSignature);
- return FALSE;
- }
- // is it an OEM block?
- if ( (si.bBadBlock != BADBLOCKMARK) || !(si.bOEMReserved & (OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY)) )
- {
- EdbgOutputDebugString("TOC_Read ERROR: SectorInfo verify failed: %x %x %x %xrn",
- si.dwReserved1, si.bOEMReserved, si.bBadBlock, si.wReserved2);
- return FALSE;
- }
- // update our boot config
- g_pBootCfg = &g_pTOC->BootCfg;
- // update our index
- g_dwTocEntry = g_pBootCfg->ImageIndex;
- // debugger enabled?
- g_bWaitForConnect = (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_DEBUGGER) ? TRUE : FALSE;
- // cache image type
- g_ImageType = g_pTOC->id[g_dwTocEntry].dwImageType;
- TOC_Print( );
- EdbgOutputDebugString("-TOC_Readrn");
- return TRUE;
- }
- //
- // Store TOC to Nand
- // BUGBUG: only uses 1 sector for now.
- //
- BOOL TOC_Write(void)
- {
- SectorInfo si, si2;
- EdbgOutputDebugString("+TOC_Writern");
- if ( !g_bBootMediaExist ) {
- EdbgOutputDebugString("TOC_Write WARN: no boot mediarn");
- return FALSE;
- }
- // is it a valid TOC?
- if ( !VALID_TOC(g_pTOC) ) {
- EdbgOutputDebugString("TOC_Write ERROR: INVALID_TOC Signature: 0x%xrn", g_pTOC->dwSignature);
- return FALSE;
- }
- // is it a valid image descriptor?
- if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) ) {
- EdbgOutputDebugString("TOC_Write ERROR: INVALID_IMAGE[%u] Signature: 0x%xrn",
- g_dwTocEntry, g_pTOC->id[g_dwTocEntry].dwSignature);
- return FALSE;
- }
- // in order to write a sector we must erase the entire block first
- // !! BUGBUG: must cache the TOC first so we don't trash other image descriptors !!
- RETAILMSG(1, (TEXT("Erasing Block: %urn"), TOC_BLOCK));
- if ( !FMD_EraseBlock(TOC_BLOCK) ) {
- RETAILMSG(1, (TEXT("TOC_Write ERROR: EraseBlock[%d] rn"), TOC_BLOCK));
- return FALSE;
- }
- // setup our metadata so filesys won't stomp us
- si.dwReserved1 = 0;
- si.bOEMReserved = OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY;
- si.bBadBlock = BADBLOCKMARK;
- si.wReserved2 = 0;
- // write the sector & metadata
- RETAILMSG(1, (TEXT("FMD_WriteSector............. rn")));
- if ( !FMD_WriteSector(TOC_SECTOR, (PUCHAR)&g_TOC, &si, 1) ) {
- EdbgOutputDebugString("TOC_Write ERROR: Unable to save TOCrn");
- return FALSE;
- }
- // read it back & verify both data & metadata
- RETAILMSG(1, (TEXT("FMD_ReadSector............. rn")));
- if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)&toc, &si2, 1) ) {
- EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOCrn");
- return FALSE;
- }
- RETAILMSG(1, (TEXT("memcmp............. rn")));
- if ( 0 != memcmp(&g_TOC, &toc, SECTOR_SIZE) ) {
- EdbgOutputDebugString("TOC_Write ERROR: TOC verify failedrn");
- return FALSE;
- }
- if ( 0 != memcmp(&si, &si2, sizeof(si)) ) {
- EdbgOutputDebugString("TOC_Write ERROR: SectorInfo verify failed: %x %x %x %xrn",
- si.dwReserved1, si.bOEMReserved, si.bBadBlock, si.wReserved2);
- return FALSE;
- }
- TOC_Print();
- EdbgOutputDebugString("-TOC_Writern");
- return TRUE;
- }
- /*
- @func PVOID | GetKernelExtPointer | Locates the kernel region's extension area pointer.
- @rdesc Pointer to the kernel's extension area.
- @comm
- @xref
- */
- PVOID GetKernelExtPointer(DWORD dwRegionStart, DWORD dwRegionLength)
- {
- DWORD dwCacheAddress = 0;
- ROMHDR *pROMHeader;
- DWORD dwNumModules = 0;
- TOCentry *pTOC;
- if (dwRegionStart == 0 || dwRegionLength == 0)
- return(NULL);
- if (*(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE)
- return NULL;
- // A pointer to the ROMHDR structure lives just past the ROM_SIGNATURE (which is a longword value). Note that
- // this pointer is remapped since it might be a flash address (image destined for flash), but is actually cached
- // in RAM.
- //
- dwCacheAddress = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
- pROMHeader = (ROMHDR *) OEMMapMemAddr(dwRegionStart, dwCacheAddress);
- // Make sure there are some modules in the table of contents.
- //
- if ((dwNumModules = pROMHeader->nummods) == 0)
- return NULL;
- // Locate the table of contents and search for the kernel executable and the TOC immediately follows the ROMHDR.
- //
- pTOC = (TOCentry *)(pROMHeader + 1);
- while (dwNumModules--) {
- LPBYTE pFileName = OEMMapMemAddr(dwRegionStart, (DWORD)pTOC->lpszFileName);
- // EdbgOutputDebugString("GetKernelExtPointer: found module[%u]: %srn", dwNumModules, pFileName);
- if (!strcmp((const char *)pFileName, "nk.exe")) {
- return ((PVOID)(pROMHeader->pExtensions));
- }
- ++pTOC;
- }
- return NULL;
- }
- /*
- @func BOOL | WriteRegionsToBootMedia | Stores the image cached in RAM to the Boot Media.
- The image may be comprised of one or more BIN regions.
- @rdesc TRUE = Success, FALSE = Failure.
- @comm
- @xref
- */
- BOOL WriteRegionsToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
- {
- BYTE nCount;
- DWORD dwNumExts;
- PXIPCHAIN_SUMMARY pChainInfo = NULL;
- EXTENSION *pExt = NULL;
- DWORD dwBINFSPartLength = 0;
- HANDLE hPart, hPartEx;
- DWORD dwStoreOffset;
- DWORD dwMaxRegionLength[BL_MAX_BIN_REGIONS] = {0};
- DWORD dwChainStart, dwChainLength;
- // Initialize the variables
- dwChainStart = dwChainLength = 0;
- EdbgOutputDebugString("+WriteRegionsToBootMedia: ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%xrn",
- dwImageStart, dwImageLength, dwLaunchAddr);
- if ( !g_bBootMediaExist ) {
- EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: device doesn't exist.rn");
- return(FALSE);
- }
- if ( !VALID_TOC(g_pTOC) ) {
- EdbgOutputDebugString("WARN: WriteRegionsToBootMedia: INVALID_TOCrn");
- if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) {
- EdbgOutputDebugString("ERROR: INVALID_TOCrn");
- return(FALSE);
- }
- }
- if ( !(IMAGE_TYPE_BINFS & g_pTOC->id[g_dwTocEntry].dwImageType) ) {
- EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: INVALID_IMAGE_TYPE: 0x%xrn",
- g_pTOC->id[g_dwTocEntry].dwImageType);
- return(FALSE);
- }
- // Look in the kernel region's extension area for a multi-BIN extension descriptor.
- // This region, if found, details the number, start, and size of each BIN region.
- //
- //for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions) && !pChainInfo ; nCount++)
- for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions); nCount++)
- {
- // Does this region contain nk.exe and an extension pointer?
- //
- pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart,
- g_BINRegionInfo.Region[nCount].dwRegionLength );
- if ( pExt != NULL)
- {
- // If there is an extension pointer region, walk it until the end.
- //
- while (pExt)
- {
- DWORD dwBaseAddr = g_BINRegionInfo.Region[nCount].dwRegionStart;
- pExt = (EXTENSION *)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt);
- EdbgOutputDebugString("INFO: OEMLaunch: Found chain extenstion: '%s' @ 0x%xrn", pExt->name, dwBaseAddr);
- if ((pExt->type == 0) && !strcmp(pExt->name, "chain information"))
- {
- pChainInfo = (PXIPCHAIN_SUMMARY) OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata);
- dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY));
- EdbgOutputDebugString("INFO: OEMLaunch: Found 'chain information' (pChainInfo=0x%x Extensions=0x%x).rn", (DWORD)pChainInfo, dwNumExts);
- break;
- }
- pExt = (EXTENSION *)pExt->pNextExt;
- }
- }
- else {
- // Search for Chain region. Chain region doesn't have the ROMSIGNATURE set
- DWORD dwRegionStart = g_BINRegionInfo.Region[nCount].dwRegionStart;
- DWORD dwSig = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET);
- if ( dwSig != ROM_SIGNATURE) {
- // It is the chain
- dwChainStart = dwRegionStart;
- dwChainLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
- EdbgOutputDebugString("Found the Chain region: StartAddress: 0x%X; Length: 0x%Xn", dwChainStart, dwChainLength);
- }
- }
- }
- // Determine how big the Total BINFS partition needs to be to store all of this.
- //
- if (pChainInfo && dwNumExts == g_BINRegionInfo.dwNumRegions) // We're downloading all the regions in a multi-region image...
- {
- DWORD i;
- EdbgOutputDebugString("Writing multi-regionsrn");
- for (nCount = 0, dwBINFSPartLength = 0 ; nCount < dwNumExts ; nCount++)
- {
- dwBINFSPartLength += (pChainInfo + nCount)->dwMaxLength;
- EdbgOutputDebugString("BINFSPartMaxLength[%u]: 0x%x, TtlBINFSPartLength: 0x%x rn",
- nCount, (pChainInfo + nCount)->dwMaxLength, dwBINFSPartLength);
- // MultiBINInfo does not store each Regions MAX length, and pChainInfo is not in any particular order.
- // So, walk our MultiBINInfo matching up pChainInfo to find each regions MAX Length
- for (i = 0; i < dwNumExts; i++) {
- if ( g_BINRegionInfo.Region[i].dwRegionStart == (DWORD)((pChainInfo + nCount)->pvAddr) ) {
- dwMaxRegionLength[i] = (pChainInfo + nCount)->dwMaxLength;
- EdbgOutputDebugString("dwMaxRegionLength[%u]: 0x%x rn", i, dwMaxRegionLength[i]);
- break;
- }
- }
- }
- }
- else // A single BIN file or potentially a multi-region update (but the partition's already been created in this latter case).
- {
- dwBINFSPartLength = g_BINRegionInfo.Region[0].dwRegionLength;
- EdbgOutputDebugString("Writing single region/multi-region update, dwBINFSPartLength: %u rn", dwBINFSPartLength);
- }
- // Open/Create the BINFS partition where images are stored. This partition starts immediately after the MBR on the Boot Media and its length is
- // determined by the maximum image size (or sum of all maximum sizes in a multi-region design).
- // Parameters are LOGICAL sectors.
- //
- /* hPart = BP_OpenPartition( NEXT_FREE_LOC,
- FILE_TO_SECTOR_SIZE(dwBINFSPartLength) + 1, // sizeof image + MBR sector
- PART_BINFS,
- TRUE,
- PART_OPEN_ALWAYS);
- */
- hPart = BP_OpenPartition( (IMAGE_START_BLOCK+1)*PAGES_PER_BLOCK, // next block of MBR
- SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength))*PAGES_PER_BLOCK, // align to block
- PART_BINFS,
- TRUE,
- PART_OPEN_ALWAYS);
- if (hPart == INVALID_HANDLE_VALUE )
- {
- EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: Failed to open/create BINFS partition.rn");
- return(FALSE);
- }
- // Are there multiple BIN files in RAM (we may just be updating one in a multi-BIN solution)?
- //
- for (nCount = 0, dwStoreOffset = 0; nCount < g_BINRegionInfo.dwNumRegions ; nCount++)
- {
- DWORD dwRegionStart = (DWORD)OEMMapMemAddr(0, g_BINRegionInfo.Region[nCount].dwRegionStart);
- DWORD dwRegionLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
- // Media byte offset where image region is stored.
- dwStoreOffset += nCount ? dwMaxRegionLength[nCount-1] : 0;
- EdbgOutputDebugString("dwRegionStart: 0x%x, dwRegionLength: 0x%x, dwStoreOffset: 0x%xrn",
- dwRegionStart, dwRegionLength, dwStoreOffset);
- // Set the file pointer (byte indexing) to the correct offset for this particular region.
- //
- if ( !BP_SetDataPointer(hPart, dwStoreOffset) )
- {
- EdbgOutputDebugString("ERROR: StoreImageToBootMedia: Failed to set data pointer in BINFS partition (offset=0x%x).rn", dwStoreOffset);
- return(FALSE);
- }
- // Write the region to the BINFS partition.
- //
- if ( !BP_WriteData(hPart, (LPBYTE)dwRegionStart, dwRegionLength) )
- {
- EdbgOutputDebugString("ERROR: StoreImageToBootMedia: Failed to write region to BINFS partition (start=0x%x, length=0x%x).rn", dwRegionStart, dwRegionLength);
- return(FALSE);
- }
- // update our TOC?
- //
- if ((g_pTOC->id[g_dwTocEntry].dwLoadAddress == g_BINRegionInfo.Region[nCount].dwRegionStart) &&
- g_pTOC->id[g_dwTocEntry].dwTtlSectors == FILE_TO_SECTOR_SIZE(dwRegionLength) )
- {
- g_pTOC->id[g_dwTocEntry].dwStoreOffset = dwStoreOffset;
- g_pTOC->id[g_dwTocEntry].dwJumpAddress = 0; // Filled upon return to OEMLaunch
- g_pTOC->id[g_dwTocEntry].dwImageType = g_ImageType;
- g_pTOC->id[g_dwTocEntry].sgList[0].dwSector = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
- g_pTOC->id[g_dwTocEntry].sgList[0].dwLength = g_pTOC->id[g_dwTocEntry].dwTtlSectors;
- // copy Kernel Region to SDRAM for jump
- memcpy((void*)g_pTOC->id[g_dwTocEntry].dwLoadAddress, (void*)dwRegionStart, dwRegionLength);
- EdbgOutputDebugString("Updateded TOC!rn");
- }
- else if( (dwChainStart == g_BINRegionInfo.Region[nCount].dwRegionStart) &&
- (dwChainLength == g_BINRegionInfo.Region[nCount].dwRegionLength))
- {
- // Update our TOC for Chain region
- g_pTOC->chainInfo.dwLoadAddress = dwChainStart;
- g_pTOC->chainInfo.dwFlashAddress = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
- g_pTOC->chainInfo.dwLength = FILE_TO_SECTOR_SIZE(dwMaxRegionLength[nCount]);
- EdbgOutputDebugString("Written Chain Region to the Flashn");
- EdbgOutputDebugString("LoadAddress = 0x%X; FlashAddress = 0x%X; Length = 0x%Xn",
- g_pTOC->chainInfo.dwLoadAddress,
- g_pTOC->chainInfo.dwFlashAddress,
- g_pTOC->chainInfo.dwLength);
- // Now copy it to the SDRAM
- memcpy((void *)g_pTOC->chainInfo.dwLoadAddress, (void *)dwRegionStart, dwRegionLength);
- // memcpy((void *)0x8c050000, (void *)dwRegionStart, dwRegionLength);
- }
- }
- // create extended partition in whatever is left
- //
- hPartEx = BP_OpenPartition( NEXT_FREE_LOC,
- USE_REMAINING_SPACE,
- PART_DOS32,
- TRUE,
- PART_OPEN_ALWAYS);
- if (hPartEx == INVALID_HANDLE_VALUE )
- {
- EdbgOutputDebugString("*** WARN: StoreImageToBootMedia: Failed to open/create Extended partition ***rn");
- }
- EdbgOutputDebugString("-WriteRegionsToBootMediarn");
- return(TRUE);
- }
- /*
- @func BOOL | ReadKernelRegionFromBootMedia |
- BinFS support. Reads the kernel region from Boot Media into RAM. The kernel region is fixed up
- to run from RAM and this is done just before jumping to the kernel entry point.
- @rdesc TRUE = Success, FALSE = Failure.
- @comm
- @xref
- */
- BOOL ReadKernelRegionFromBootMedia( )
- {
- HANDLE hPart;
- SectorInfo si;
- DWORD chainaddr, flashaddr;
- int i;
- if (!g_bBootMediaExist) {
- EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: device doesn't exist.rn");
- return(FALSE);
- }
- if ( !VALID_TOC(g_pTOC) ) {
- EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: INVALID_TOCrn");
- return(FALSE);
- }
- if ( !(IMAGE_TYPE_BINFS & g_pTOC->id[g_dwTocEntry].dwImageType) ) {
- EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: INVALID_IMAGE_TYPE: 0x%xrn",
- g_pTOC->id[g_dwTocEntry].dwImageType);
- return(FALSE);
- }
- if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) ) {
- EdbgOutputDebugString("OEMPlatformInit: ERROR_INVALID_IMAGE_DESCRIPTOR: 0x%xrn",
- g_pTOC->id[g_dwTocEntry].dwSignature);
- return FALSE;
- }
- if ( !OEMVerifyMemory(g_pTOC->id[g_dwTocEntry].dwLoadAddress, sizeof(DWORD)) ||
- !OEMVerifyMemory(g_pTOC->id[g_dwTocEntry].dwJumpAddress, sizeof(DWORD)) ||
- !g_pTOC->id[g_dwTocEntry].dwTtlSectors )
- {
- EdbgOutputDebugString("OEMPlatformInit: ERROR_INVALID_ADDRESS: (address=0x%x, sectors=0x%x, launch address=0x%x)...rn",
- g_pTOC->id[g_dwTocEntry].dwLoadAddress, g_pTOC->id[g_dwTocEntry].dwTtlSectors, g_pTOC->id[g_dwTocEntry].dwJumpAddress);
- return FALSE;
- }
- EdbgOutputDebugString("INFO: Loading image from Boot Media to RAM (address=0x%x, sectors=0x%x, launch address=0x%x)...rn",
- g_pTOC->id[g_dwTocEntry].dwLoadAddress, g_pTOC->id[g_dwTocEntry].dwTtlSectors, g_pTOC->id[g_dwTocEntry].dwJumpAddress);
- // Open the BINFS partition (it must exist).
- //
- hPart = BP_OpenPartition( NEXT_FREE_LOC,
- USE_REMAINING_SPACE,
- PART_BINFS,
- TRUE,
- PART_OPEN_EXISTING);
- if (hPart == INVALID_HANDLE_VALUE )
- {
- EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to open existing BINFS partition.rn");
- return(FALSE);
- }
- // Set the partition file pointer to the correct offset for the kernel region.
- //
- if ( !BP_SetDataPointer(hPart, g_pTOC->id[g_dwTocEntry].dwStoreOffset) )
- {
- EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to set data pointer in BINFS partition (offset=0x%x).rn",
- g_pTOC->id[g_dwTocEntry].dwStoreOffset);
- return(FALSE);
- }
- // Read the kernel region from the Boot Media into RAM.
- //
- if ( !BP_ReadData( hPart,
- (LPBYTE)(g_pTOC->id[g_dwTocEntry].dwLoadAddress),
- SECTOR_TO_FILE_SIZE(g_pTOC->id[g_dwTocEntry].dwTtlSectors)) )
- {
- EdbgOutputDebugString("ERROR: ReadKernelRegionFromBootMedia: Failed to read kernel region from BINFS partition.rn");
- return(FALSE);
- }
- EdbgOutputDebugString("g_pTOC->chainInfo.dwLength=0x%xrn", g_pTOC->chainInfo.dwLength);
- chainaddr = g_pTOC->chainInfo.dwLoadAddress;
- flashaddr = g_pTOC->chainInfo.dwFlashAddress;
- for ( i = 0; i < (g_pTOC->chainInfo.dwLength); i++ )
- {
- EdbgOutputDebugString("chainaddr=0x%x, flashaddr=0x%xrn", chainaddr, flashaddr+i);
- if ( !FMD_ReadSector(flashaddr+i, (PUCHAR)(chainaddr), &si, 1) ) {
- EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOCrn");
- return FALSE;
- }
- chainaddr += 512;
- }
- {
- int i;
- for ( i = 0; i < 60; i++ )
- EdbgOutputDebugString("[0x%x]0x%x ", g_pTOC->chainInfo.dwLoadAddress + i, *(LPBYTE)(g_pTOC->chainInfo.dwLoadAddress + i));
- }
- return(TRUE);
- }
- BOOL ReadRamImageFromBootMedia( )
- {
- DWORD dwSectorsNeeded;
- DWORD dwSector, dwLength; // Start Sector & Length
- DWORD dwLoadAddress, dwJumpAddr, i;
- if ( !TOC_Read( ) ) { // should already be read
- return FALSE;
- }
- // is this a RAM image?
- // N.B: we can't read BinFS regions because we don' know where they are in g_pTOC->id[dwEntry].sgList[i].dwSector
- if ( g_pTOC->id[g_dwTocEntry].dwImageType != IMAGE_TYPE_RAMIMAGE ) {
- EdbgOutputDebugString("ReadRamImageFromBootMedia ERROR: TOC[%u] not a RAM image: 0x%xrn",
- g_dwTocEntry, g_pTOC->id[g_dwTocEntry].dwImageType);
- return FALSE;
- }
- dwSectorsNeeded = g_pTOC->id[g_dwTocEntry].dwTtlSectors;
- dwLoadAddress = g_pTOC->id[g_dwTocEntry].dwLoadAddress;
- dwJumpAddr = g_pTOC->id[g_dwTocEntry].dwJumpAddress ? g_pTOC->id[g_dwTocEntry].dwJumpAddress :
- g_pTOC->id[g_dwTocEntry].dwLoadAddress;
- EdbgOutputDebugString("dwSectorsNeeded: 0x%x, dwLoadAddress: 0x%x, dwJumpAddr: 0x%xrn",
- dwSectorsNeeded, dwLoadAddress, dwJumpAddr);
- //
- // Load the disk image directly into RAM
- // BUGBUG: recover from read failures
- //
- i = 0;
- while (dwSectorsNeeded && i < MAX_SG_SECTORS)
- {
- dwSector = g_pTOC->id[g_dwTocEntry].sgList[i].dwSector;
- dwLength = g_pTOC->id[g_dwTocEntry].sgList[i].dwLength;
- // read each sg segment
- while (dwLength) {
- if ( !FMD_ReadSector(dwSector, (LPBYTE)dwLoadAddress, NULL, 1) ) {
- EdbgOutputDebugString("ReadRamImageFromBootMedia ERROR reading sector: 0x%xrn", dwSector);
- return FALSE;
- }
- dwSector++;
- dwLength--;
- dwLoadAddress += SECTOR_SIZE;
- }
- dwSectorsNeeded -= dwLength;
- i++;
- }
- return TRUE;
- }
- BOOL WriteRamImageToBootMedia(DWORD dwEntry)
- {
- EdbgOutputDebugString("*** ERROR: WriteRamImageToBootMedia: NOT IMPLEMENTED *** rn");
- return FALSE;
- }