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

📄 ftllite.c

📁 truefs for vxworks, make fs on flash or rom
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Changes an entry in the virtual map					*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorNo	: Virtual sector no. whose entry is changed.	*//*	newAddress	: Logical sector no. to assign in Virtual Map.	*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus setVirtualMap(Flare vol,			    VirtualSectorNo sectorNo,			    LogicalSectorNo newAddress){  unsigned pageNo;  int sectorInPage;  CardAddress virtualMapEntryAddress;  LEulong addressToWrite;  LogicalAddress oldAddress;  LogicalSectorNo updatedPage;    vol.mappedSectorNo = UNASSIGNED_SECTOR;    if(sectorNo < vol.directAddressingSectors)    {        checkStatus(deleteLogicalSector(&vol,vol.pageTable[sectorNo]));        vol.pageTable[sectorNo] = newAddress;    return flOK;  }  sectorNo -= vol.noOfPages;  pageNo = sectorNo >> (PAGE_SIZE_BITS - SECTOR_SIZE_BITS);  sectorInPage = (int) (sectorNo) % ADDRESSES_PER_SECTOR;  updatedPage = vol.pageTable[pageNo];  virtualMapEntryAddress = logical2Physical(&vol,updatedPage) +				 sectorInPage * sizeof(LogicalAddress);  oldAddress = LE4(*(LEulong FAR0 *)	vol.flash.map(&vol.flash,virtualMapEntryAddress,sizeof(LogicalAddress)));    /* kick out early. EAN */    if(newAddress == DELETED_ADDRESS && ((unsigned long)oldAddress == DELETED_ADDRESS))        return flOK;        if(oldAddress == DELETED_ADDRESS && vol.replacementPageNo == pageNo)    {        updatedPage = vol.replacementPageAddress;        virtualMapEntryAddress = logical2Physical(&vol,updatedPage) +				   sectorInPage * sizeof(LogicalAddress);    oldAddress = LE4(*(LEulong FAR0 *)	  vol.flash.map(&vol.flash,virtualMapEntryAddress,sizeof(LogicalAddress)));  }    if(newAddress == DELETED_ADDRESS && ((unsigned long)oldAddress == UNASSIGNED_ADDRESS))        return flOK;        /* kick out early. EAN */    if(newAddress == DELETED_ADDRESS && ((unsigned long)oldAddress == DELETED_ADDRESS))        return flOK;  toLE4(addressToWrite,(LogicalAddress) newAddress << SECTOR_SIZE_BITS);    if(cannotWriteOver(LE4(addressToWrite),oldAddress))    {        FLStatus status;        if(pageNo != vol.replacementPageNo ||           updatedPage == vol.replacementPageAddress)        {            if(vol.replacementPageNo != UNASSIGNED_SECTOR)	checkStatus(closeReplacementPage(&vol));      checkStatus(allocateAndWriteSector(&vol,pageNo,NULL,TRUE));    }    status = flashWrite(&vol,			logical2Physical(&vol,vol.replacementPageAddress) +				      sectorInPage * sizeof(LogicalAddress),			&addressToWrite,			sizeof addressToWrite,                            0);        if(status != flOK)        {            closeReplacementPage(&vol);				/* we may get a write-error because a				   previous cache update did not complete. */      return status;    }    toLE4(addressToWrite,DELETED_ADDRESS);    updatedPage = vol.pageTable[pageNo];  }  checkStatus(flashWrite(&vol,			 logical2Physical(&vol,updatedPage) +				   sectorInPage * sizeof(LogicalAddress),			 &addressToWrite,			 sizeof addressToWrite,			 (unsigned long)oldAddress != UNASSIGNED_ADDRESS));#ifndef SINGLE_BUFFER  if (buffer.sectorNo == pageNo && buffer.owner == &vol)    toLE4(mapCache[sectorInPage],(LogicalAddress) newAddress << SECTOR_SIZE_BITS);#endif  return deleteLogicalSector(&vol,(LogicalSectorNo) (oldAddress >> SECTOR_SIZE_BITS));}/*----------------------------------------------------------------------*//*      	     c h e c k F o r W r i t e I n p l a c e		*//*									*//* Checks possibility for writing Flash data inplace.			*//*									*//* Parameters:                                                          *//*	newData		: New data to write.				*//*	oldData		: Old data at this location.			*//*                                                                      *//* Returns:                                                             *//*	< 0	=>	Writing inplace not possible			*//*	>= 0	=>	Writing inplace is possible. Value indicates    *//*			how many bytes at the start of data are		*//*			identical and may be skipped.			*//*----------------------------------------------------------------------*/static int checkForWriteInplace(long FAR1 *newData,				long FAR0 *oldData){  int i;  int skipBytes = 0;    FLBoolean stillSame = TRUE;    for(i = SECTOR_SIZE / sizeof *newData; i > 0; i--, newData++, oldData++)    {        if(cannotWriteOver(*newData,*oldData))            return -1;    if (stillSame && *newData == *oldData)      skipBytes += sizeof *newData;    else      stillSame = FALSE;  }  return skipBytes;}/*----------------------------------------------------------------------*//*      	              i n i t F T L				*//*									*//* Initializes essential volume data as a preparation for mount or	*//* format.								*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus initFTL(Flare vol){  long int size = 1;  for (vol.erasableBlockSizeBits = 0; size < vol.flash.erasableBlockSize;       vol.erasableBlockSizeBits++, size <<= 1);  vol.unitSizeBits = vol.erasableBlockSizeBits;  if (vol.unitSizeBits < 16)    vol.unitSizeBits = 16;		/* At least 64 KB */  vol.noOfUnits = (unsigned) ((vol.flash.noOfChips * vol.flash.chipSize) >> vol.unitSizeBits);  vol.unitOffsetMask = (1L << vol.unitSizeBits) - 1;  vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS);  vol.bamOffset = sizeof(UnitHeader);  vol.unitHeaderSectors = ((allocEntryOffset(&vol,vol.sectorsPerUnit) - 1) >>				    SECTOR_SIZE_BITS) + 1;  vol.transferUnit = NULL;  vol.replacementPageNo = UNASSIGNED_SECTOR;  vol.badFormat = TRUE;	/* until mount completes */  vol.mappedSectorNo = UNASSIGNED_SECTOR;  vol.currWearLevelingInfo = 0;#ifdef BACKGROUND  vol.unitEraseInProgress = NULL;  vol.garbageCollectStatus = flOK;  vol.mirrorOffset = 0;#endif  return flOK;}/*----------------------------------------------------------------------*//*      	            i n i t T a b l e s				*//*									*//* Allocates and initializes the dynamic volume table, including the	*//* unit tables and secondary virtual map.				*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus initTables(Flare vol){  VirtualSectorNo iSector;  UnitNo iUnit;  /* Allocate the conversion tables */#ifdef MALLOC_TFFS/** sjk - Added fix for SPR # 79468 **/   if ( vol.physicalUnits )    free (vol.physicalUnits);  if ( vol.logicalUnits )    free (vol.logicalUnits);  if ( vol.pageTable )    free ( vol.pageTable );  vol.physicalUnits = (Unit *) MALLOC_TFFS(vol.noOfUnits * sizeof(Unit));  vol.logicalUnits = (UnitPtr *) MALLOC_TFFS(vol.noOfUnits * sizeof(UnitPtr));  vol.pageTable = (LogicalSectorNo *)	     MALLOC_TFFS(vol.directAddressingSectors * sizeof(LogicalSectorNo));  if (vol.physicalUnits == NULL ||      vol.logicalUnits == NULL ||      vol.pageTable == NULL)    return flNotEnoughMemory;#else  char *heapPtr;  heapPtr = vol.heap;  vol.physicalUnits = (Unit *) heapPtr;  heapPtr += vol.noOfUnits * sizeof(Unit);  vol.logicalUnits = (UnitPtr *) heapPtr;  heapPtr += vol.noOfUnits * sizeof(UnitPtr);  vol.pageTable = (LogicalSectorNo *) heapPtr;  heapPtr += vol.directAddressingSectors * sizeof(LogicalSectorNo);  if (heapPtr > vol.heap + sizeof vol.heap)    return flNotEnoughMemory;#endif#ifndef SINGLE_BUFFER  vol.volBuffer = flBufferOf(flSocketNoOf(vol.flash.socket));#endif  buffer.sectorNo = UNASSIGNED_SECTOR;  for (iSector = 0; iSector < vol.directAddressingSectors; iSector++)    vol.pageTable[iSector] = UNASSIGNED_SECTOR;  for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++)    vol.logicalUnits[iUnit] = NULL;  return flOK;}/*----------------------------------------------------------------------*//*      	             m a p S e c t o r				*//*									*//* Maps and returns location of a given sector no.			*//* NOTE: This function is used in place of a read-sector operation.	*//*									*//* A one-sector cache is maintained to save on map operations.		*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorNo	: Sector no. to read				*//*	physAddress	: Optional pointer to receive sector address	*//*                                                                      *//* Returns:                                                             *//*	Pointer to physical sector location. NULL returned if sector	*//*	does not exist.							*//*----------------------------------------------------------------------*/static const void FAR0 *mapSector(Flare vol, SectorNo sectorNo, CardAddress *physAddress){    if(sectorNo != vol.mappedSectorNo || vol.flash.socket->remapped)    {        LogicalSectorNo sectorAddress;        if(sectorNo >= vol.virtualSectors)        {            dbgMsg(DEBUG_LIGHT,"mapSector:  sectorNo >= vol.virtualSectors\n",0,0,0,0,0,0);            vol.mappedSector = NULL;        }        else        {            sectorAddress = virtual2Logical(&vol,sectorNo + vol.noOfPages);            if(sectorAddress == UNASSIGNED_SECTOR || sectorAddress == DELETED_SECTOR)            {                vol.mappedSector = NULL;    /* no such sector */            }            else            {	vol.mappedSectorAddress = logical2Physical(&vol,sectorAddress);	vol.mappedSector = vol.flash.map(&vol.flash,					 vol.mappedSectorAddress,					 SECTOR_SIZE);                if(vol.mappedSector == NULL)                  {                   dbgMsg(DEBUG_LIGHT,"mapSector:  vol.flash.map returns NULL.\n",0,0,0,0,0,0);                  }      }    }    vol.mappedSectorNo = sectorNo;    vol.flash.socket->remapped = FALSE;  }  if (physAddress)    *physAddress = vol.mappedSectorAddress;  return vol.mappedSector;}/*----------------------------------------------------------------------*//*      	          w r i t e S e c t o r				*//*									*//* Writes a sector.							*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorNo	: Sector no. to write				*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus writeSector(Flare vol,  SectorNo sectorNo, void FAR1 *fromAddress){  LogicalSectorNo oldSectorAddress;  int skipBytes;  FLStatus status;  if (vol.badFormat)    return flBadFormat;  if (sectorNo >= vol.virtualSectors)    return flSectorNotFound;  sectorNo += vol.noOfPages;  oldSectorAddress = virtual2Logical(&vol,sectorNo);    if(oldSectorAddress != UNASSIGNED_SECTOR && oldSectorAddress != DELETED_SECTOR &&       (skipBytes = checkForWriteInplace((long FAR1 *) fromAddress,                                         (long FAR0 *) mapLogical(&vol,oldSectorAddress))) >= 0)    {        if(skipBytes < SECTOR_SIZE)            status = flashWrite(&vol,                                logical2Physical(&vol,oldSectorAddress) + skipBytes,			  (char FAR1 *) fromAddress + skipBytes,			  SECTOR_SIZE - skipBytes,			  OVERWRITE);    else      status = flOK;		/* nothing to write */  }  else    status = allocateAndWriteSector(&vol,sectorNo,fromAddress,FALSE);  if (status == flWriteFault)		/* Automatic retry */    status = allocateAndWriteSector(&vol,sectorNo,fromAddress,FALSE);  return status;}/*----------------------------------------------------------------------*//*      	          t l S e t B u s y				*//*									*//* Notifies the start and end of 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -