/* @func BOOL | OEMWriteFlash | Writes data to flash (the source location is determined using OEMMapMemAddr). @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL OEMWriteFlash(DWORD dwStartAddr, DWORD dwLength) { BOOL rc; EdbgOutputDebugString("OEMWriteFlash 0x%x 0x%x\r\n", dwStartAddr, dwLength); EdbgOutputDebugString("OEMWriteFlash 0x%x \r\n", g_ImageType); switch (g_ImageType) { case IMAGE_TYPE_DIONB0: rc = TRUE; break; case IMAGE_TYPE_FLASHBIN: // rc = WriteFlashNK(dwStartAddr, dwLength); rc = TRUE; break; case IMAGE_TYPE_STEPLDR: rc = TRUE; break; case IMAGE_TYPE_LOADER: rc = TRUE; break; default: rc = FALSE; } return rc; // return(TRUE); }
// // Retrieve TOC from Nand. // BOOL TOC_Read(void) { SectorInfo si; unsigned char tbuf[2048]; // EdbgOutputDebugString("+TOC_Read\r\n"); if ( !g_bBootMediaExist ) { EdbgOutputDebugString("TOC_Read ERROR: no boot media\r\n"); return FALSE; } // EdbgOutputDebugString("FMD_ReadSector\r\n"); if ( !FMD_ReadSector(TOC_SECTOR, tbuf, &si, 1) ) { EdbgOutputDebugString("TOC_Read ERROR: Unable to read TOC\r\n"); return FALSE; } memcpy(g_pTOC, tbuf, sizeof(g_TOC)); // EdbgOutputDebugString("VALID_TOC\r\n"); // is it a valid TOC? if ( !VALID_TOC(g_pTOC) ) { EdbgOutputDebugString("TOC_Read ERROR: INVALID_TOC Signature: 0x%x\r\n", 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 %x\r\n", si.dwReserved1, si.bOEMReserved, si.bBadBlock, si.wReserved2); return FALSE; } // update our boot config g_pBootCfg = &g_pTOC->BootCfg; pBSPArgs->Device_ID[0]=g_pBootCfg->Device_ID[0]; pBSPArgs->Device_ID[1]=g_pBootCfg->Device_ID[1]; pBSPArgs->Device_ID[2]=g_pBootCfg->Device_ID[2]; pBSPArgs->Device_ID[3]=g_pBootCfg->Device_ID[3]; // update our index g_dwTocEntry = g_pBootCfg->ImageIndex; // cache image type g_ImageType = g_pTOC->id[g_dwTocEntry].dwImageType; // EdbgOutputDebugString("-TOC_Read\r\n"); return TRUE; }
// // Retrieve TOC from Nand. // BOOL TOC_Read(void) { SectorInfo si; //EdbgOutputDebugString("TOC_Read\r\n"); if ( !g_bBootMediaExist ) { EdbgOutputDebugString("TOC_Read ERROR: no boot media\r\n"); return FALSE; } if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)g_pTOC, &si, 1) ) { EdbgOutputDebugString("TOC_Read ERROR: Unable to read TOC\r\n"); return FALSE; } // is it a valid TOC? if ( !VALID_TOC(g_pTOC) ) { EdbgOutputDebugString("TOC_Read ERROR: INVALID_TOC Signature: 0x%x\r\n", 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 %x\r\n", 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; // KITL enabled? g_bWaitForConnect = (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_KITL) ? TRUE : FALSE; // cache image type g_ImageType = g_pTOC->id[g_dwTocEntry].dwImageType; //EdbgOutputDebugString("-TOC_Read\r\n"); return TRUE; }
// Set default boot configuration values static void BootConfigInit(DWORD dwIndex) { EdbgOutputDebugString("+BootConfigInit\r\n"); g_pBootCfg = &g_pTOC->BootCfg; memset(g_pBootCfg, 0, sizeof(BOOT_CFG)); g_pBootCfg->ImageIndex = dwIndex; g_pBootCfg->ConfigFlags = BOOT_TYPE_MULTISTAGE | CONFIG_FLAGS_DEBUGGER; g_pBootCfg->BootDelay = CONFIG_BOOTDELAY_DEFAULT; g_pBootCfg->SubnetMask = inet_addr("255.255.255.0"); EdbgOutputDebugString("-BootConfigInit\r\n"); return; }
void BootConfigPrint(void) { EdbgOutputDebugString( "BootCfg { \r\n"); EdbgOutputDebugString( " ConfigFlags: 0x%x\r\n", g_pBootCfg->ConfigFlags); EdbgOutputDebugString( " BootDelay: 0x%x\r\n", g_pBootCfg->BootDelay); EdbgOutputDebugString( " ImageIndex: %d \r\n", g_pBootCfg->ImageIndex); EdbgOutputDebugString( " IP: %s\r\n", inet_ntoa(g_pBootCfg->EdbgAddr.dwIP)); EdbgOutputDebugString( " MAC Address: %B:%B:%B:%B:%B:%B\r\n", 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: %s\r\n", inet_ntoa(g_pBootCfg->EdbgAddr.wPort)); EdbgOutputDebugString( " SubnetMask: %s\r\n", inet_ntoa(g_pBootCfg->SubnetMask)); EdbgOutputDebugString("\r\nDeviceID %x %x %x %x : ",g_pBootCfg->Device_ID[0],g_pBootCfg->Device_ID[1],g_pBootCfg->Device_ID[2],g_pBootCfg->Device_ID[3]); EdbgOutputDebugString( "}\r\n"); }
/* @func BOOL | OEMEthSendFrame | Writes data to an Ethernet device. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL OEMEthSendFrame(PUCHAR pData, DWORD dwLength) { BYTE Retries = 0; while (Retries++ < 4) { if (!pfnEDbgSendFrame(pData, dwLength)) return(TRUE); EdbgOutputDebugString("INFO: OEMEthSendFrame: retrying send (%u)\r\n", Retries); } return(FALSE); }
BOOL ConfirmProcess(const char *msg) { BYTE KeySelect = 0; EdbgOutputDebugString ( msg); while (! ( ( (KeySelect == 'Y') || (KeySelect == 'y') ) || ( (KeySelect == 'N') || (KeySelect == 'n') ) )) { KeySelect = OEMReadDebugByte(); } if(KeySelect == 'Y' || KeySelect == 'y') { return TRUE; } return FALSE; }
unsigned char getChar() { unsigned char KeySelect = 0; while (! ( ( (KeySelect == ';') || (KeySelect == ':' ) ) || ( (KeySelect == '+') || (KeySelect == '-' ) ) || ( (KeySelect == 27) || (KeySelect == 8 ) ) || ( (KeySelect >= '0') && (KeySelect <= '9') ) || ( (KeySelect == 'A') || (KeySelect == 'a') ) || ( (KeySelect == 'B') || (KeySelect == 'b') ) || ( (KeySelect == 'C') || (KeySelect == 'c') ) || ( (KeySelect == 'D') || (KeySelect == 'd') ) || ( (KeySelect == 'E') || (KeySelect == 'e') ) || ( (KeySelect == 'F') || (KeySelect == 'f') ) || ( (KeySelect == 'G') || (KeySelect == 'g') ) || ( (KeySelect == 'H') || (KeySelect == 'h') ) || ( (KeySelect == 'I') || (KeySelect == 'i') ) || ( (KeySelect == 'J') || (KeySelect == 'j') ) || ( (KeySelect == 'K') || (KeySelect == 'k') ) || ( (KeySelect == 'L') || (KeySelect == 'l') ) || ( (KeySelect == 'M') || (KeySelect == 'm') ) || ( (KeySelect == 'N') || (KeySelect == 'n') ) || ( (KeySelect == 'O') || (KeySelect == 'o') ) || ( (KeySelect == 'P') || (KeySelect == 'p') ) || ( (KeySelect == 'Q') || (KeySelect == 'q') ) || ( (KeySelect == 'R') || (KeySelect == 'r') ) || ( (KeySelect == 'S') || (KeySelect == 's') ) || ( (KeySelect == 'T') || (KeySelect == 't') ) || ( (KeySelect == 'U') || (KeySelect == 'u') ) || ( (KeySelect == 'V') || (KeySelect == 'v') ) || ( (KeySelect == 'W') || (KeySelect == 'w') ) || ( (KeySelect == 'X') || (KeySelect == 'x') ) || ( (KeySelect == 'Y') || (KeySelect == 'y') ) || ( (KeySelect == 'Z') || (KeySelect == 'z') ) )) { KeySelect = OEMReadDebugByte(); } EdbgOutputDebugString ( "%c\r\n", KeySelect); return toUpper(KeySelect); }
/* @func BOOL | OEMEthSendFrame | Writes data to an Ethernet device. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL OEMEthSendFrame(PUCHAR pData, DWORD dwLength) { BYTE Retries = 0; switch(g_pBootCfg->BootDevice) { case BOOT_DEVICE_ETHERNET: while (Retries++ < 4) { if (!pfnEDbgSendFrame(pData, dwLength)) return(TRUE); EdbgOutputDebugString("INFO: OEMEthSendFrame: retrying send (%u)\r\n", Retries); } break; case BOOT_DEVICE_USB_RNDIS: return(ERROR_SUCCESS == Rndis_SendFrame(pData, dwLength)); break; } return(FALSE); }
void TOC_Print(void) { int i; EdbgOutputDebugString("TOC {\r\n"); EdbgOutputDebugString("dwSignature: 0x%x\r\n", 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%X\r\n", g_pTOC->chainInfo.dwLoadAddress); EdbgOutputDebugString("chainInfo.dwFlashAddress: 0X%X\r\n", g_pTOC->chainInfo.dwFlashAddress); EdbgOutputDebugString("chainInfo.dwLength: 0X%X\r\n", g_pTOC->chainInfo.dwLength); EdbgOutputDebugString("}\r\n"); }
void ID_Print(DWORD i) { DWORD j; EdbgOutputDebugString("ID[%u] {\r\n", i); EdbgOutputDebugString(" dwVersion: 0x%x\r\n", g_pTOC->id[i].dwVersion); EdbgOutputDebugString(" dwSignature: 0x%x\r\n", g_pTOC->id[i].dwSignature); EdbgOutputDebugString(" String: '%s'\r\n", g_pTOC->id[i].ucString); EdbgOutputDebugString(" dwImageType: 0x%x\r\n", g_pTOC->id[i].dwImageType); EdbgOutputDebugString(" dwTtlSectors: 0x%x\r\n", g_pTOC->id[i].dwTtlSectors); EdbgOutputDebugString(" dwLoadAddress: 0x%x\r\n", g_pTOC->id[i].dwLoadAddress); EdbgOutputDebugString(" dwJumpAddress: 0x%x\r\n", g_pTOC->id[i].dwJumpAddress); EdbgOutputDebugString(" dwStoreOffset: 0x%x\r\n", 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%x\r\n", j, g_pTOC->id[i].sgList[j].dwSector); EdbgOutputDebugString(" sgList[%u].dwLength: 0x%x\r\n", j, g_pTOC->id[i].sgList[j].dwLength); } EdbgOutputDebugString("}\r\n"); }
/* @func BOOL | WriteOSImageToBootMedia | 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 WriteOSImageToBootMedia(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; OALMSG(OAL_FUNC, (TEXT("+WriteOSImageToBootMedia\r\n"))); OALMSG(OAL_INFO, (TEXT("+WriteOSImageToBootMedia: g_dwTocEntry =%d, ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%x\r\n"), g_dwTocEntry, dwImageStart, dwImageLength, dwLaunchAddr)); if ( !g_bBootMediaExist ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_WARN, (TEXT("WARN: WriteOSImageToBootMedia: INVALID_TOC\r\n"))); if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: INVALID_TOC\r\n"))); 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); 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); OALMSG(OAL_INFO, (TEXT("INFO: OEMLaunch: Found chain extenstion: '%s' @ 0x%x\r\n"), 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)); OALMSG(OAL_INFO, (TEXT("INFO: OEMLaunch: Found 'chain information' (pChainInfo=0x%x Extensions=0x%x).\r\n"), (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; OALMSG(TRUE, (TEXT("Found the Chain region: StartAddress: 0x%X; Length: 0x%X\n"), 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; OALMSG(TRUE, (TEXT("Writing multi-regions\r\n"))); for (nCount = 0, dwBINFSPartLength = 0 ; nCount < dwNumExts ; nCount++) { dwBINFSPartLength += (pChainInfo + nCount)->dwMaxLength; OALMSG(OAL_ERROR, (TEXT("BINFSPartMaxLength[%u]: 0x%x, TtlBINFSPartLength: 0x%x \r\n"), 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; OALMSG(TRUE, (TEXT("dwMaxRegionLength[%u]: 0x%x \r\n"), 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; OALMSG(TRUE, (TEXT("Writing single region/multi-region update, dwBINFSPartLength: %u \r\n"), 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( (IMAGE_START_BLOCK)*PAGES_PER_BLOCK, // MBR block 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 ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: Failed to open/create partition.\r\n"))); 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; // Set the file pointer (byte indexing) to the correct offset for this particular region. // if ( !BP_SetDataPointer(hPart, dwStoreOffset) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: StoreImageToBootMedia: Failed to set data pointer in partition (offset=0x%x).\r\n"), 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).\r\n", dwRegionStart, dwRegionLength); return(FALSE); } RETAILMSG(TRUE, (TEXT("g_pTOC->id[g_dwTocEntry].dwLoadAddress = 0x%x \r\n"), g_pTOC->id[g_dwTocEntry].dwLoadAddress)); RETAILMSG(TRUE, (TEXT("g_BINRegionInfo.Region[nCount].dwRegionStart = 0x%x \r\n"), g_BINRegionInfo.Region[nCount].dwRegionStart)); RETAILMSG(TRUE, (TEXT("g_pTOC->id[g_dwTocEntry].dwTtlSectors = 0x%x \r\n"), g_pTOC->id[g_dwTocEntry].dwTtlSectors)); RETAILMSG(TRUE, (TEXT("FILE_TO_SECTOR_SIZE(dwRegionLength) = 0x%x \r\n"), FILE_TO_SECTOR_SIZE(dwRegionLength))); // 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) ) { OALMSG(TRUE, (TEXT("if \r\n"))); 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); OALMSG(TRUE, (TEXT("Updateded TOC!\r\n"))); } else if( (dwChainStart == g_BINRegionInfo.Region[nCount].dwRegionStart) && (dwChainLength == g_BINRegionInfo.Region[nCount].dwRegionLength)) { OALMSG(TRUE, (TEXT("else if \r\n"))); // 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]); OALMSG(TRUE, (TEXT("Written Chain Region to the Flash\n"))); OALMSG(TRUE, (TEXT("LoadAddress = 0x%X; FlashAddress = 0x%X; Length = 0x%X\n"), 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); } OALMSG(TRUE, (TEXT("pass \r\n"))); } // 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 ) { OALMSG(OAL_WARN, (TEXT("*** WARN: StoreImageToBootMedia: Failed to open/create Extended partition ***\r\n"))); } OALMSG(OAL_FUNC, (TEXT("-WriteOSImageToBootMedia\r\n"))); return(TRUE); }
// // Store TOC to Nand // BUGBUG: only uses 1 sector for now. // BOOL TOC_Write(void) { SectorInfo si, si2; EdbgOutputDebugString("+TOC_Write\r\n"); if ( !g_bBootMediaExist ) { EdbgOutputDebugString("TOC_Write WARN: no boot media\r\n"); return FALSE; } // is it a valid TOC? if ( !VALID_TOC(g_pTOC) ) { EdbgOutputDebugString("TOC_Write ERROR: INVALID_TOC Signature: 0x%x\r\n", 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%x\r\n", 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 !! if ( !FMD_EraseBlock(TOC_BLOCK) ) { RETAILMSG(1, (TEXT("TOC_Write ERROR: EraseBlock[%d] \r\n"), 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 if ( !FMD_WriteSector(TOC_SECTOR, (PUCHAR)&g_TOC, &si, 1) ) { EdbgOutputDebugString("TOC_Write ERROR: Unable to save TOC\r\n"); return FALSE; } // read it back & verify both data & metadata if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)&toc, &si2, 1) ) { EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOC\r\n"); return FALSE; } if ( 0 != memcmp(&g_TOC, &toc, SECTOR_SIZE) ) { EdbgOutputDebugString("TOC_Write ERROR: TOC verify failed\r\n"); return FALSE; } if ( 0 != memcmp(&si, &si2, sizeof(si)) ) { EdbgOutputDebugString("TOC_Write ERROR: SectorInfo verify failed: %x %x %x %x\r\n", si.dwReserved1, si.bOEMReserved, si.bBadBlock, si.wReserved2); return FALSE; } EdbgOutputDebugString("-TOC_Write\r\n"); return TRUE; }
// 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%x\r\n", dwEntry, dwImageType, dwImageStart, dwImageLength, dwLaunchAddr); if (0 == dwEntry) { EdbgOutputDebugString("\r\n*** WARNING: TOC_Init blasting Eboot ***\r\n"); return FALSE; } switch (dwImageType) { case IMAGE_TYPE_LOADER: dwSig = IMAGE_EBOOT_SIG; break; case IMAGE_TYPE_RAMIMAGE: dwSig = IMAGE_RAM_SIG; break; default: EdbgOutputDebugString("ERROR: OEMLaunch: unknown image type: 0x%x \r\n", dwImageType); return FALSE; } memset(g_pTOC, 0, sizeof(g_TOC)); // init boof cfg BootConfigInit(dwEntry); // update our index g_dwTocEntry = dwEntry; // 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; }