⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imgsftal.c

📁 M-System DOC(Disk on a Chip) Flash芯片映像读写工具, 可以进行二片Flash芯片的内容互相拷贝, 提高烧录程序的效率.
💻 C
📖 第 1 页 / 共 3 页
字号:
#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(&params.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(&params.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(&params.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(&params.imageDevTar,pMain,16);
	}

	/* write data header*/
	DataHeader2Buffer(&dataHeader,unitInfoBuff);
	CheckStat(WriteSerialFileDevice(&params.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(&params.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 + -