📄 imgsftal.c
字号:
wReadedSectors=0;
}
} /* end of sector loop */
} /* end of BDK units loop */
}/* end of read BDK part */
else /* read BDTL part */
{
EXDWORD dwSectorOfPart=dwNumberOfVirtUnitOnPreviousFloors[bPart]*pPartitionHeader[bPart].wSectorPerUnit;
EXBYTE bBdtlPart=bPart-mediaHeader.bBdks;
dataHeader.dataType=DT_BDTL;
CheckStat(flAbsMountVolume(IoreqSrc(bBdtlPart,0,NULL,0,0)));
for(dwVirtUnitOfFloor=0;dwVirtUnitOfFloor<infoSrcFloor.dwVirtualUnits;dwVirtUnitOfFloor++)
{
EXWORD wVSO; /* Virtual Sector Offset */
EXWORD wReadedSectors=0; /* number of sectors in data chunk */
EXBOOL fUnitEmpty=TRUE; /* indicate first sector of the current unit */
EXWORD wVUN=(EXWORD)(dwVirtUnitOfFloor+dwNumberOfVirtUnitOnPreviousFloors[bPart]); /* Virtual Unit Number */
EXWORD wSequentialSectorsCount=0;
dataHeader.dwUnit=dwVirtUnitOfFloor;
dataHeader.dwSector=0;
for(wVSO=0;wVSO<pPartitionHeader[bPart].wSectorPerUnit;wVSO++,dwSectorOfPart++)
{
/* ask if sector exist */
if((stat=flAbsAddress(IoreqSrc(bBdtlPart,0,EXNULL,dwSectorOfPart,0)))==flOK)
{
EXBYTE*pTmp=pMain+(wReadedSectors<<9);
/* read sector data area */
CheckStat(flAbsRead(IoreqSrc(bBdtlPart,0,pTmp,dwSectorOfPart,1)));
/* fill sector extra area */
pTmp[512]=(EXBYTE)wVSO;
pTmp[513]=(EXBYTE)((wVSO>>8)|0x80|0x38); /* Virtual Sector Offset 3 MSL | Transaction | Sector flag Used */
if(fUnitEmpty)
{ /* it's first sector of this virtual unit */
fUnitEmpty=FALSE;
pTmp[514]=(EXBYTE)wVUN; /* Virtual unit number */
pTmp[515]=(EXBYTE)(wVUN>>8); /* Virtual unit number */
pTmp[516]=pTmp[517]=0xff; /* Previous unit number */
pTmp[518]=0x70; /* 0|3 reserved|ANAK=0 */
pTmp[519]=Hamming_Parity(pTmp+512,7);
BCH_Parity(pTmp,520,pTmp+520);
pTmp[527]=0x55;
}
else
{
pTmp[514]=(EXBYTE)wSequentialSectorsCount; /* Sequential Sectors Count */
pTmp[515]=(EXBYTE)((wSequentialSectorsCount>>8)|0xc0); /* Sequential Sectors Count | 0xC0 reserved */
pTmp[516]=pTmp[517]=pTmp[518]=0xff; /* reserved */
pTmp[519]=Hamming_Parity(pTmp+512,7);
BCH_Parity(pTmp,520,pTmp+520);
pTmp[527]=0xff; /* erase mark */
}
ExMemCpy(pExtra+(wReadedSectors<<4),pTmp+512,16);
wReadedSectors++;
}
else /* we did not find sector */
{
if(stat!=flSectorNotFound)
{
return stat;
}
wSequentialSectorsCount=0;
}
if( wReadedSectors && ( (wReadedSectors==flashSrc->sharedSectors) || (wVSO+1==pPartitionHeader[bPart].wSectorPerUnit) ) ) /* end of unit or we reached end of data chunk - flush the data */
{
/* copy extra areas to the end of data chunk */
ExMemCpy(pMain+(wReadedSectors<<9),pExtra,wReadedSectors<<4);
/* call PutImage() to write the BDK data */
dataHeader.wDataLen=528*wReadedSectors;
CheckStat(ProgressBarManager());
CheckStat(PutImage());
dataHeader.dwSector+=wReadedSectors;
/* start new data chunk */
wReadedSectors=0;
}
} /* end of BDTL sectors of virtual unit loop */
} /* end of BDTL units loop */
CheckStat(flDismountVolume(IoreqSrc(bBdtlPart,0,NULL,0,0)));
}/* end of read BDTL part */
dwNumberOfVirtUnitOnPreviousFloors[bPart]+=infoSrcFloor.dwVirtualUnits;
}/* end of partition loop */
}/* end of floor loop */
/* close the image with last data header */
dataHeader.dwSector=0xffff;
dataHeader.dwUnit=0xffff;
dataHeader.wDataLen=0;
dataHeader.dataType=DT_LAST;
dataHeader.bFloor=0xff;
dataHeader.bPart=0xff;
CheckStat(ProgressBarManager());
CheckStat(PutImage());
/* remove key */
flashSrc->download(flashSrc);
return EX_OK;
}
#endif /* PUTIMAGE */
static ExStatus EXAPI PutToDoc()
{
EXBYTE b,bPart;
EXDWORD dwIndex1,dwIndex2;
static FLFlash*flashTar;
switch(dataHeader.dataType)
{
case DT_INIT:
flashTar=flFlashOf(params.bSocketTar);
#ifndef NO_SINGLE
if(params.bSingle==0xff)
#endif
bFirstFloor=0;
#ifndef NO_SINGLE
else
bFirstFloor=params.bSingle;
#endif
bLastFloor=bFirstFloor+flashTar->noOfFloors;
return EX_OK;
case DT_FORMAT:
{
FormatParams2*fp;
PhysicalInfo physicalInfoTar;
FLExtendedDiskInfo infoTar,infoTarFloor;
EXBYTE bFloor;
infoTar.dwStructSize=sizeof(infoTar);
infoTarFloor.dwStructSize=sizeof(infoTarFloor);
CheckStat(flGetPhysicalInfo(IoreqTar(0,0,&physicalInfoTar,0,0)));
/* check media supported */
switch(physicalInfoTar.mediaType)
{
case FL_DOC_OREN:
case FL_MDOC512_G3:
case FL_MDOC256_P3:
break;
default:
ExSprintf((char*)pError,"Media type %d == %s not supported",physicalInfoTar.mediaType,TranslateTffsDocType(physicalInfoTar.mediaType));
return EX_USER_CUSTOM_ERROR;
}
/* check image compatibility */
if(
(physicalInfoTar.mediaType!=mediaHeader.bMediaType) ||
((EXDWORD)physicalInfoTar.mediaSize!=mediaHeader.dwMediaSize
#ifndef NO_SINGLE
&& params.bSingle==0xff
#endif
)
)
return EXE_NOT_COMPATIBLE;
/* format */
fp=(FormatParams2*)pMain;
fp->binaryPartitionInfo=(BinaryPartitionFormatParams*)(pMain+sizeof(FormatParams2));
fp->BDTLPartitionInfo=(BDTLPartitionFormatParams*)(fp->binaryPartitionInfo+mediaHeader.bBdks);
fp->percentUse=mediaHeader.bPercentUsed;
fp->noOfBDTLPartitions=mediaHeader.bBdtls;
fp->noOfBinaryPartitions=mediaHeader.bBdks;
#ifndef NO_SINGLE
if(params.bSingle==0xff)
{
#endif
fp->cascadedDeviceNo=0;
fp->noOfCascadedDevices=0;
#ifndef NO_SINGLE
}
else
{
fp->cascadedDeviceNo=params.bSingle;
fp->noOfCascadedDevices=mediaHeader.bFloors;
}
#endif
fp->progressCallback=ProgressCallback;
fp->vmAddressingLimit=0x10000l;
fp->embeddedCISlength=0;
fp->embeddedCIS=EXNULL;
for(b=0;b<mediaHeader.bBdks;b++)
{
fp->binaryPartitionInfo[b].length=pPartitionHeader[b].dwSize;
ExMemCpy(fp->binaryPartitionInfo[b].sign,"BIPO",4);
fp->binaryPartitionInfo[b].flags=(EXBYTE)pPartitionHeader[b].dwFlags;
#ifdef HW_PROTECTION
ExMemCpy(fp->binaryPartitionInfo[b].protectionKey,pPartitionHeader[b].pProtKey,8);
fp->binaryPartitionInfo[b].protectionType=pPartitionHeader[b].bProtType;
#endif /* HW_PROTECTION */
}
for(b=0;b<mediaHeader.bBdtls;b++)
{
if(b+1<mediaHeader.bBdtls)
fp->BDTLPartitionInfo[b].length=pPartitionHeader[b+mediaHeader.bBdks].dwSize;
else
fp->BDTLPartitionInfo[b].length=0;
fp->BDTLPartitionInfo[b].noOfSpareUnits=pPartitionHeader[b+mediaHeader.bBdks].dwSpares;
fp->BDTLPartitionInfo[b].flags=(EXBYTE)pPartitionHeader[b+mediaHeader.bBdks].dwFlags;
ExMemCpy(fp->BDTLPartitionInfo[b].volumeId,"0000",4);
fp->BDTLPartitionInfo[b].volumeLabel=EXNULL;
fp->BDTLPartitionInfo[b].noOfFATcopies=0;
#ifdef HW_PROTECTION
ExMemCpy(fp->BDTLPartitionInfo[b].protectionKey,pPartitionHeader[b+mediaHeader.bBdks].pProtKey,8);
fp->BDTLPartitionInfo[b].protectionType=pPartitionHeader[b+mediaHeader.bBdks].bProtType;
#endif /* HW_PROTECTION */
}
#ifdef HW_PROTECTION
/* remove original protection (/..TRG:) */
if(params.tarPass[0].bPartType!=2)
{
flashTar->protectionKeyInsert(flashTar,0,params.tarPass[0].pPassword);
flashTar->protectionKeyInsert(flashTar,1,params.tarPass[0].pPassword);
}
if(params.tarPass[1].bPartType!=2)
{
flashTar->protectionKeyInsert(flashTar,0,params.tarPass[1].pPassword);
flashTar->protectionKeyInsert(flashTar,1,params.tarPass[1].pPassword);
}
for(b=0;b<2;b++)
{
FLWord wProtType;
stat=flashTar->protectionType(flashTar,b,&wProtType);
if(stat==flOK)
{
if(wProtType&PROTECTABLE && !(wProtType&KEY_INSERTED))
return flHWProtection;
}
else
if(stat!=flNotProtected)
return stat;
}
#endif /* HW_PROTECTION */
OpenPrgBarDevice(&progDev,"Formatting",physicalInfoTar.mediaSize/physicalInfoTar.unitSize);
#ifndef NO_SINGLE
CheckStat(flFormatPhysicalDrive(IoreqTar(0,TL_DO_NOT_PERFORM_DOWNLOAD|(params.bSingle==0xff?0:TL_SINGLE_FLOOR),fp,0,0)));
#else
CheckStat(flFormatPhysicalDrive(IoreqTar(0,TL_DO_NOT_PERFORM_DOWNLOAD,fp,0,0)));
#endif
ClosePrgBarDevice(&progDev);
CheckStat(flGetExtendedDiskInfo(IoreqTar(0,0,&infoTar,FL_ALL_FLOORS,0)));
/* Turn off verify write mode - from now on it is done manually */
if(params.bVerify == EXTRUE)
{
EXDWORD tmp;
CheckStat(flSetEnvSocket(FL_VERIFY_WRITE_OTHER,params.bSocketTar,FL_OFF,&tmp));
}
/* read BBT */
flashTar->args.noOfUnits=(EXWORD)(physicalInfoTar.mediaSize/infoTar.dwUnitSize);
#ifdef FL_MALLOC
if((pBbtTar=(EXBYTE *)ExMemAlloc((EXWORD)flashTar->args.noOfUnits))==EXNULL) /* free in BdkSrc */
return EX_MALLOC_ERROR;
#else
pBbtTar = tar_bbt_table;
#endif
flashTar->args.readMainBuf=pBbtTar;
flashTar->args.startUnit=0;
CheckStat(flashTar->readBBT(flashTar));
/* fill virtual to physical table for each partition */
for(bFloor=bFirstFloor;bFloor<bLastFloor;bFloor++)
{
for(bPart=0;bPart<mediaHeader.bBdks+mediaHeader.bBdtls;bPart++)
{
EXDWORD dwPhyUnit,dwVirtUnit;
/* check that the part exist on the floor */
CheckStat(flGetExtendedDiskInfo(IoreqTar(0,(bPart<mediaHeader.bBdks)?FL_BDK_PARTITION:FL_DISK_PARTITION,&infoTarFloor,bFloor-bFirstFloor,(bPart<mediaHeader.bBdks)?bPart:bPart-mediaHeader.bBdks)));
if(!infoTarFloor.dwVirtualUnits)
continue;
#ifdef FL_MALLOC
if((pVir2PhyTar[bFloor*MAX_FLOORS+bPart]=(EXWORD*)ExMemAlloc(infoTarFloor.dwVirtualUnits*sizeof(EXWORD)))==EXNULL)
return EX_MALLOC_ERROR;
#else
pVir2PhyTar[bFloor*MAX_FLOORS+bPart]= (EXWORD *)&Vir2PhyTar_area[(bFloor*MAX_FLOORS+bPart)*MAX_LOGICAL_UNITS_IN_FLOOR*2];
#endif
dwPhyUnit=(EXWORD)infoTarFloor.dwFirstUnit;
if(dwPhyUnit==0) /* part continued from previous floor - skip media header unit */
dwPhyUnit=infoTarFloor.wHeaderLocation+infoTarFloor.bHeaderUnits;
#ifndef NO_SINGLE
else /* part begin on this floor */
if(params.bSingle!=0xff)
dwPhyUnit-=(EXWORD)infoTarFloor.dwUnitsInFirstFloor*params.bSingle;
#endif
for(dwVirtUnit=0;dwVirtUnit<infoTarFloor.dwVirtualUnits;dwVirtUnit++,dwPhyUnit++)
{
/* skip bad blocks */
while(pBbtTar[dwPhyUnit]!=BBT_GOOD_UNIT)
dwPhyUnit++;
*(pVir2PhyTar[bFloor*MAX_FLOORS+bPart]+dwVirtUnit)=(EXWORD)dwPhyUnit;
}
}
}
#ifdef FL_MALLOC
ExMemFree(pBbtTar);
#endif
pBbtTar=EXNULL;
return EX_OK;
} /* end of case DT_FORMAT */
case DT_OTP: /* write OTP */
# ifdef HW_OTP
if(bFirstFloor==0)
return flashTar->writeOTP(flashTar,pMain,dataHeader.wDataLen);
else
#else
return EX_OK;
# endif /* HW_OTP */
case DT_IPL: /* write IPL */
#ifndef NO_IPL_CODE
/* devide and multifly by odd number give result different */
/* from the original, so calc reminder and use it */
if (dataHeader.wDataLen%mediaHeader.bFloors)
{
EXBYTE reminder = dataHeader.wDataLen%mediaHeader.bFloors;
CheckStat(flashTar->writeIPL(flashTar,(const void FAR1 *)(pMain+(FLWord)(dataHeader.wDataLen/mediaHeader.bFloors)*(FLWord)bFirstFloor),
(FLWord)(reminder + (FLWord)(dataHeader.wDataLen/mediaHeader.bFloors)*(FLWord)(bLastFloor-bFirstFloor)),
(FLByte)0,(unsigned)FL_IPL_MODE_NORMAL));
}
else
{
CheckStat(flashTar->writeIPL(flashTar,(const void FAR1 *)(pMain+(FLWord)(dataHeader.wDataLen/mediaHeader.bFloors)*(FLWord)bFirstFloor),
(FLWord)((FLWord)(dataHeader.wDataLen/mediaHeader.bFloors)*(FLWord)(bLastFloor-bFirstFloor)),
(FLByte)0,(unsigned)FL_IPL_MODE_NORMAL));
}
#endif /* NO_IPL_CODE */
return EX_OK;
case DT_BDK:
case DT_BDTL:
flashTar->args.noOfSectors=dataHeader.wDataLen/528;
flashTar->args.startSector=(EXDWORD)(*(pVir2PhyTar[dataHeader.bFloor*MAX_FLOORS+dataHeader.bPart]+dataHeader.dwUnit))*(EXDWORD)pPartitionHeader[dataHeader.bPart].wSectorPerUnit+dataHeader.dwSector;
flashTar->args.writeMainBuf=pMain;
flashTar->args.extraBuf=pMain+(flashTar->args.noOfSectors<<9);
flashTar->args.opFlags=pPartitionHeader[dataHeader.bPart].dwMTDFlags|MTD_SW_EDC;
stat = flashTar->flashWrite(flashTar);
if(stat != flOK)
{
ExSprintf((char*)pError,"Failed in writing of sector %lu with status %d",flashTar->args.startSector,stat);
return stat;
}
if(params.bVerify == EXFALSE)
return EX_OK;
/* Read back and compare */
flashTar->args.readMainBuf=pMainReadBack;
flashTar->args.extraBuf=pMainReadBack+(flashTar->args.noOfSectors<<9);
stat = flashTar->flashRead(flashTar);
if(stat != flOK)
{
ExSprintf((char*)pError,"Failed in verify of sector %lu with status %d",flashTar->args.startSector,stat);
return flWriteFault;
}
/* Restore values just in case!!! */
flashTar->args.writeMainBuf=pMain;
flashTar->args.extraBuf=pMain+(flashTar->args.noOfSectors<<9);
/* Compare the 2 buffers */
for(dwIndex1=0;dwIndex1<flashTar->args.noOfSectors;dwIndex1++)
{
EXBYTE FAR1 * bSrcPtrMain = pMain+(dwIndex1<<9) ;
EXBYTE FAR1 * bDstPtrMain = pMainReadBack+(dwIndex1<<9) ;
EXBYTE FAR1 * bSrcPtrExtra = pMain+(dwIndex1<<4)+(flashTar->args.noOfSectors<<9) ;
EXBYTE FAR1 * bDstPtrExtra = pMainReadBack+(dwIndex1<<4)+(flashTar->args.noOfSectors<<9) ;
EXBYTE bNoOfBitFlips = 0;
EXBYTE bXoredData;
/* Verify main area */
if(ExMemCmp(bSrcPtrMain,bDstPtrMain,512))
{
/* Count bit flips */
for(dwIndex2=0;dwIndex2<512;dwIndex2++)
{
if(bSrcPtrMain[dwIndex2]!=bDstPtrMain[dwIndex2])
{
for(bXoredData = bSrcPtrMain[dwIndex2] ^ bDstPtrMain[dwIndex2];
bXoredData != 0 ; bXoredData = bXoredData>>1)
{
if(bXoredData & 1)
bNoOfBitFlips++;
}
}
}
}
/* Verify extra area */
if(ExMemCmp(bSrcPtrExtra,bDstPtrExtra,15))
{
/* Count bit flips */
for(dwIndex2=0;dwIndex2<15;dwIndex2++)
{
if(bSrcPtrExtra[dwIndex2]!=bDstPtrExtra[dwIndex2])
{
for(bXoredData = bSrcPtrExtra[dwIndex2] ^ bDstPtrExtra[dwIndex2];
bXoredData != 0 ; bXoredData = bXoredData>>1)
{
if(bXoredData & 1)
bNoOfBitFlips++;
}
}
}
}
if(bNoOfBitFlips>2)
{
ExSprintf((char*)pError,"Failed in verify write of sector %lu (with %u bit flips)",flashTar->args.startSector+dwIndex2,(FLWord)bNoOfBitFlips);
return flWriteFault;
}
}
return EX_OK;
case DT_LAST: /* dimage /SINGLE may not reach it */
flashTar->download(flashTar);
return EX_OK;
}
return EXE_IMAGE; /* prevent warning */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -