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

📄 ftllite.c

📁 该程序是一个tffs文件系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorNo	: BAM entry no.					*//*                                                                      *//* Returns:                                                             *//*	Offset of BAM entry in unit					*//*----------------------------------------------------------------------*/static int allocEntryOffset(Flare vol, int sectorNo){  return (int) (vol.bamOffset + sizeof(VirtualAddress) * sectorNo);}/*----------------------------------------------------------------------*//*		         m a p U n i t H e a d e r 			*//*									*//* Map a unit header and return pointer to it.				*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	unit		: Unit to map header				*//*                                                                      *//* Returns:                                                             *//*	Pointer to mapped unit header					*//*	blockAllocMap	: (optional) Pointer to mapped BAM		*//*----------------------------------------------------------------------*/static UnitHeader FAR0 *mapUnitHeader(Flare vol,				     const Unit *unit,				     LEulong FAR0 **blockAllocMap){  UnitHeader FAR0 *unitHeader;  int length = sizeof(UnitHeader);  if (blockAllocMap)    length = allocEntryOffset(&vol,vol.sectorsPerUnit);  unitHeader = (UnitHeader FAR0 *) vol.flash.map(&vol.flash,physicalBase(&vol,unit),length);  if (blockAllocMap)    *blockAllocMap = (LEulong FAR0 *) ((char FAR0 *) unitHeader + allocEntryOffset(&vol,0));  return unitHeader;}#ifndef SINGLE_BUFFER/*----------------------------------------------------------------------*//*		          s e t u p M a p C a c h e			*//*									*//* Sets up map cache sector to contents of specified Virtual Map page	*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	pageNo		: Page no. to copy to map cache			*//*                                                                      *//*----------------------------------------------------------------------*/static void setupMapCache(Flare vol,  VirtualSectorNo pageNo){  vol.flash.read(&vol.flash,logical2Physical(&vol,vol.pageTable[pageNo]),mapCache,SECTOR_SIZE,0);  if (pageNo == vol.replacementPageNo) {    int i;    LEulong FAR0 *replacementPage =	(LEulong FAR0 *) mapLogical(&vol,vol.replacementPageAddress);    for (i = 0; (unsigned)i < ADDRESSES_PER_SECTOR; i++) {      if (LE4(mapCache[i]) == DELETED_ADDRESS)	toLE4(mapCache[i],LE4(replacementPage[i]));    }  }  buffer.sectorNo = pageNo;  buffer.owner = &vol;}#endif/*----------------------------------------------------------------------*//*		        v i r t u a l 2 L o g i c a l			*//*									*//* Translates virtual sector no. to logical sector no.			*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorNo	: Virtual sector no.				*//*                                                                      *//* Returns:                                                             *//*	Logical sector no. corresponding to virtual sector no.		*//*----------------------------------------------------------------------*/static LogicalSectorNo virtual2Logical(Flare vol,  VirtualSectorNo sectorNo){  LogicalAddress virtualMapEntry;  if (sectorNo < vol.directAddressingSectors)    return vol.pageTable[sectorNo];  else {    unsigned pageNo;    int sectorInPage;    sectorNo -= vol.noOfPages;    pageNo = (int) (sectorNo >> (PAGE_SIZE_BITS - SECTOR_SIZE_BITS));    sectorInPage = (int) (sectorNo) % ADDRESSES_PER_SECTOR;    {#ifdef SINGLE_BUFFER      LogicalAddress FAR0 *virtualMapPage;      virtualMapPage = (LogicalAddress FAR0 *) mapLogical(&vol, vol.pageTable[pageNo]);      if (pageNo == vol.replacementPageNo &&	  virtualMapPage[sectorInPage] == DELETED_ADDRESS)	virtualMapPage = (LogicalAddress FAR0 *) mapLogical(&vol, vol.replacementPageAddress);      virtualMapEntry = LE4(virtualMapPage[sectorInPage]);#else      if (buffer.sectorNo != pageNo || buffer.owner != &vol)	setupMapCache(&vol,pageNo);      virtualMapEntry = LE4(mapCache[sectorInPage]);#endif      return (LogicalSectorNo) (virtualMapEntry >> SECTOR_SIZE_BITS);    }  }}/*----------------------------------------------------------------------*//*		          v e r i f y F o r m a t 			*//*									*//* Verify an FTL unit header.						*//*                                                                      *//* Parameters:                                                          *//*	unitHeader	: Pointer to unit header			*//*                                                                      *//* Returns:                                                             *//*	TRUE if header is correct. FALSE if not.			*//*----------------------------------------------------------------------*/static FLBoolean verifyFormat(UnitHeader FAR0 *unitHeader){  FORMAT_PATTERN[6] = unitHeader->formatPattern[6];	/* TPL_LINK */  return tffscmp(unitHeader->formatPattern + 2,		 FORMAT_PATTERN + 2,		 sizeof unitHeader->formatPattern - 2) == 0;}/*----------------------------------------------------------------------*//*		          f o r m a t U n i t				*//*									*//* Formats a unit by erasing it and writing a unit header.		*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	unit		: Unit to format				*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus formatUnit(Flare vol,  Unit *unit){  unsigned unitHeaderLength = allocEntryOffset(&vol,vol.unitHeaderSectors);  unit->noOfFreeSectors = FREE_UNIT;  unit->noOfGarbageSectors = 0;#ifdef BACKGROUND  {    FLStatus status;    vol.unitEraseInProgress = unit;    status = vol.flash.erase(&vol.flash,			 (int) (physicalBase(&vol,unit) >> vol.erasableBlockSizeBits),			 1 << (vol.unitSizeBits - vol.erasableBlockSizeBits));    vol.unitEraseInProgress = NULL;    if (status != flOK)      return status;    /* Note: This suspend to the foreground is not only nice to have, it is       necessary ! The reason is that we may have a write from the buffer       waiting for the erase to complete. We are next going to overwrite the       buffer, so this break enables the write to complete before the data is       clobbered (what a relief). */    while (flForeground(1) == BG_SUSPEND)      ;  }#else  checkStatus(vol.flash.erase(&vol.flash,			  (int) (physicalBase(&vol,unit) >> vol.erasableBlockSizeBits),			  1 << (vol.unitSizeBits - vol.erasableBlockSizeBits)));#endif  /* We will copy the unit header as far as the format entries of the BAM     from another unit (logical unit 0) */#ifdef SINGLE_BUFFER  if (buffer.dirty)    return flBufferingError;#endif  buffer.sectorNo = UNASSIGNED_SECTOR;    /* Invalidate map cache so we can					     use it as a buffer */  if (vol.logicalUnits[vol.firstPhysicalEUN]) {    vol.flash.read(&vol.flash,	       physicalBase(&vol,vol.logicalUnits[vol.firstPhysicalEUN]),	       uh,	       unitHeaderLength,	       0);  }  toLE4(uh->wearLevelingInfo,++vol.currWearLevelingInfo);  toLE2(uh->logicalUnitNo,UNASSIGNED_UNIT_NO);  checkStatus(vol.flash.write(&vol.flash,			  physicalBase(&vol,unit),			  uh,			  unitHeaderLength,			  0));  return flOK;}#ifdef BACKGROUND/*----------------------------------------------------------------------*//*		          f l a s h W r i t e				*//*									*//* Writes to flash through flash.write, but, if possible, allows a	*//* background erase to continue while writing.				*//*                                                                      *//* Parameters:                                                          *//*	Same as flash.write						*//*          								*//* Returns:                                                             *//*	Same as flash.write						*//*----------------------------------------------------------------------*/static FLStatus flashWrite(Flare vol,			 CardAddress address,			 const void FAR1 *from,			 int length,			 FLBoolean overwrite){  if (vol.mirrorOffset != 0 &&      address >= vol.mirrorFrom && address < vol.mirrorTo) {    checkStatus(flashWrite(&vol,			   address + vol.mirrorOffset,			   from,			   length,			   overwrite));  }  if (vol.unitEraseInProgress) {    CardAddress startChip = physicalBase(&vol,vol.unitEraseInProgress) &				(-vol.flash.interleaving * vol.flash.chipSize);    CardAddress endChip = startChip + vol.flash.interleaving * vol.flash.chipSize;    if (address < startChip || address >= endChip) {      flBackground(BG_RESUME);      checkStatus(vol.flash.write(&vol.flash,address,from,length,overwrite));      flBackground(BG_SUSPEND);      return flOK;    }    else if (!(vol.flash.flags & SUSPEND_FOR_WRITE)) {      do {	flBackground(BG_RESUME);      } while (vol.unitEraseInProgress);    }  }  return vol.flash.write(&vol.flash,address,from,length,overwrite);}#else#define flashWrite(v,address,from,length,overwrite)	\		(v)->flash.write(&(v)->flash,address,from,length,overwrite)#endif	/* BACKGROUND *//*----------------------------------------------------------------------*//*		           m o u n t U n i t				*//*									*//* Performs mount scan for a single unit				*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	unit		: Unit to mount					*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus mountUnit(Flare vol,  Unit *unit){  unsigned i;  LogicalSectorNo sectorAddress;  LEulong FAR0 *blockAllocMap;  UnitHeader FAR0 *unitHeader = mapUnitHeader(&vol,unit,&blockAllocMap);  UnitNo logicalUnitNo = LE2(unitHeader->logicalUnitNo);  unit->noOfGarbageSectors = 0;  unit->noOfFreeSectors = FREE_UNIT;  if (!verifyFormat(unitHeader) ||      ((logicalUnitNo != UNASSIGNED_UNIT_NO) &&       ((logicalUnitNo >= vol.noOfUnits) ||        (logicalUnitNo < vol.firstPhysicalEUN) ||        vol.logicalUnits[logicalUnitNo]))) {    if (vol.transferUnit == NULL)      vol.transferUnit = unit;    return flBadFormat;  }  if (logicalUnitNo == UNASSIGNED_UNIT_NO) {    vol.transferUnit = unit;    return flOK;		/* this is a transfer unit */  }  if (LE4(unitHeader->wearLevelingInfo) > vol.currWearLevelingInfo &&      LE4(unitHeader->wearLevelingInfo) != 0xffffffffl)    vol.currWearLevelingInfo = LE4(unitHeader->wearLevelingInfo);  /* count sectors and setup virtual map */  sectorAddress =     ((LogicalSectorNo) logicalUnitNo << (vol.unitSizeBits - SECTOR_SIZE_BITS));  unit->noOfFreeSectors = 0;  for (i = 0; i < vol.sectorsPerUnit; i++, sectorAddress++) {    VirtualAddress allocMapEntry = LE4(blockAllocMap[i]);    if (allocMapEntry == GARBAGE_SECTOR || (unsigned long)allocMapEntry == ALLOCATED_SECTOR)      unit->noOfGarbageSectors++;    else if ((unsigned long)allocMapEntry == FREE_SECTOR) {      unit->noOfFreeSectors++;      vol.totalFreeSectors++;    }    else if (allocMapEntry < vol.directAddressingMemory) {      char signature = (short) (allocMapEntry) & SECTOR_OFFSET_MASK;      if (signature == DATA_SECTOR || signature == REPLACEMENT_PAGE) {	int pageNo = (int) (allocMapEntry >> SECTOR_SIZE_BITS) + vol.noOfPages;	if (pageNo >= 0)	  if (signature == DATA_SECTOR)	    vol.pageTable[pageNo] = sectorAddress;	  else {	    vol.replacementPageAddress = sectorAddress;	    vol.replacementPageNo = pageNo;	  }      }    }  }  /* Place the logical mapping of the unit */  vol.mappedSectorNo = UNASSIGNED_SECTOR;  vol.logicalUnits[logicalUnitNo] = unit;  return flOK;}/*----------------------------------------------------------------------*//*		           a s s i g n U n i t				*//*									*//* Assigns a logical unit no. to a unit					*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	unit		: Unit to assign				*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus assignUnit(Flare vol,  Unit *unit, UnitNo logicalUnitNo){  LEushort unitNoToWrite;

⌨️ 快捷键说明

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