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

📄 ftllite.c

📁 truefs for vxworks, make fs on flash or rom
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ftllite.c - True Flash File System *//* Copyright 1984-2004 Wind River Systems, Inc. */#include "copyright_wrs.h"/* FAT-FTL Lite Software Development Kit * Copyright (C) M-Systems Ltd. 1995-1997	*//*modification history--------------------01i,12may05,jb3  Fix compile error01h,06may05,jb3  Changes  for  Datalight Reliance01g,06oct04,pmr  turned off debugging.01f,29jul04,alr  removed compilation warnings01e,29jul04,alr  modified format header to ignore first 4 bytes                 (detection could break first 4 bytes in unit 0)01d,29jul04,alr  modified format header to-do aligned writes                 (some MTDs don't allow mis-aligned writes)01c,29jul04,alr  added sjk memory leak patch01b,29jul04,alr  added (EAN) TFFS patches01a,29jul04,alr  modified file header, restarted history*/#include "backgrnd.h"#include "flflash.h"#include "flbuffer.h"#include "fltl.h"#include "stdio.h"#include "logLib.h"/* better debug routines.  EAN */#define DEBUG_LIGHT  1#define DEBUG_NORMAL 2#define DEBUG_INSANE 4#define DEBUG_LEVEL_LIGHT  1  /* only corruptions reported */#define DEBUG_LEVEL_NORMAL 3  /* corruptions and out of norms reported */#define DEBUG_LEVEL_INSANE 7  /* everything reported */#undef  DEBUG_FTL                       /* turn on/off debug messages */#define DEBUG_LEVEL DEBUG_LEVEL_INSANE  /* set debug level */#ifdef DEBUG_FTL/* sjk changed printf to logMsg */#define dbgMsg(num,msg,var1,var2,var3,var4,var5,var6) if(num & DEBUG_LEVEL) logMsg(msg,var1,var2,var3,var4,var5,var6);#else#define dbgMsg(num,msg,var1,var2,var3,var4,var5,var6)#endif/*  Implementation constants and type definitions */#define SECTOR_OFFSET_MASK (SECTOR_SIZE - 1)typedef long int LogicalAddress;	/* Byte address of media in logical					   unit no. order. */typedef long int VirtualAddress;	/* Byte address of media as specified					   by Virtual Map. */typedef SectorNo LogicalSectorNo;	/* A logical sector no. is given					   by dividing its logical address by					   the sector size */typedef SectorNo VirtualSectorNo;	/* A virtual sector no. is such that					   the first page is no. 0, the 2nd					   is 1 etc.					   The virtual sector no. is given					   by dividing its virtual address by					   the sector size and adding the					   number of pages (result always					   positive). */typedef unsigned short UnitNo;#define ADDRESSES_PER_SECTOR (SECTOR_SIZE / sizeof(LogicalAddress))#define UNASSIGNED_ADDRESS 0xffffffffl#define DELETED_ADDRESS 0#define	DELETED_SECTOR	0#define PAGE_SIZE_BITS (SECTOR_SIZE_BITS + (SECTOR_SIZE_BITS - 2))#define PAGE_SIZE (1L << PAGE_SIZE_BITS)/* Unit descriptor record */#define UNASSIGNED_UNIT_NO 0xffff#define MARKED_FOR_ERASE 0x7ffftypedef struct{    short     noOfFreeSectors;    short         noOfGarbageSectors;} Unit;typedef Unit *UnitPtr;/* Structure of data on a unit */#define FREE_SECTOR	0xffffffffl#define GARBAGE_SECTOR	0#define ALLOCATED_SECTOR 0xfffffffel#define	FORMAT_SECTOR	0x30#define DATA_SECTOR	0x40#define	REPLACEMENT_PAGE 0x60#define BAD_SECTOR	0x70static char FORMAT_PATTERN[15] = {0x13, 3, 'C', 'I', 'S',    0x46, 57, 0, 'F', 'T', 'L', '1', '0', '0', 0};typedef struct{    char      formatPattern[15];    unsigned char noOfTransferUnits;  /* no. of transfer units */    LEulong   wearLevelingInfo;  LEushort	logicalUnitNo;  unsigned char	log2SectorSize;  unsigned char	log2UnitSize;  LEushort	firstPhysicalEUN;	/* units reserved for boot image */  LEushort	noOfUnits;		/* no. of formatted units */  LEulong	virtualMediumSize;	/* virtual size of volume */  LEulong	directAddressingMemory;	/* directly addressable memory */  LEushort	noOfPages;		/* no. of virtual pages */  unsigned char	flags;  unsigned char	eccCode;  LEulong	serialNumber;  LEulong	altEUHoffset;  LEulong	BAMoffset;  char		reserved[12];  char		embeddedCIS[4];		/* Actual length may be larger. By					   default, this contains FF's */} UnitHeader;/* flags assignments */#define	HIDDEN_AREA_FLAG	1#define	REVERSE_POLARITY_FLASH	2#define	DOUBLE_BAI		4#define dummyUnit ((const UnitHeader *) 0)  /* for offset calculations */#define logicalUnitNoOffset ((char *) &dummyUnit->logicalUnitNo -	\			     (char *) dummyUnit)#ifndef MALLOC_TFFS#define HEAP_SIZE						\		((0x100000l / PAGE_SIZE) *                      \			sizeof(LogicalSectorNo) +               \		 (0x100000l / ASSUMED_FTL_UNIT_SIZE) *          \			(sizeof(Unit) + sizeof(UnitPtr))) *     \		MAX_VOLUME_MBYTES +                             \		(ASSUMED_VM_LIMIT / SECTOR_SIZE) *              \			sizeof(LogicalSectorNo)#endif#define cannotWriteOver(newContents, oldContents)		\		((newContents) & ~(oldContents))struct tTLrec{    FLBoolean     badFormat;      /* true if FTL format is bad */    VirtualSectorNo   totalFreeSectors;   /* Free sectors on volume */  SectorNo		virtualSectors;		/* size of virtual volume */  unsigned int		unitSizeBits;		/* log2 of unit size */  unsigned int		erasableBlockSizeBits;	/* log2 of erasable block size */  UnitNo		noOfUnits;  UnitNo		noOfTransferUnits;  UnitNo		firstPhysicalEUN;  int			noOfPages;  VirtualSectorNo	directAddressingSectors;/* no. of directly addressable sectors */  VirtualAddress 	directAddressingMemory;	/* end of directly addressable memory */  CardAddress		unitOffsetMask;		/* = 1 << unitSizeBits - 1 */  CardAddress		bamOffset;  unsigned int		sectorsPerUnit;  unsigned int		unitHeaderSectors;	/* sectors used by unit header */  Unit *		physicalUnits;		/* unit table by physical no. */  Unit **		logicalUnits;		/* unit table by logical no. */  Unit *		transferUnit;		/* The active transfer unit */  LogicalSectorNo *	pageTable;		/* page translation table */						/* directly addressable sectors */  LogicalSectorNo	replacementPageAddress;  VirtualSectorNo	replacementPageNo;  SectorNo 		mappedSectorNo;  const void FAR0 *	mappedSector;  CardAddress		mappedSectorAddress;  unsigned long		currWearLevelingInfo;#ifdef BACKGROUND  Unit *		unitEraseInProgress;	/* Unit currently being formatted */  FLStatus		garbageCollectStatus;	/* Status of garbage collection */  /* When unit transfer is in the background, and is currently in progress,     all write operations done on the 'from' unit moust be mirrored on the     transfer unit. If so, 'mirrorOffset' will be non-zero and will be the     offset of the alternate address from the original. 'mirrorFrom' and     'mirrorTo' will be the limits of the original addresses to mirror. */  long int		mirrorOffset;  CardAddress		mirrorFrom,			mirrorTo;#endif#ifndef SINGLE_BUFFER  FLBuffer *		volBuffer;		/* Define a sector buffer */#endif  FLFlash		flash;#ifndef MALLOC_TFFS  char			heap[HEAP_SIZE];#endif};typedef TLrec Flare;static Flare vols[DRIVES];#ifdef SINGLE_BUFFERextern FLBuffer buffer;#else#define buffer (*vol.volBuffer)/* Virtual map cache (shares memory with buffer) */#define mapCache	((LEulong *) buffer.data)#endif/* Unit header buffer (shares memory with buffer) */#define uh		((UnitHeader *) buffer.data)/* Transfer sector buffer (shares memory with buffer) */#define sectorCopy 	((LEulong *) buffer.data)#define FREE_UNIT	-0x400	/* Indicates a transfer unit *//*----------------------------------------------------------------------*//*		         p h y s i c a l B a s e			*//*									*//* Returns the physical address of a unit.				*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	unit		: unit pointer					*//*                                                                      *//* Returns:                                                             *//*	physical address of unit					*//*----------------------------------------------------------------------*/static CardAddress physicalBase(Flare vol,  const Unit *unit){  return (CardAddress) (unit - vol.physicalUnits) << vol.unitSizeBits;}/*----------------------------------------------------------------------*//*		      l o g i c a l 2 P h y s i c a l			*//*									*//* Returns the physical address of a logical sector no.			*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	address		: logical sector no.				*//*                                                                      *//* Returns:                                                             *//*	CardAddress	: physical address of sector			*//*----------------------------------------------------------------------*/static CardAddress logical2Physical(Flare vol,  LogicalSectorNo address){  return physicalBase(&vol,vol.logicalUnits[address >> (vol.unitSizeBits - SECTOR_SIZE_BITS)]) |	 (((CardAddress) address << SECTOR_SIZE_BITS) & vol.unitOffsetMask);}/*----------------------------------------------------------------------*//*		            m a p L o g i c a l				*//*									*//* Maps a logical sector and returns pointer to physical Flash location.*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	address		: logical sector no.				*//*                                                                      *//* Returns:                                                             *//*	Pointer to sector on Flash 					*//*----------------------------------------------------------------------*/static void FAR0 *mapLogical(Flare vol, LogicalSectorNo address){  return vol.flash.map(&vol.flash,logical2Physical(&vol,address),SECTOR_SIZE);}/*----------------------------------------------------------------------*//*		        a l l o c E n t r y O f f s e t			*//*									*//* Returns unit offset of given BAM entry				*//*                                                                      *//* 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;

⌨️ 快捷键说明

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