static int writeBlock( buffer_t * buf ) { Message msg; int result; memset( &msg, 0, sizeof(msg) ); // 目标驱动 msg.ThreadId = buf->device->thread; // 扇区操作 msg.Command = Device_WriteSector; // 设备ID msg.Arguments[0] = buf->device->devID; // 扇区号 msg.Arguments[1] = BLOCK_TO_SECTOR(buf->block); // 扇区数 msg.Arguments[2] = BLOCK_TO_SECTOR(1); // 数据内容 msg.Large[0] = (size_t)buf->data; // 发送请求 result = Api_Send( &msg, 0 ); if( result < 0 ) return -ERR_UNKNOWN; result = Api_Receive( &msg, INFINITE ); if( result < 0 ){ printf("[vfs]receive message failed. \n"); return result; } if( msg.Code < 0 ){ printf("[vfs]write buffer failed. The device %d has a problem.\n", buf->device->devID); return msg.Code; } return 0; }
// Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD BOOL FlashIsRealBadBlock(DWORD block) { SectorInfo si; FMD_ReadSector(BLOCK_TO_SECTOR(block), NULL, &si, 1); RETAILMSG(1,(TEXT("=FlashIsRealBadBlock:[%d] %x %x \r\n"),block,si.bBadBlock,si.bOEMReserved)); // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == 0x0) && (si.bOEMReserved != 0xfc )&&block!=0) return TRUE; return FALSE; }
void ReserveLoaderArea() { DWORD block, sector; DWORD startsector=0; SectorInfo si; RETAILMSG(0,(L"+FlashReserveLoaderArea \r\n")); #ifdef IROMBOOT startsector=(STEPLDR_LENGTH/SECTOR_SIZE); OALMSG(TRUE, (TEXT("SECTOR_SIZE : 0x%x ...\r\n"), SECTOR_SIZE)); #endif // to keep bootpart off of our reserved blocks we must mark it as bad, reserved & read-only si.bOEMReserved = ~(OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY); si.bBadBlock = BADBLOCKMARK; si.dwReserved1 = 0xffffffff; si.wReserved2 = 0xffff; OALMSG(TRUE, (TEXT("Reserving Blocks [0x%x - 0x%x] ...\r\n"), 0, IMAGE_START_BLOCK-1)); for(block = 0; block < IMAGE_START_BLOCK; block++) { if( FlashIsRealBadBlock(block) ) RETAILMSG(1,(TEXT(" ..0x%x block is bad -- NOT ERASED\r\n"),block)); else { RETAILMSG(1,(TEXT(" ..0x%x block is reserved\r\n"),block)); //if(block!=0) // startsector=0; // for( sector = startsector; sector < g_FlashInfo.wSectorsPerBlock; sector++){ // FMD_WriteSector(block * g_FlashInfo.wSectorsPerBlock + sector, NULL, &si, 1); FMD_WriteSector(BLOCK_TO_SECTOR(block), NULL, &si, 1); //} } } OALMSG(TRUE, (TEXT("...reserve complete.\r\n"))); RETAILMSG(0,(L"-FlashReserveLoaderArea \r\n")); }
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) { DWORD dwBlock = 0; DWORD dwNumBlocks = 0; LPBYTE pbBuffer; SectorInfo si; //unsigned int sectorchk; unsigned int sectorcnt = 0; unsigned int areachange = 0; OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n"))); if ( !g_bBootMediaExist ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if(dwLaunchAddr==0x10) { dwBlock = LOGO_BLOCK; //dwImageLength = UPLDR_RAM_IMAGE_SIZE; g_ImageType=IMAGE_TYPE_RAWBIN; }else{ if (g_ImageType == IMAGE_TYPE_LOADER) { dwBlock = EBOOT_BLOCK; if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: 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); } } } else if (g_ImageType == IMAGE_TYPE_STEPLDR) { dwBlock = STEPLDR_BLOCK; dwImageStart += dwLaunchAddr; //dwImageLength = 0x2050; //step loader can support 8k bytes. //dwImageLength = STEPLDR_RAM_IMAGE_SIZE; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } else if (g_ImageType == IMAGE_TYPE_DIONB0) { dwBlock = DIONB0_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength -= (dwImageLength / (g_FlashInfo.wDataBytesPerSector + 8))*8; } else if (g_ImageType == IMAGE_TYPE_UPLDR) { dwBlock = UPLDR_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength = UPLDR_RAM_IMAGE_SIZE; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } else if (g_ImageType == IMAGE_TYPE_FLASHBIN) { dwBlock = FLASHBIN_BLOCK; // dwImageStart += dwLaunchAddr; // dwImageLength = dwImageLength; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } } if(dwLaunchAddr==0x10) pbBuffer=(LPBYTE)dwImageStart; else pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart); // Compute number of blocks. dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0); OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength)); OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks)); while (dwNumBlocks--) { // If the block is marked bad, skip to next block. Note that the assumption in our error checking // is that any truely bad block will be marked either by the factory during production or will be marked // during the erase and write verification phases. If anything other than a bad block fails ECC correction // in this routine, it's fatal. OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock)); OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock)); OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock)); if (!FMD_EraseBlock(dwBlock)) { OALMSG(TRUE, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } // FMD_GetBlockStatus(dwBlock); if ((FMD_GetBlockStatus(dwBlock) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))&&dwBlock!=0) { OALMSG(TRUE, (TEXT("FMD_GetBlockStatus Error \r\n"))); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } //FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1); if (!FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1)) { OALMSG(TRUE, (TEXT("FMD_ReadSector : Failed to get block(0x%x)'s sector info.\r\n"), dwBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=0xfc )&&dwBlock!=0) { OALMSG(TRUE, (TEXT("si.bBadBlock failed, si.bOEMReserved %x,si.bBadBlock %x.\r\n"),si.bOEMReserved, si.bBadBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) { OALMSG(TRUE, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock)); return(FALSE); } if (g_ImageType == IMAGE_TYPE_DIONB0) { for ( int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector ++ ) { if (!WritePage(dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, pbBuffer, (PSectorInfo)(pbBuffer+g_FlashInfo.wDataBytesPerSector) )) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } pbBuffer += (g_FlashInfo.wDataBytesPerSector + 8); } ++dwBlock; } else if (g_ImageType == IMAGE_TYPE_FLASHBIN) { for ( int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector ++ ) { //RETAILMSG(1, (TEXT("WriteData: (0x%x)(0x%x,0x%x,0x%x).\r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, g_pSectorInfoBuf->dwReserved1, g_pSectorInfoBuf->bOEMReserved, g_pSectorInfoBuf->wReserved2)); if (!WritePage(dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, pbBuffer, (PSectorInfo)(pbBuffer+g_FlashInfo.wDataBytesPerSector) )) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); #ifdef IROMBOOT FMD_EraseBlock(dwBlock); // this block is actually considered to bad block. // because it may be erased initial bad block information. si.bOEMReserved = 0xff; si.bBadBlock = BADBLOCKMARK; si.dwReserved1 = 0xffffffff; si.wReserved2 = 0xffff; FMD_WriteSector(BLOCK_TO_SECTOR(dwBlock), NULL, &si, 1); pbBuffer -= (g_FlashInfo.wDataBytesPerSector + 8)*iSector; iSector = 0; break; #else return(FALSE); #endif // !IROMBOOT } pbBuffer += (g_FlashInfo.wDataBytesPerSector + 8); } ++dwBlock; } else { OALMSG(TRUE, (TEXT(" Write Reserved Area \n"))); if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } ++dwBlock; OALMSG(TRUE, (TEXT("pbBuffer + %x .\r\n"), SECTOR_SIZE/*SECTORS_PER_PAGE*/*PAGES_PER_BLOCK)); #ifdef IROMBOOT pbBuffer += (SECTOR_SIZE/*SECTORS_PER_PAGE*/*PAGES_PER_BLOCK); #else pbBuffer += 0x4000; #endif // !IROMBOOT } } if (g_ImageType == IMAGE_TYPE_LOADER) { g_pTOC->id[0].dwLoadAddress = dwImageStart; g_pTOC->id[0].dwJumpAddress = 0; g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength); g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK); g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors; } OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\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; }
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) { DWORD dwBlock,dwNumBlocks; LPBYTE pbBuffer; SectorInfo si; OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n"))); if ( !g_bBootMediaExist ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if (g_ImageType == IMAGE_TYPE_LOADER) { dwBlock = EBOOT_BLOCK; if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: 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); } } } else if (g_ImageType == IMAGE_TYPE_STEPLDR) { dwBlock = NBOOT_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength = STEPPINGSTONE_SIZE; //step loader can support 8k bytes. } pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart); // Compute number of blocks. //dwNumBlocks = (dwImageLength / 0x4000) + 1; dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0); OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength)); OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks)); while (dwNumBlocks--) { // If the block is marked bad, skip to next block. Note that the assumption in our error checking // is that any truely bad block will be marked either by the factory during production or will be marked // during the erase and write verification phases. If anything other than a bad block fails ECC correction // in this routine, it's fatal. OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock)); OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock)); OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock)); FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1); // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == BADBLOCKMARK) && (si.bOEMReserved != 0xFC )) { ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock)); return(FALSE); } if (!FMD_EraseBlock(dwBlock)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock)); return FALSE; } if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } ++dwBlock; pbBuffer += g_FlashInfo.dwBytesPerBlock; //c ksk 20060311 OALMSG(TRUE, (TEXT("dwBytesPerBlock : %d\r\n"), g_FlashInfo.dwBytesPerBlock)); } if (g_ImageType == IMAGE_TYPE_LOADER) { g_pTOC->id[0].dwLoadAddress = dwImageStart; g_pTOC->id[0].dwJumpAddress = 0; g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength); g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK); g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors; } OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n"))); return TRUE; }