这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 做过Flash嵌入设备文件系统的大虾来指教一下!!

共21条 1/3 1 2 3 跳转至

做过Flash嵌入设备文件系统的大虾来指教一下!!

菜鸟
2006-08-28 17:48:31     打赏
小弟正要开始研究这方面的东西,但是以前从没接触过,也没人给我指导,所以觉得很迷惘,请大家指点指点,如果想要制作类似U盘的Flash设备,需要了解哪些知识,怎样如手,谢谢~



关键词: 做过     Flash     嵌入     设备     文件     系统     大虾         

菜鸟
2006-08-28 18:49:00     打赏
2楼
ECNChina
嵌入式操作系统VxWorks中TFFS文件系统的构建
[ 作者:佚名 | 转贴自:本站原创 | 点击数:637 | 更新时间:2006-1-13 | 文章录入:zhouchang ]
摘要:目前的嵌入式系统多使用FLASH作为主存,因此,如何有效管理FLASH上的数据非常重要。文章以MX29LV160BT芯
片为例,讨论了在VxWorks操作系统下Nor Flash上建立TFFS文件系统的一般步骤,从而为FLASH上的数据管理提供了理想
的选择方式,同时也为开发者和用户升级程序提供了方便。
关键词:VxWorks Flash MTD TFFS 文件系统
嵌入式系统正随着Internet的发展而在各个领域得到广泛的应用,作为一个优秀的操作系统,VxWorks实现了比其他实时操
作系统更好的有效性、商用性、可裁减性以及互操作性,广泛应用在通信、军事、航空、航天等高精尖技术及实时性要求
极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。
如今越来越多的嵌入式操作系统中,通常都使用FLASH作为主存介质。许多开发者和用户为了方便以后升级用户程序,通
常在FLASH上建立TFFS文件系统,建立文件系统后,我们就可以象在windows操作系统下对硬盘操作一样,进行数据的拷
贝、删除以及文件的建立等操作。
NOR和NAND是现在市场上两种主要的非易失闪存技术。Intel于1988年首先开发出NOR flash技术,彻底改变了原先有
EPROM和EEPROM一统天下的局面。NOR的特点是芯片内执行XIP execute In Place,这样应用程序可以直接在flash闪存内运
行,不必再把代码读到系统RAM中。NOR的传输效率很高,在1~4MB的小容量时具有很高的成本效益,因此在嵌入式系
统得到广泛的应用。
一、 TFFS文件系统结构简介
Tornado的TrueFFS是和VxWorks兼容的一种M-Systems Flite实现方式,版本为2.0。它为种类繁多的flash存储设备提供了统一
的块设备接口,并且具有可重入、线程安全的特点,支持大多数流行的CPU构架。有了Tornado的TrueFFS,应用程序对
flash存储设备的读写就好象它们对拥有MS-DOS文件系统的磁碟设备的操作一样。
如图1所示,TrueFFS由核心层(core layer)和三个功能层,翻译层(translation layer),MTD层(MTD layer),socket层
(socket layer)组成。
核心层(Core layer):核心层主要起相互连接其他几层的功能。同时它也可以进行碎片回收、定时器和其他系统资源的维
护。通常WindRiver公司将这部分内容以二进制文件提供。
翻译层主要实现TrueFFS和dosFs之间的高级交互功能。它也包含了控制flash映射到块、wear-leveling、碎片回收和数据完整
性所需的智能化处理功能。目前有三种不同的翻译层模块可供选择。选择哪一种层要看你所用的flash介质是采用NORbased,
还是NAND-based, 或者SSFDC-based技术而定。
  Socket层则是提供TrueFFS和板卡硬件(如flash卡)的接口服务。其名字来源于用户可以插入flash卡的物理插槽。用来
向系统注册socket设备,检测设备拔插,硬件写保护等。后面将详细讲解它的功能。
  MTD层(Memory Technology Drivers)功能主要是实现对具体的flash进行读、写、擦、ID识别等驱动,并设置与flash密
ECNChina
切相关的一些参数。TrueFFS已经包含了支持Intel,AMD以及samsung部分flash芯片的MTD层驱动。新的芯片需要新的MTD支
持,你可以使用一个标准的接口来加入这些驱动。
  以上四部分,我们通常要的工作就是后两层。
  当在VxWorks下配置TrueFFS时,你必须为每一层至少包含一个软件模块。后面我们将详细讨论。
二、 MX29LV160BT芯片上建立TrueFFS文件系统
1、配置相关文件
在此,我以Nor Flash MX29LV160BT为例,开发工具为Tornado2.2 for PPC。要在VxWorks映像中包含TrueFFS文件系统,首
先必须在config.h文件中定义INCLUDE_TFFS。这使得VxWorks的初始化代码调用tffsDrv()来创建管理TrueFFS所需的结构和
全局变量,并为所有挂接了的flash设备注册socket组件驱动。在链接的时候,通过解析与tffsDrv()相关联的符号(symbols)
可以将TrueFFS所必需的软件模块链接到VxWorks映象中。
为了支持TrueFFS,每一个BSP目录下都必须包含一个sysTffs.c文件。它将TrueFFS所有的层(翻译层,socket层和MTD层)链
接到一起并和VxWorks绑定。因此,我必须编辑这个文件并决定哪一种MTD和翻译层模块应该包含到TrueFFS中。即:
#define INCLUDE_MTD_MX29LV /* MX29LV160BT MTD driver */
#define INCLUDE_TL_FTL /* FTL translation layer */
#define FLASH_BASE_ADRS 0x2a10000 /* Flash memory base address */
#undef FLASH_SIZE
#define FLASH_SIZE 0x001f0000 /*Flash memory size,2M(parameter block) */
其他无关的MTD driver包含头都#undef掉,同时定义Flash在系统中的基地址和大小。另外,还必须编辑sysLib.c中的
sysPhysMemDesc[ ]数组,将Flash基地址和大小加入到MMU中,以供将来访问Flash,否则访问Flash会失败。如果BSP目录下
没有sysTffs.c文件,那么我们可以从其他BSP目录下拷贝一个即可,然后做上述修改,其他的内容基本可以不用修改。
接下来需要修改tffsConfig.c文件,为了方便管理,通常我们将src/drv/tffs/目录下该文件拷贝到我们BSP目录下,然后再做出
修改。在MTDidentifyRoutine mtdTable[]表中加入如下语句:
#ifdef INCLUDE_MTD_MX29LV
mx29lvMTDIdentify,
#endif /* INCLUDE_MTD_MX29LV */
并在该文件开头声明。
#ifdef INCLUDE_MTD_MX29LV
FLStatus mx29lvMTDIdentify (FLFlash vol);
#endif /* INCLUDE_MTD_MX29LV */
最后就是将我们的flash相关MTD驱动加入到makefile中。即:
MACH_EXTRA = mx29lvMtd.o
为了方便我们调试MTD驱动,应该在重新编译VxWorks映象前将诸如格式化flash、创建TrueFFS块设备、绑定此块设备到
dosFs所必要的功能包含到VxWorks映像中。比如如下定义:
#define INCLUDE_TFFS
#ifdef INCLUDE_TFFS
#define INCLUDE_TFFS_DOSFS
#define INCLUDE_TFFS_SHOW
#define INCLUDE_DOSFS /* dosFs file system */
#define INCLUDE_SHOW_ROUTINES /* show routines for system facilities*/
#define INCLUDE_TL_FTL
#define INCLUDE_IO_SYSTEM
#define INCLUDE_DISK_UTIL
#endif /* INCLUDE_DOSFS */
2、MTD驱动简介
ECNChina
做了上述配置后,进入VxWorks操作系统后,我们在shell上利用tffsShow工具来显示flash的信息。TffsShow函数最终会调用
MTD驱动中的mx29lvMtdIdentiy( )函数,在mx29lvMtdIdentiy ( )函数主要是通过读取MX29LV160BT芯片的设备和厂商ID来识
别它,然后对FLFlash结构成员进行初始化,最主要的几个参数是:
type
Flash内存的JEDEC ID号。
erasableBlockSize
Flash内存的擦除块大小(字节)。设置这个值时应考虑到interleaving。因此,通常通过如下方法来设置它的大小。
Vol.erasableBlockSize = MX29LV_MTD_SECTOR_SIZE * vol.interleaving;
对于MX29LV160BT,MX29LV_MTD_SECTOR_SIZE为64K字节。
chipSize
使用来构建TrueFFS文件系统的flash实际大小(字节)。
noOfChips
使用来构建TrueFFS文件系统的flash实际片数。
interleaving
Flash内存交叉因子(interleaving factor)。即扩展数据总线的设备数。比如,一个32位数据总线上,我们可以使用4片8位
或2片16位的设备。
map
指向flash内存映射(map)函数。该函数将flash映射到内存区。
read
指向flash内存的读函数。在MTD驱动识别函数中,这个成员函数已经被初始化为缺省的读函数。通常情况下,我们不需
要再初始化它,否则还需要修改很多相关的函数。
write
指向flash内存的写函数。这个成员必须初始化,这是我们要做的一个重要工作。
erase
指向flash内存的擦除函数。这个成员必须初始化,这也是我们要做的一个重要工作。
针对FLFlash结构成员,我们所关心的两个函数就是写和擦除函数。在mx29lvMtdIdentiy()函数中必须有如下定义:
vol.write = mx29lvWrite;
vol.erase = mx29lvErase;
在mx29lvWrite()函数中主要是实现将数据写到flash中。首先需要对扇区进行解锁,然后写入写命令,之后才能进行数据的
写入。最后需要判断数据是否写完。为了确保操作成功,我们应该在写完每个数据后进行数据的比较,比较正确后方能进
行下一个数据的操作。
在mx29lvErase ()函数中主要是实现flash扇区的擦除。如今的flash一般都是按照扇区进行擦除操作的。在擦除操作之前也应该
首先对扇区进行解锁,然后写擦除建立和扇区擦除命令。擦除成功后,flash中的内容应该是0xffff。所以为了确保成功,我
们还是应该在擦除后进行比较,比较正确后方能进入下一个扇区的擦除操作,否则返回擦除错误标志。
所以,对于MTD驱动的调试,基本上就是调试写和擦除两个函数。在调试过程中,我们可以在这两个函数相应位置加入打
印语句来调试。为了能调试这两个函数,我们通过在shell上输入命令tffsDevFormat来格式化flash,tffsDevFormat最终会调用
mx29lvErase和mx29lvWrite函数,如果成功就会返回0,否则返回-1。当然也可以调用tffsDevCreate函数来验证我们的写和擦
除函数的正确性。图2说明了tffsDevCreate调用过程。
在shell上利用tffsShow来验证mx29lvMtdIdentiy。
è tffsShow
0: socket=RFA: type=0x2249, unitSize=0x10000, mediaSize=0x1f0000
value = 49 = 0x31 = "1"
说明已正确识别到MX29LV160BT设备,设备号为0x2249。
三、 建立TFFS设备
1、挂接设备名
MTD驱动调试成功后,我们就可以给flash设备挂接上dos设备名,如下操作:
格式化:
è tffsDevFormat
value = 1
è usrTffsConfig 0,0,”/tffs0”
value = 0
然后通过devs来查看挂接的设备名。
è devs
drv name
0 /null
1 /tyCo/0
1 /tyCo/1
5 host:
6 /pty/rlogin.S
7 /pty/rlogin.M
3 /tffs0/
8 /vio
value = 25 = 0x19
看到/tffs0/说明挂接设备已经成功,接下来就可以利用dosFs文件系统相关命令来操作flash了。如,ls、copy等。
2、从Flash中启动并下载VxWorks映像
要从flash中下载VxWorks映像,首先需要把VxWorks映像拷贝到flash中,在shell中的操作命令为copy “VxWorks”,”/tffs0/
VxWorks”,然后修改config.h文件中引导行,如下:
#define DEFAULT_BOOT_LINE \
"tffs=0,0(0,0)host:/tffs0/VxWorks h=192.168.0.153 e=192.168.0.154 u=target pw=target o=cpm"
修改完后,重新编译生成bootrom_uncmp.bin,并把它烧写到flash中(注意:该flash与上面建立TFFS文件系统的flash不一
样,它并没有建立文件系统)。然后重新启动,即可看到如下启动画面:
ECNChina
boot device : tffs=0,0
unit number : 0
processor number : 0
host name : host
file name : /tffs0/VxWorks
inet on ethernet (e) : 192.168.0.154
host inet (h) : 192.168.0.153
user (u) : target
ftp password (pw) : target
flags (f) : 0x0
other (o) : cpm
Attaching to TFFS... done.
Loading /tffs0/VxWorks...894304
Starting at 0x10000...
Development System
VxWorks version 5.5.1
KERNEL: WIND version 2.6
Copyright Wind River Systems, Inc., 1984-2003
CPU: Motorola ADS - PowerPC 860. Processor #0.
Memory Size: 0x1000000. BSP version 1.2/5.
WDB Comm Type: WDB_COMM_END
WDB: Ready.
到此,说明引导成功。flash整个TFFS文件系统就已经建立成功。
四、 结论
VxWorks操作系统中支持TFFS文件系统,我们将VxWorks映像作为文件放到flash上,这就有利于开发者和用户更新应用程
序而不需要影响bootrom,直接更新VxWorks映像或者将应用程序直接copy到flash中,然后装载到RAM中运行。


菜鸟
2007-03-28 14:23:00     打赏
3楼
如果要做U盘,则没有什么好选择,只能用FAT。如果是采用Linux,JFFS或YAFFS是不错的选择。如果内存很有限,可以试试UFFS。

菜鸟
2007-03-28 17:03:00     打赏
4楼
TFFS有个最新的补丁,打上之后可以解决大部分由于操作过程中复位引起的问题。TFFS跟dosFS配合在vxWorks上使用还是很不错的。

菜鸟
2007-03-28 20:53:00     打赏
5楼

呵呵,精华贴啊,有点牵强,不过还是很高兴,再补几篇文档吧。


[align=right][color=#000066][此贴子已经被作者于2007-3-28 13:06:25编辑过][/color][/align]

菜鸟
2007-03-28 20:53:00     打赏
6楼

TFFS的几个基本的概念以及实现

a) 垃圾回收

Flash是一种不对称的存储器,读取速度快,写入速度慢,并且只能向1的位置写入0,把0写为1需要先做擦除操作。擦除的最小单位是Block,即TFFS里面的Unit,一般一个Unit有32K或64K,或者更大。

删除文件的时候,文件不一定刚好占用一个Unit,所以不能直接擦除,通常的做法是把它占用的Sector置为垃圾(garbage)。这样垃圾就产生了。当修改一个文件或者记录的时候,理想的做法应该是在原来的位置写入,把原来的内容覆盖掉,但是由于Flash本身的特点,往往覆盖会失败。TFFS的做法是重新分配的一个新的Sector,新Sector使用了旧Sector的序号,旧Sector也会被置为垃圾。随着文件内容的删除、修改和上层操作系统记录的修改,垃圾会越来越多。如果不及时清理,会导致可用空间耗尽,文件系统崩溃。

垃圾回收是针对存在垃圾的Unit,把正常的Sector拷贝到一个干净的Unit里面,然后把旧的Unit擦除。Flash的寿命是以擦写次数来计算的,频繁做垃圾回收必然会降低Flash的寿命。所以为了延长使用寿命,同时也为了提高读写的效率,vxWorks里一直等到正常Sector耗尽了才会去做垃圾回收。被回收Unit的选择,vxWorks里面提供了两种衡量标准,一种选择是垃圾最多的Unit,每个Unit的管理头部有一个变量记录了本Unit里面垃圾Sector的个数,选择一个垃圾最多的Unit回收可以最大的提高垃圾回收的效率;另一种方法是选择损耗最小的,这样做可以平衡介质损耗,但是vxWorks统计介质损耗的手段比较落后,它使用了一个全局的变量,每擦除一次Unit,全局变量加1,把全局变量记入Unit管理单元,作为介质损耗值,从这个数字上只能看出哪个Unit是最久未被使用的,而不能看出哪个Unit历史上被使用的次数最多。对于这两种方式,vxWorks随机采用一种,比例是96%的机会回收垃圾最多的Unit,4%的比例回收最久未被使用的Unit。

菜鸟
2007-03-28 20:54:00     打赏
7楼

a) Unit管理

由于Flash本身对Unit的操作依赖性,对存储的管理首先体现为对Unit的管理。

TFFS里把Unit分为物理Unit和逻辑Unit两个层次。物理Unit是Unit在物理存储器上的顺序,第一个Unit序号为0,第二个Unit序号为1,依次类推,他们的序号不会随使用的过程发生变化。逻辑Unit是人为增加的,与内容相关,与物理位置无关。物理Unit号就像一个楼房的门牌号码,楼盖好了以后,不会再变动;而逻辑Unit号就像家里的电话号码,当搬家的时候,电话号码做一个登记后随主人换到新居,我们仍然可以打电话找到主人,但主人现在的门牌号码肯定与原来不同了。我们做Unit的管理就像电信局,要为每个电话号码与门牌号做映射,TFFS里面的“主人”经常要“搬家”,我们的映射也要随时修改。TFFS里的“搬家”发生在垃圾回收的时候。垃圾回收的过程是先把被回收Unit里面非垃圾扇区拷贝到一个干净的Unit里面,然后擦除被回收的Unit,这样一系列操作以后上层应用程序关注的内容在物理位置发生了变化,我们需要能够从逻辑Unit号找到我们想要的内容,必须修改物理Unit与逻辑Unit的映射关系。举个简单的例子,如果物理Unit1映射了逻辑Unit1的内容,物理Unit2作为传输Unit专用于垃圾回收,当发生垃圾回收的时候,把Unit1里面非垃圾部分拷贝到Unit2,然后擦除Unit1,此时修改物理Unit与逻辑Unit的映射关系,让物理Unit2映射逻辑Unit1,把刚刚擦除的物理Unit1作为传输Unit等待下一次垃圾回收。这样操作以后,所有在Flash里面记录的关于Unit号的链接都不需要修改,因为他们关注的内容仍然记录原来的逻辑Unit里面,只是位置变了。在文件系统的主处理结构struct tTLrec里有两张表,分别管理物理Unit和逻辑Unit。下图是物理Unit和逻辑Unit的映射关系,从图中可以看到并不是所有的物理Unit都映射了逻辑Unit,这是因为Unit里面还有一部分特殊的开销,前文也提到过,就是TransferUnit,这是为垃圾回收和坏块管理准备的备用Unit。他本身不映射逻辑Unit,也就是不存储有效内容。当垃圾回收或出现坏块的时候,用它来替换。

格式化的时候全部有效的逻辑Unit都与物理Unit映射。正常使用时使用Unit号、Sector号和Sector内偏移来唯一寻址。但是这种映射关系是保存在内存中的,系统掉电后将消失,下次上电的时候必须重建这种映射关系才能继续使用原来的数据,否则系统内的数据就乱了。每个Unit在头部管理单元里使用了一个68字节的Unit头结构确保记录下所有必要的内容,以备重新上电后恢复文件系统。Unit管理单元的数据结构如下表:

偏移

名称

长度

备注

0

formatPattern

15

TFFS文件系统可用Unit的标志,vxWorks的TFFS填的是:{0x13,3,'C','I','S',0x46,57,0,'F',

'T','L','1','0','0',0}

15

noOfTransferUnits

1

用于做垃圾回收中转和坏Unit替换的Unit数

16

wearLevelingInfo

4

介质损耗信息记录

20

logicalUnitNo

2

本物理Unit映射的逻辑Unit号

22

log2SectorSize

1

扇区空间占用的位数,512字节占用9位

23

log2UnitSize

1

Unit空间占用的位数,64K字节占用16位

24

firstPhysicalEUN

2

保留Unit的数量,用于Bootrom

26

noOfUnits

2

文件系统内可用Unit的数量

28

virtualMediumSize

4

文件系统内可用于存储纯数据的大小,不超过2047G

32

directAddressingMemory

4

格式化时的参数,决定了直接访问的虚拟扇区数

36

noOfPages

2

virtualMediumSize换算后的页数

38

flags

1

格式化时的参数

39

eccCode

1

0xFF

40

serialNumber

4

0

44

altEUHoffset

4

0

48

BAMoffset

4

BAM区的偏移地址

52

reserved

12

保留字段

64

embeddedCIS

4

CIS


菜鸟
2007-03-28 20:56:00     打赏
8楼

看不到图,算了,只贴文字吧

[align=right][color=#000066][此贴子已经被作者于2007-3-28 13:00:39编辑过][/color][/align]

菜鸟
2007-03-28 21:01:00     打赏
9楼

a) Sector管理

Sector即扇区,文件系统操作的最小管理单位,TFFS为了与上层的文件系统兼容,也用扇区做基本管理单位。每个Sector的大小512字节。

Sector内512个字节都用作正常的数据,针对每个Sector的管理部分集中在所在的Unit首部。每个Sector对应4个字节,TFFS里面称为BAM字段。如果一个Unit大小256K,将包含512个扇区,共需要占用2048字节的空间,加上Unit的头部的68个字节,总共2116字节。TFFS规定Unit管理头和BAM一起占用的空间必须以Sector边界对齐,不足一个Sector的部分也要占用一个Sector,所以上述的Unit头部需要分配5个Sector来做管理。

每个Sector的BAM部分4个字节分为两个部分,高23位填充虚拟扇区号,低9位用作状态位。关于虚拟扇区号后面会讲到,低9位的状态位标志了每个Sector的用途和状态。

状态

含义

0xffffffffl

空闲扇区

0

垃圾扇区

0xfffffffel

已分配扇区,实际作用不大

0x30

Unit管理部分占用的扇区

0x40

正常数据扇区

0x60

交换扇区,交换结束后可以转换为数据扇区

0x70

坏扇区

BAM的位置顺序与扇区一一对应,查找某个扇区的BAM从Unit开头处做相应的偏移就可以了。下图是管理扇区的结构。

扇区的编号是以逻辑Unit号加Unit内的扇区序号来统一编号的,成为逻辑扇区号(LogicSectorNo)。这个序号方便了管理扇区,但是不方便上层的文件系统记录内容。比如一个文件占用三个扇区,使用的逻辑扇区号为30、20、40,写文件的时候需要一个扇区一个扇区的告诉TFFS要写的扇区序号,操作起来很麻烦,同时也不利于文件系统的兼容性,因为内存或者硬盘文件系统没有必要这样做。所以,在TFFS增加了一个虚拟扇区号(VirtualSectorNo),这个序号体现了扇区内容上的连续性。可以让逻辑扇区30映射虚拟扇区0,逻辑扇区20映射虚拟扇区1,逻辑扇区40映射虚拟扇区2。上层的文件系统写文件的时候只需要告诉TFFS起始的虚拟扇区号是多少,写几个扇区,TFFS就可以自己根据映射关系找到相应的逻辑扇区进行操作。映射方式采取的直接映射加二级索引的方式。

格式化TFFS的时候有一个输入参数vmAddressingLimit,在TFFS体现为Unit管理头部的参数directAddressingMemory,这是TFFS里面用于直接索引扇区的空间大小。如配置64K,直接索引的扇区就有128个。直接索引部分的扇区在TFFS进行mount的时候会搜索出来并为之创建一个映射表,表的顺序号为虚拟扇区号,内容为逻辑扇区号。可以减小或加大格式化参数vmAddressingLimit的值来控制直接索引扇区的数量。二级索引部分采用页方式,一页内包含扇区的个数是扇区大小除以4,如果扇区是512字节,一页就包含128个扇区,共64K,为什么要这样定呢,因为每个扇区对应的映射字段占用4个字节,每页内所有的扇区映射字段刚好充满一个扇区。所以一页内的虚拟扇区映射关系可以写在一个Sector里,称之为页管理扇区。虚拟扇区号在一页内是连续的,页管理扇区的偏移除以4就是页内的虚拟扇区号。页管理扇区的映射关系和其他直接映射的扇区写在同一个数组列表(pageTable)里面。页管理扇区占据前面的几项,后面是直接映射扇区。

对扇区的分配、写数据、删除只需要修改扇区对应的BAM区状态字就可以了,这几个状态的转换是可以直接覆盖写入的。直接索引扇区和二级索引扇区操作流程是一样的。如果要修改扇区的内容,比如修改一个文件,扇区的内容部分如果覆盖写入一般会失败,需要使用新的扇区替换原来的。对于直接索引扇区只需要修改一下pageTable里面对应项的内容就可以了。对于二级索引扇区,替换变得非常麻烦。因为它要改写的不是内存里面的pageTable,而是Flash里面的页管理扇区。修改Flash的内容,只有一个办法就是替换。这个操作会让很多人反感,原本只修改了一个扇区内的几个字节,实际操作却要占用两个新的扇区,显然是在“浪费”。为了最大程度的减小“浪费”,vxWorks增加了一个“替换状态”,对应的状态字是0x60。在发生文件内容修改的时候,文件内容占用的扇区必然要换掉,无可置疑,页管理扇区暂时不换,只是把虚拟扇区对应位置清0(变成垃圾),新申请一个扇区作为替换扇区,在它同样偏移的位置写上新的逻辑扇区号,同时在文件系统的管理结构体里几下replacementPageNo和replacementPageAddress。查找这个虚拟扇区的时候,先根据页找到页管理扇区,发现页管理扇区里面记录的是0后,会查看replacementPageNo是不是当前要访问的页,如果是,再到替换扇区中去查找。这个过程在连续替换多个扇区的时候有效的节省了空间和时间,但是对文件的同一块内容多次替换或者两个页内的扇区交替替换则不会起到任何作用。因为replacementPageNo只能记录一个页号,当replacementPageNo不为空时发生替换必须把上一个替换结束掉,过程是把页管理扇区内非0值全部拷贝到替换扇区里,然后把替换扇区的状态字0x60改成0x40,作为正常的页管理扇区使用。这个过程里面实际上已经操作了两个扇区。由于实际应用过程中大多是按文件修改连续的内容,所以使用替换扇区这种方法还是行之有效的。

举个例子,某文件系统管理Flash大小2M,共4096个扇区,直接索引扇区128个,二级索引扇区分31页,每页128个扇区,pageTable共(128+31)159项。假设第1页的页管理扇区占用逻辑扇区10,它的第2个虚拟扇区映射逻辑扇区5,现在它的内容被修改导致替换发生,新申请一个逻辑扇区12存储了新的内容,新申请一个替换扇区15帮助完成页管理扇区的替换,所有逻辑扇区均在同一个Unit内。下面两张图分别时替换前和替换后的状态。

菜鸟
2007-03-28 21:05:00     打赏
10楼

没有图,凑合着看吧,可能这些TFFS原理性的东西不会有多少人感兴趣。

[em03]

共21条 1/3 1 2 3 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]