📄 imgsftal.c
字号:
pBuff[14]=fh->bBdks;
}
#endif
static void Buffer2MediaHeader(MediaHeader*fh,EXBYTE*pBuff)
{
ExMemSet(fh,0,sizeof(MediaHeader));
fh->wFlashType=pBuff[1];
fh->wFlashType<<=8;
fh->wFlashType+=pBuff[0];
fh->dwMediaSize=pBuff[5];
fh->dwMediaSize<<=8;
fh->dwMediaSize+=pBuff[4];
fh->dwMediaSize<<=8;
fh->dwMediaSize+=pBuff[3];
fh->dwMediaSize<<=8;
fh->dwMediaSize+=pBuff[2];
fh->dwOsakver=pBuff[9];
fh->dwOsakver<<=8;
fh->dwOsakver+=pBuff[8];
fh->dwOsakver<<=8;
fh->dwOsakver+=pBuff[7];
fh->dwOsakver<<=8;
fh->dwOsakver+=pBuff[6];
fh->bFloors=pBuff[10];
fh->bMediaType=pBuff[11];
fh->bPercentUsed=pBuff[12];
fh->bBdtls=pBuff[13];
fh->bBdks=pBuff[14];
}
#ifndef PUTIMAGE
static void PartitionHeader2Buffer(PartitionHeader*ph,EXBYTE*pBuff)
{
ExMemSet(pBuff,0,PARTITION_HEADER_SIZE);
pBuff[0]=(EXBYTE)ph->dwSize;
pBuff[1]=(EXBYTE)(ph->dwSize>>8);
pBuff[2]=(EXBYTE)(ph->dwSize>>16);
pBuff[3]=(EXBYTE)(ph->dwSize>>24);
pBuff[4]=(EXBYTE)ph->dwSpares;
pBuff[5]=(EXBYTE)(ph->dwSpares>>8);
pBuff[6]=(EXBYTE)(ph->dwSpares>>16);
pBuff[7]=(EXBYTE)(ph->dwSpares>>24);
pBuff[8]=(EXBYTE)ph->dwFlags;
pBuff[9]=(EXBYTE)(ph->dwFlags>>8);
pBuff[10]=(EXBYTE)(ph->dwFlags>>16);
pBuff[11]=(EXBYTE)(ph->dwFlags>>24);
pBuff[12]=ph->pProtKey[0];
pBuff[13]=ph->pProtKey[1];
pBuff[14]=ph->pProtKey[2];
pBuff[15]=ph->pProtKey[3];
pBuff[16]=ph->pProtKey[4];
pBuff[17]=ph->pProtKey[5];
pBuff[18]=ph->pProtKey[6];
pBuff[19]=ph->pProtKey[7];
pBuff[20]=ph->bProtType;
pBuff[21]=(EXBYTE)(ph->wSectorPerUnit);
pBuff[22]=(EXBYTE)(ph->wSectorPerUnit>>8);
pBuff[23]=(EXBYTE)ph->dwMTDFlags;
pBuff[24]=(EXBYTE)(ph->dwMTDFlags>>8);
pBuff[25]=(EXBYTE)(ph->dwMTDFlags>>16);
pBuff[26]=(EXBYTE)(ph->dwMTDFlags>>24);
}
#endif
static void Buffer2PartitionHeader(PartitionHeader*ph,EXBYTE*pBuff)
{
ExMemSet(ph,0,sizeof(PartitionHeader));
ph->dwSize=pBuff[3];
ph->dwSize<<=8;
ph->dwSize+=pBuff[2];
ph->dwSize<<=8;
ph->dwSize+=pBuff[1];
ph->dwSize<<=8;
ph->dwSize+=pBuff[0];
ph->dwSpares=pBuff[7];
ph->dwSpares<<=8;
ph->dwSpares+=pBuff[6];
ph->dwSpares<<=8;
ph->dwSpares+=pBuff[5];
ph->dwSpares<<=8;
ph->dwSpares+=pBuff[4];
ph->dwFlags=pBuff[11];
ph->dwFlags<<=8;
ph->dwFlags+=pBuff[10];
ph->dwFlags<<=8;
ph->dwFlags+=pBuff[9];
ph->dwFlags<<=8;
ph->dwFlags+=pBuff[8];
ph->pProtKey[0]=pBuff[12];
ph->pProtKey[1]=pBuff[13];
ph->pProtKey[2]=pBuff[14];
ph->pProtKey[3]=pBuff[15];
ph->pProtKey[4]=pBuff[16];
ph->pProtKey[5]=pBuff[17];
ph->pProtKey[6]=pBuff[18];
ph->pProtKey[7]=pBuff[19];
ph->bProtType=pBuff[20];
ph->wSectorPerUnit=pBuff[22];
ph->wSectorPerUnit<<=8;
ph->wSectorPerUnit+=pBuff[21];
ph->dwMTDFlags=pBuff[26];
ph->dwMTDFlags<<=8;
ph->dwMTDFlags+=pBuff[25];
ph->dwMTDFlags<<=8;
ph->dwMTDFlags+=pBuff[24];
ph->dwMTDFlags<<=8;
ph->dwMTDFlags+=pBuff[23];
}
#ifndef PUTIMAGE
static void DataHeader2Buffer(DataHeader*ui,EXBYTE*pBuff)
{
ExMemSet(pBuff,0,UNIT_DATA_SIZE);
pBuff[0]=(EXBYTE)ui->dwUnit;
pBuff[1]=(EXBYTE)(ui->dwUnit>>8);
pBuff[2]=(EXBYTE)ui->dwSector;
pBuff[3]=(EXBYTE)(ui->dwSector>>8);
pBuff[4]=(EXBYTE)ui->wDataLen;
pBuff[5]=(EXBYTE)(ui->wDataLen>>8);
pBuff[6]=(EXBYTE)(ui->dataType);
pBuff[7]=ui->bFloor;
pBuff[8]=ui->bPart;
}
#endif
static void Buffer2DataHeader(DataHeader*ui,EXBYTE*pBuff)
{
ExMemSet(ui,0,sizeof(DataHeader));
ui->dwUnit=pBuff[1];
ui->dwUnit<<=8;
ui->dwUnit+=pBuff[0];
ui->dwSector=pBuff[3];
ui->dwSector<<=8;
ui->dwSector+=pBuff[2];
ui->wDataLen=pBuff[5];
ui->wDataLen<<=8;
ui->wDataLen+=pBuff[4];
ui->dataType=pBuff[6];
ui->bFloor=pBuff[7];
ui->bPart=pBuff[8];
}
#ifndef PUTIMAGE
static ExStatus EXAPI GetFromDoc()
{
#ifdef HW_PROTECTION
EXBYTE b;
#endif /* HW_PROTECTION */
EXBYTE bPart,bParts,bFloor;
FLExtendedDiskInfo infoSrc,infoSrcFloor;
EXDWORD dwNumberOfVirtUnitOnPreviousFloors[MAX_FLOORS]; /* contains number of virtual unit of the partition on previous floors */
PhysicalInfo physicalInfoSrc;
FLFlash*flashSrc;
/* itit PutImage() */
dataHeader.dataType=DT_INIT;
dataHeader.bFloor=0xff;
dataHeader.bPart=0xff;
CheckStat(ProgressBarManager());
CheckStat(PutImage());
flashSrc=flFlashOf(params.bSocketSrc);
CheckStat(flGetPhysicalInfo(IoreqSrc(0,0,&physicalInfoSrc,0,0)));
infoSrc.dwStructSize=sizeof(infoSrc);
infoSrcFloor.dwStructSize=sizeof(infoSrcFloor);
CheckStat(flGetExtendedDiskInfo(IoreqSrc(0,0,&infoSrc,FL_ALL_FLOORS,0)));
/* check media supported */
switch(physicalInfoSrc.mediaType)
{
case FL_DOC_OREN:
case FL_MDOC512_G3:
case FL_MDOC256_P3:
#ifdef FL_MALLOC
if((pExtra=(EXBYTE *)ExMemAlloc(flashSrc->sharedSectors*16))==EXNULL)
return EX_MALLOC_ERROR;
#else
pExtra = extra_area;
#endif
break;
default:
ExSprintf((char*)pError,"Media type %d == %s not supported",physicalInfoSrc.mediaType,TranslateTffsDocType(physicalInfoSrc.mediaType));
return EX_USER_CUSTOM_ERROR;
}
ExSprintf((char*)pMsg,"Source: %s %dMB\n\n",TranslateTffsDocType(physicalInfoSrc.mediaType),physicalInfoSrc.mediaSize>>20);
WriteMsgDevice(&msgDev,pMsg);
#ifdef HW_PROTECTION
for(b=0;b<=1;b++)
{
switch(params.srcPass[b].bPartType)
{
case 0: /* binary */
CheckStat(bdkInsertProtectionKey(IoreqSrc(params.srcPass[b].bPart,0,params.srcPass[b].pPassword,0,0)));
break;
case 1: /* BDTL */
CheckStat(flInsertProtectionKey(IoreqSrc(params.srcPass[b].bPart,0,params.srcPass[b].pPassword,0,0)));
break;
default:
b=2;
break;
}
}
#endif /* HW_PROTECTION */
ExMemSet(&mediaHeader,0,sizeof(MediaHeader));
ExMemSet(pPartitionHeader,0,(EXWORD)(VOLUMES*sizeof(PartitionHeader)));
/* fill media header */
mediaHeader.wFlashType=physicalInfoSrc.type;
mediaHeader.dwMediaSize=physicalInfoSrc.mediaSize;
mediaHeader.dwOsakver=infoSrc.dwTrueFFSVersion;
mediaHeader.bFloors=infoSrc.bNoOfFloors;
mediaHeader.bMediaType=physicalInfoSrc.mediaType;
mediaHeader.bPercentUsed=(EXBYTE)infoSrc.dwPercentUsed;
mediaHeader.bBdtls=infoSrc.bNoOfDiskPartitions;
mediaHeader.bBdks=infoSrc.bNoOfBinaryPartitions;
bParts=(EXBYTE)(mediaHeader.bBdks+mediaHeader.bBdtls);
/* fill partition headers */
for(bPart=0;bPart<bParts;bPart++)
{
CheckStat(flGetExtendedDiskInfo(IoreqSrc(0,bPart<mediaHeader.bBdks?FL_BDK_PARTITION:FL_DISK_PARTITION,&infoSrc,FL_ALL_FLOORS /* sizeof(infoSrc) */,(bPart<mediaHeader.bBdks)?bPart:bPart-mediaHeader.bBdks)));
pPartitionHeader[bPart].dwSpares=infoSrc.dwSpareUnits;
#ifdef HW_PROTECTION
if (bPart>=mediaHeader.bBdks)
stat = flIdentifyProtection(IoreqSrc(bPart-mediaHeader.bBdks,0,EXNULL,0,0));
else
stat = bdkIdentifyProtection(IoreqSrc(bPart,0,EXNULL,0,0));
if(stat!=flOK && stat!=flNotProtected)
{
CheckStat(stat);
}
if(ioreqSrc.irFlags&PROTECTABLE && !(ioreqSrc.irFlags&KEY_INSERTED))
return flHWProtection;
pPartitionHeader[bPart].bProtType=(EXBYTE)ioreqSrc.irFlags&(~KEY_INSERTED);
#endif /* HW_PROTECTION */
pPartitionHeader[bPart].dwFlags=0;
/* fill partition flags */
if(!(infoSrc.dwPartitionFlags&SAFTL_ADVANCED_MATCHING))
pPartitionHeader[bPart].dwFlags|=TL_SIMPLE_MATCHING;
if(infoSrc.dwPartitionFlags&SAFTL_REL_PARTITION)
pPartitionHeader[bPart].dwFlags|=TL_FORCE_REL;
if(infoSrc.dwPartitionFlags&SAFTL_FAST_PARTITION)
pPartitionHeader[bPart].dwFlags|=TL_FAST_MODE;
if(infoSrc.dwPartitionFlags&SAFTL_NO_MATCHING)
pPartitionHeader[bPart].dwFlags|=TL_NO_PLANES;
/* fill MTD flags */
pPartitionHeader[bPart].dwMTDFlags=MTD_DATA|MTD_EXTRA;
if(pPartitionHeader[bPart].dwFlags&TL_FORCE_REL)
pPartitionHeader[bPart].dwMTDFlags|=MTD_REL_MODE;
if(pPartitionHeader[bPart].dwFlags&TL_FAST_MODE)
pPartitionHeader[bPart].dwMTDFlags|=MTD_FAST_MODE;
if(pPartitionHeader[bPart].dwFlags&TL_NO_PLANES)
pPartitionHeader[bPart].dwMTDFlags|=MTD_NO_MATCHING;
pPartitionHeader[bPart].wSectorPerUnit=(EXWORD)(infoSrc.dwUnitSize>>9);
if((pPartitionHeader[bPart].dwFlags & TL_FORCE_REL)&&(flashSrc->flashTechnology & FL_SUPPORT_MLC))
{
if((pPartitionHeader[bPart].dwFlags & TL_FAST_MODE) && (flashSrc->flashTechnology & FL_SUPPORT_FAST))
pPartitionHeader[bPart].wSectorPerUnit>>=1;
else
if(flashSrc->flashTechnology & FL_SUPPORT_RELIABLE)
pPartitionHeader[bPart].wSectorPerUnit>>=1;
}
pPartitionHeader[bPart].dwSize=(infoSrc.dwVirtualUnits*pPartitionHeader[bPart].wSectorPerUnit)<<9;
}
/* set src's password to media header */
if(params.chPass[0].bPartType!=2)
ExMemCpy(pPartitionHeader[params.chPass[0].bPartType==0?params.chPass[0].bPart:params.chPass[0].bPart+mediaHeader.bBdks].pProtKey,params.chPass[0].pPassword,8);
else
if(params.srcPass[0].bPartType!=2)
ExMemCpy(pPartitionHeader[params.srcPass[0].bPartType==0?params.srcPass[0].bPart:params.srcPass[0].bPart+mediaHeader.bBdks].pProtKey,params.srcPass[0].pPassword,8);
if(params.chPass[1].bPartType!=2)
ExMemCpy(pPartitionHeader[params.chPass[1].bPartType==0?params.chPass[1].bPart:params.chPass[1].bPart+mediaHeader.bBdks].pProtKey,params.chPass[1].pPassword,8);
else
if(params.srcPass[1].bPartType!=2)
ExMemCpy(pPartitionHeader[params.srcPass[1].bPartType==0?params.srcPass[1].bPart:params.srcPass[1].bPart+mediaHeader.bBdks].pProtKey,params.srcPass[1].pPassword,8);
/* call PutImage() to format */
dataHeader.dwSector=0xffff;
dataHeader.dwUnit=0xffff;
dataHeader.wDataLen=MEDIA_HEADER_SIZE+PARTITION_HEADER_SIZE*bParts;
dataHeader.dataType=DT_FORMAT;
CheckStat(ProgressBarManager());
CheckStat(PutImage());
/* read OTP */
# ifdef HW_OTP
CheckStat(flInquireCapabilities(IoreqSrc(0,0,EXNULL,SUPPORT_OTP_AREA,0)));
if(ioreqSrc.irLength==CAPABILITY_SUPPORTED)
{
CheckStat(flOTPSize(IoreqSrc(0,0,EXNULL,0,0)));
if(ioreqSrc.irFlags==LOCKED_OTP && ioreqSrc.irLength<0x6800) /* OTP written */
{
dataHeader.wDataLen=(EXWORD)ioreqSrc.irLength;
dataHeader.wDataLen=(dataHeader.wDataLen>>4)<<4;
if(dataHeader.wDataLen!=(EXWORD)ioreqSrc.irLength)
dataHeader.wDataLen+=16;
CheckStat(flOTPRead(IoreqSrc(0,0,pMain,ioreqSrc.irLength,0)));
/* call PutImage() to write OTP */
dataHeader.dataType=DT_OTP;
dataHeader.bFloor=0xff;
dataHeader.bPart=0xff;
dataHeader.dwSector=0;
dataHeader.dwUnit=0;
CheckStat(ProgressBarManager());
CheckStat(PutImage());
}
}
# endif /* HW_OTP */
/* read IPL */
#ifndef NO_IPL_CODE
dataHeader.wDataLen=(EXWORD)infoSrc.dwIPLSize;
CheckStat(flReadIPL(IoreqSrc(0,0,pMain,dataHeader.wDataLen,0)));
dataHeader.dataType=DT_IPL;
dataHeader.bFloor=0xff;
dataHeader.bPart=0xff;
dataHeader.dwSector=0;
dataHeader.dwUnit=0;
CheckStat(ProgressBarManager());
CheckStat(PutImage());
#endif /* NO_IPL_CODE */
/* read BBT */
flashSrc->args.noOfUnits=(EXWORD)(physicalInfoSrc.mediaSize/infoSrc.dwUnitSize);
#ifdef FL_MALLOC
if((pBbtSrc=(EXBYTE *)ExMemAlloc((EXWORD)flashSrc->args.noOfUnits))==EXNULL) /* free in BdkSrc */
return EX_MALLOC_ERROR;
#else
pBbtSrc = src_bbt_table;
#endif
flashSrc->args.readMainBuf=pBbtSrc;
flashSrc->args.startUnit=0;
CheckStat(flashSrc->readBBT(flashSrc));
/* read partitions */
dwNumberOfVirtUnitOnPreviousFloors[0]=dwNumberOfVirtUnitOnPreviousFloors[1]=dwNumberOfVirtUnitOnPreviousFloors[2]=dwNumberOfVirtUnitOnPreviousFloors[3]=0;
for(bFloor=0;bFloor<mediaHeader.bFloors;bFloor++)
{
dataHeader.bFloor=bFloor;
for(bPart=0;bPart<bParts;bPart++)
{
EXDWORD dwVirtUnitOfFloor;
/* check that the part exist on the floor */
CheckStat(flGetExtendedDiskInfo(IoreqSrc(0,(bPart<mediaHeader.bBdks)?FL_BDK_PARTITION:FL_DISK_PARTITION,&infoSrcFloor,bFloor,(bPart<mediaHeader.bBdks)?bPart:bPart-mediaHeader.bBdks)));
if(!infoSrcFloor.dwVirtualUnits)
continue;
dataHeader.bPart=bPart;
if(bPart<mediaHeader.bBdks) /* read BDK part */
{
EXDWORD dwPhyUnit=infoSrcFloor.dwFirstUnit;
if(dwPhyUnit==0) /* part continued from previous floor - skip media header unit */
dwPhyUnit=infoSrcFloor.wHeaderLocation+infoSrcFloor.bHeaderUnits;
dataHeader.dataType=DT_BDK;
for(dwVirtUnitOfFloor=0;dwVirtUnitOfFloor<infoSrcFloor.dwVirtualUnits;dwVirtUnitOfFloor++,dwPhyUnit++)
{
EXWORD wSectorOfUnit; /* sector offset from begin of unit */
EXWORD wReadedSectors=0; /* number of sectors in data chunk */
/* skip bad block */
while(pBbtSrc[dwPhyUnit]!=BBT_GOOD_UNIT)
dwPhyUnit++;
/* read current unit */
for(wSectorOfUnit=0;wSectorOfUnit<pPartitionHeader[bPart].wSectorPerUnit;wSectorOfUnit++)
{
EXBYTE*pTmp=pMain+wReadedSectors*512;
/* read 1 sector with ECC */
flashSrc->args.noOfSectors=1;
flashSrc->args.startSector=dwPhyUnit*(FLDword)pPartitionHeader[bPart].wSectorPerUnit+wSectorOfUnit;
flashSrc->args.readMainBuf=pTmp;
flashSrc->args.extraBuf=pTmp+512;
flashSrc->args.opFlags=pPartitionHeader[bPart].dwMTDFlags;
stat=flashSrc->flashRead(flashSrc);
if(stat==EX_OK)
{
/* calculate ECC for readed sector */
pTmp[519]=Hamming_Parity(pTmp+512,7);
BCH_Parity(pTmp,520,pTmp+520);
pTmp[527] = 0xFF;
/* all extra areas should be after all data areas */
ExMemCpy(pExtra+(wReadedSectors<<4),pTmp+512,16);
if(wReadedSectors==0) /* it's first sector in the data chunk, so copy its address to dataHeader */
{
dataHeader.dwUnit=dwVirtUnitOfFloor;
dataHeader.dwSector=wSectorOfUnit;
}
wReadedSectors++;
}
/* we do put image if: we read something AND */
/* (empty sector found in this session OR we read 4 (8) sectors OR unit is over) */
if( wReadedSectors && (stat!=EX_OK || !((wSectorOfUnit+1)%flashSrc->sharedSectors) || (wSectorOfUnit+1==pPartitionHeader[bPart].wSectorPerUnit)) ) /* sector empty or we reached end of data chunk or end of unit - 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());
/* start new data chunk */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -