📄 imgsftal.c
字号:
#include "exdevice.h"
#include "extffs.h"
#include "exos.h"
#include "blockdev.h"
#include "saftl.h"
#include "image.h"
#include <stdio.h>
#include "bch_hm.h"
#include "bchhwsim.h"
static ExStatus (EXAPI*GetImage)();
static ExStatus (EXAPI*PutImage)();
static ExStatus EXAPI GetFromDoc();
static ExStatus EXAPI GetFromFile();
static ExStatus EXAPI PutToDoc();
static ExStatus EXAPI PutToFile();
#define MAX_LOGICAL_UNITS_IN_PLATFORM (((FLDword)FL_ASSUMED_MAX_VOLUME_MBYTES<<20L) / FL_ASSUMED_MIN_UNIT_SIZE)
#define FL_MAX_SHARED_SECTORS 8
#define MAX_LOGICAL_UNITS_IN_FLOOR (MAX_LOGICAL_UNITS_IN_PLATFORM/4)
#ifndef FL_MALLOC
static EXBYTE main_area[EX_MAIN_SIZE];
static EXBYTE main_read_back_area[EX_MAIN_SIZE];
static EXBYTE src_bbt_table[MAX_LOGICAL_UNITS_IN_PLATFORM];
static EXBYTE tar_bbt_table[MAX_LOGICAL_UNITS_IN_PLATFORM];
static EXBYTE extra_area[FL_MAX_SHARED_SECTORS * 16];
/* 4 floors , 4 part , 2 bytes */
/* pVir2PhyTar is an array of 16 ptrs , and each one can point to floor size area */
/* so all together we need to support 16 floors X num units infloor X 2 */
static EXBYTE Vir2PhyTar_area[MAX_LOGICAL_UNITS_IN_FLOOR * 4 * 4 * 2];
#endif
static ExStatus stat;
#define CheckStat(s) stat=s;if(stat!=EX_OK){return stat;}
extern ExDevice msgDev;
extern EXCHAR pError[0xff],pMsg[0xff];
extern Params params;
static ExDevice progDev; /* progress bar device handle */
static EXCHAR pProgHeader[26]; /* used to store progress bar device header string */
static MediaHeader mediaHeader;
static PartitionHeader pPartitionHeader[VOLUMES];
static DataHeader dataHeader;
#ifndef PUTIMAGE
static IOreq ioreqSrc;
#endif
static IOreq ioreqTar;
static EXBYTE*pMain=EXNULL;
static EXBYTE*pMainReadBack = EXNULL;
#ifndef PUTIMAGE
static EXBYTE *pBbtSrc = EXNULL;
static EXBYTE *pExtra = EXNULL;
#endif
static EXBYTE*pBbtTar=EXNULL;
static EXWORD*pVir2PhyTar[MAX_FLOORS*MAX_PARTS];
/* ProgressCallback vars */
static int units;
static EXBYTE bFirstFloor=0,bLastFloor=0; /* initialized to prevent warnings */
IOreq* EXAPI IoreqSrc(FLHandle irHandle,unsigned int irFlags,void EXFAR*irData,long irLength,long irCount);
IOreq* EXAPI IoreqTar(FLHandle irHandle,unsigned int irFlags,void EXFAR*irData,long irLength,long irCount);
ExStatus EXAPI RemoveProtection(EXBYTE bSocket);
FLStatus ProgressCallback(EXWORD totalUnitsToFormat, EXWORD totalUnitsFormattedSoFar);
static void MediaHeader2Buffer(MediaHeader*fh,EXBYTE*pBuff);
static void Buffer2MediaHeader(MediaHeader*fh,EXBYTE*pBuff);
static void PartitionHeader2Buffer(PartitionHeader*ph,EXBYTE*pBuff);
static void Buffer2PartitionHeader(PartitionHeader*ph,EXBYTE*pBuff);
static void DataHeader2Buffer(DataHeader*ui,EXBYTE*pBuff);
static void Buffer2DataHeader(DataHeader*ui,EXBYTE*pBuff);
static void ImageMemFree(void);
ExStatus EXAPI ImageSaftl()
{
EXDWORD tmp;
/* Set bus access type before any TrueFFS access */
if(params.bSocketSrc!=SOCKETS || params.bSocketTar!=SOCKETS)
{
if(params.dwBusConfig!=0)
{
CheckStat(flSetEnvAll(FL_MTD_BUS_ACCESS_TYPE,params.dwBusConfig,&tmp));
}
CheckStat(flInit());
}
/* For putimage with verify flag turn the verify write on */
if((params.bSocketTar!=SOCKETS) && (params.bVerify == EXTRUE))
{
CheckStat(flSetEnvSocket(FL_VERIFY_WRITE_OTHER,params.bSocketTar,FL_ON,&tmp));
}
/* For getimage without putimage change to read only */
if(params.bSocketSrc!=SOCKETS)
{
CheckStat(flSetEnvSocket(FL_SUSPEND_MODE,params.bSocketSrc,(FL_IGNORE_WRITE|FL_IGNORE_ERASE),&tmp));
}
#ifdef FL_MALLOC
if((pMain=(EXBYTE *)ExMemAlloc(EX_MAIN_SIZE))==EXNULL)
{
return EX_MALLOC_ERROR;
}
if((pMainReadBack=(EXBYTE *)ExMemAlloc(EX_MAIN_SIZE))==EXNULL)
{
return EX_MALLOC_ERROR;
}
#else
pMain = main_area;
pMainReadBack = main_read_back_area;
#endif
#ifndef PUTIMAGE
if(params.bSocketSrc==SOCKETS)
#endif
GetImage=GetFromFile;
#ifndef PUTIMAGE
else
GetImage=GetFromDoc;
#endif
#ifndef PUTIMAGE
if(params.bSocketTar==SOCKETS)
PutImage=PutToFile;
else
#endif
PutImage=PutToDoc;
/* init ProgressCallback vars */
units=0;
ExMemSet(pVir2PhyTar,0,MAX_PARTS*MAX_FLOORS*sizeof(EXWORD*));
stat=GetImage();
ImageMemFree();
if(params.bSocketSrc!=SOCKETS || params.bSocketTar!=SOCKETS)
flExit();
if(stat==EXE_END_OF_DATA)
return EX_OK;
else
return stat;
}
static void ImageMemFree(void)
{
EXBYTE b;
if(pMain!=EXNULL)
{
#ifdef FL_MALLOC
ExMemFree(pMain);
#endif
pMain=EXNULL;
}
if(pMainReadBack!=EXNULL)
{
#ifdef FL_MALLOC
ExMemFree(pMainReadBack);
#endif
pMainReadBack=EXNULL;
}
#ifndef PUTIMAGE
if(pExtra!=EXNULL)
{
#ifdef FL_MALLOC
ExMemFree(pExtra);
#endif
pExtra=EXNULL;
}
if(pBbtSrc!=EXNULL)
{
#ifdef FL_MALLOC
ExMemFree(pBbtSrc);
#endif
pBbtSrc=EXNULL;
}
#endif
if(pBbtTar!=EXNULL)
{
#ifdef FL_MALLOC
ExMemFree(pBbtTar);
#endif
pBbtTar=EXNULL;
}
for(b=0;b<MAX_PARTS*MAX_FLOORS;b++)
{
if(*(pVir2PhyTar+b)!=EXNULL)
{
#ifdef FL_MALLOC
ExMemFree(*(pVir2PhyTar+b));
#endif
*(pVir2PhyTar+b)=EXNULL;
}
}
}
static ExStatus EXAPI ProgressBarManager(void)
{
static EXBYTE bPrevPart,bPrevFloor;
if(bPrevPart!=dataHeader.bPart || bPrevFloor!=dataHeader.bFloor)
{
if(dataHeader.dataType==DT_INIT)
{
bPrevPart=0xff;
bPrevFloor=0xff;
return EX_OK;
}
if(bPrevPart!=0xff || bPrevFloor!=0xff)
ClosePrgBarDevice(&progDev);
switch(dataHeader.dataType)
{
case DT_BDK:
ExSprintf(pProgHeader,"Floor %d BDK %d",dataHeader.bFloor,dataHeader.bPart);
CheckStat(OpenPrgBarDevice(&progDev,pProgHeader,pPartitionHeader[dataHeader.bPart].dwSize>>9));
break;
case DT_BDTL:
ExSprintf(pProgHeader,"Floor %d BDTL %d",dataHeader.bFloor,dataHeader.bPart);
CheckStat(OpenPrgBarDevice(&progDev,pProgHeader,pPartitionHeader[dataHeader.bPart].dwSize>>9));
break;
}
bPrevPart=dataHeader.bPart;
bPrevFloor=dataHeader.bFloor;
}
switch(dataHeader.dataType)
{
case DT_FORMAT:
/* WriteMsgDevice(&msgDev,"Formatting\n"); */
break;
case DT_OTP:
WriteMsgDevice(&msgDev,"OTP\n");
break;
case DT_IPL:
WriteMsgDevice(&msgDev,"IPL\n");
break;
case DT_BDK:
WritePrgBarDevice(&progDev,dataHeader.dwSector+dataHeader.dwUnit*pPartitionHeader[dataHeader.bPart].wSectorPerUnit);
break;
case DT_BDTL:
WritePrgBarDevice(&progDev,dataHeader.dwSector+dataHeader.dwUnit*pPartitionHeader[dataHeader.bPart].wSectorPerUnit);
break;
case DT_LAST:
WriteMsgDevice(&msgDev,"End of image\n");
break;
}
return EX_OK;
}
static ExStatus EXAPI GetFromFile()
{
EXDWORD dwReaded;
EXBYTE unitInfoBuff[16];
EXWORD wTffsVer,wDimageVer;
EXBYTE bParts;
/* read and check version numbers and signature */
if(ReadSerialFileDevice(¶ms.imageDevSrc,pMain,16,&dwReaded)!=EX_OK)
return EXE_IMAGE;
if(pMain[0]!='V' || pMain[4]!='V' || ExMemCmp(pMain+8,VER_SIGNATURE,8))
{
DBG_PRINT_ERR (FLZONE_UTIL,"GetFromFile: expected 'V' not found. \n\r") ;
return EXE_IMAGE;
}
wTffsVer=pMain[1];
wTffsVer<<=8;
wTffsVer+=pMain[2];
wDimageVer=pMain[7];
wDimageVer<<=8;
wDimageVer+=pMain[6];
wDimageVer<<=8;
wDimageVer+=pMain[5];
if (wDimageVer<VER_DIMAGE_COMPATIBLE)
{
DBG_PRINT_ERR (FLZONE_UTIL,"GetFromFile: Dimage does not support this image-file-version. \n\r") ;
return EXE_IMAGE;
}
/* init PutImage */
dataHeader.dataType=DT_INIT;
dataHeader.bFloor=0xff;
dataHeader.bPart=0xff;
CheckStat(ProgressBarManager());
CheckStat(PutImage());
/* read image */
while(1)
{
/* read data header */
if(ReadSerialFileDevice(¶ms.imageDevSrc,unitInfoBuff,16,&dwReaded)!=EX_OK)
return EXE_IMAGE;
Buffer2DataHeader(&dataHeader,unitInfoBuff);
/* read data */
if(dataHeader.wDataLen)
{
EXWORD wDataLen=(dataHeader.wDataLen>>4)<<4;
if(wDataLen!=dataHeader.wDataLen)
wDataLen+=16;
if(ReadSerialFileDevice(¶ms.imageDevSrc,pMain,wDataLen,&dwReaded)!=EX_OK)
return EXE_IMAGE;
}
if(dataHeader.dataType==DT_FORMAT)
{
EXBYTE bPart;
Buffer2MediaHeader(&mediaHeader,pMain);
bParts=(EXBYTE)(mediaHeader.bBdks+mediaHeader.bBdtls);
for(bPart=0;bPart<bParts;bPart++)
{
Buffer2PartitionHeader(&pPartitionHeader[bPart],pMain+MEDIA_HEADER_SIZE+PARTITION_HEADER_SIZE*bPart);
}
/* replace src password, if needed */
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);
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);
}
CheckStat(ProgressBarManager());
if(dataHeader.bFloor==0xff || (dataHeader.bFloor>=bFirstFloor && dataHeader.bFloor<bLastFloor) )
CheckStat(PutImage());
if(dataHeader.dataType==DT_LAST || (dataHeader.bFloor>=bLastFloor && dataHeader.bFloor!=0xff))
return EXE_END_OF_DATA;
}
return EXE_IMAGE; /* prevent warning */
}
#ifndef PUTIMAGE
static ExStatus EXAPI PutToFile()
{
EXBYTE unitInfoBuff[16];
/* write version numbers and signature */
if(dataHeader.dataType==DT_INIT)
{
ExMemSet(pMain,0,16);
pMain[0]='V';
pMain[1]=(EXBYTE)(VER_TFFS>>8);
pMain[2]=(EXBYTE)VER_TFFS;
pMain[4]='V';
pMain[5]=(EXBYTE)VER_DIMAGE;
pMain[6]=(EXBYTE)(VER_DIMAGE>>8);
pMain[7]=(EXBYTE)(VER_DIMAGE>>16);
ExMemCpy(pMain+8,"MSYSTEMS",8);
return WriteSerialFileDevice(¶ms.imageDevTar,pMain,16);
}
/* write data header*/
DataHeader2Buffer(&dataHeader,unitInfoBuff);
CheckStat(WriteSerialFileDevice(¶ms.imageDevTar,unitInfoBuff,16));
switch(dataHeader.dataType)
{
case DT_FORMAT:
{
EXBYTE bPart;
MediaHeader2Buffer(&mediaHeader,pMain);
for(bPart=0;bPart<mediaHeader.bBdks+mediaHeader.bBdtls;bPart++)
PartitionHeader2Buffer(&pPartitionHeader[bPart],pMain+MEDIA_HEADER_SIZE+PARTITION_HEADER_SIZE*bPart);
break;
}
case DT_OTP:
break;
case DT_IPL:
break;
case DT_BDK:
break;
case DT_BDTL:
break;
case DT_LAST:
break;
}
if(dataHeader.wDataLen!=0)
{
EXWORD wDataLen=(dataHeader.wDataLen>>4)<<4;
if(wDataLen!=dataHeader.wDataLen)
wDataLen+=16;
CheckStat(WriteSerialFileDevice(¶ms.imageDevTar,pMain,wDataLen));
}
return EX_OK;
}
#endif
#ifndef PUTIMAGE
IOreq* EXAPI IoreqSrc(FLHandle irHandle,unsigned int irFlags,void EXFAR*irData,long irLength,long irCount)
{
ioreqSrc.irHandle=(irHandle<<4)+params.bSocketSrc;
ioreqSrc.irFlags=irFlags;
ioreqSrc.irData=irData;
ioreqSrc.irLength=irLength;
ioreqSrc.irCount=irCount;
return &ioreqSrc;
}
#endif
IOreq* EXAPI IoreqTar(FLHandle irHandle,unsigned int irFlags,void EXFAR*irData,long irLength,long irCount)
{
ioreqTar.irHandle=(irHandle<<4)+params.bSocketTar;
ioreqTar.irFlags=irFlags;
ioreqTar.irData=irData;
ioreqTar.irLength=irLength;
ioreqTar.irCount=irCount;
return &ioreqTar;
}
/************** IO interface functions *************/
FLStatus ProgressCallback(EXWORD totalUnitsToFormat, EXWORD totalUnitsFormattedSoFar)
{
/* Make sure progress is increamental and print it */
if(units<totalUnitsFormattedSoFar)
{
WritePrgBarDevice(&progDev,totalUnitsFormattedSoFar);
units=totalUnitsFormattedSoFar;
}
return flOK;
}
#ifndef PUTIMAGE
static void MediaHeader2Buffer(MediaHeader*fh,EXBYTE*pBuff)
{
ExMemSet(pBuff,0,MEDIA_HEADER_SIZE);
pBuff[0]=(EXBYTE)fh->wFlashType;
pBuff[1]=(EXBYTE)(fh->wFlashType>>8);
pBuff[2]=(EXBYTE)fh->dwMediaSize;
pBuff[3]=(EXBYTE)(fh->dwMediaSize>>8);
pBuff[4]=(EXBYTE)(fh->dwMediaSize>>16);
pBuff[5]=(EXBYTE)(fh->dwMediaSize>>24);
pBuff[6]=(EXBYTE)fh->dwOsakver;
pBuff[7]=(EXBYTE)(fh->dwOsakver>>8);
pBuff[8]=(EXBYTE)(fh->dwOsakver>>16);
pBuff[9]=(EXBYTE)(fh->dwOsakver>>24);
pBuff[10]=fh->bFloors;
pBuff[11]=fh->bMediaType;
pBuff[12]=fh->bPercentUsed;
pBuff[13]=fh->bBdtls;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -