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

📄 imgsftal.c

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