关于linux,大家应该都有所了解了,那么,嵌入linux也是一门学问,我在网上不小心就看关于嵌入式
[url=http://www.beidaqingniao.org/jiuye/0915333.html]linux[/url]的网站了。


关于Linux文件系统

JFFS 全称为:The Journalling Flash File System(日志闪存文件系统)最初由瑞典的 Axis 

Communications 开发,Red Hat 的 David Woodhouse 对它进行了改进。作为用于微型嵌入式设备的原始

闪存芯片的实际文件系统而出现。JFFS文件系统是日志结构化的,这意味着它基本上是一长列节点。每个

节点包含有关文件的部分信息 — 可能是文件的名称、也许是一些数据。相对于 Ext2 fs,JFFS 因为有

以下这些优点而在无盘嵌入式设备中越来越受欢迎:
  
   1 JFFS 在扇区级别上执行闪存擦除/写/读操作要比 Ext2 文件系统好。
   2 JFFS 提供了比 Ext2 更好的崩溃/掉电安全保护。当需要更改少量数据时,Ext2 文件系统将整

个扇区复制到内存(DRAM)中,在内存中合并新数据,并写回整个扇区。这意味着为了更改单个字,必须

对整个扇区(64 KB)执行读/擦除/写例程 — 这样做的效率非常低。要是运气差,当正在 DRAM 中合

并数据时,发生了电源故障或其它事故,那么将丢失整个数据集合,因为在将数据读入 DRAM 后就擦除了

闪存扇区。JFFS 附加文件而不是重写整个扇区,并且具有崩溃/掉电安全保护这一功能。
   3 这可能是最重要的一点:JFFS 是专门为象闪存芯片那样的嵌入式设备创建的,所以它的整个设计

提供了更好的闪存管理。
   要构建JFFS文件系统,首先要有硬件设备FLASH及支持JFFS文件系统的操作系统。


摘要:本文主要分析了uclinux 2.4内核的jffs文件系统机制。希望能对基于uclinux开发产品的广大工程

师有所帮助。

关键词:uclinux vfs jffs

申明:这份文档是按照自由软件开放源代码的精神发布的,任何人可以免费获得、使用和重新发布,但是

你没有限制别人重新发布你发布内容的权利。发布本文的目的是希望它能对读者有用,但没有任何担保,

甚至没有适合特定目的的隐含的担保。更详细的情况请参阅 GNU 通用公共许可证(GPL),以及GNU 自由文

档协议(GFDL)。

你应该已经和文档一起收到一份GNU 通用公共许可证(GPL)的副本。如果还没有,写信给:
The Free Software Foundation, Inc., 675 Mass Ave, Cambridge,MA02139, USA

欢迎各位指出文档中的错误与疑问


一、flash读写的特殊性
对于嵌入式系统,flash是很常见的一种设备,而大部分的嵌入式系统都是把文件系统建立在flash之上,

由于对flash操作的特殊性,使得在flash上的文件系统和普通磁盘上的文件系统有很大的差别,对flash

操作的特殊性包括:
(1) 不能对单个字节进行擦除,最小的擦写单位是一个block,有时候也称为一个扇区。典型的一个

block的大小是64k。不同的flash会有不同,具体参考flash芯片的规范。
(2) 写操作只能对一个原来是空(也就是该地址的内容是全f)的位置操作,如果该位置非空,写操作

不起作用,也就是说如果要改写一个原来已经有内容的空间,只能是读出该sector到ram,在ram中改写,

然后写整个sector。
由于这些特殊写,所以在flash这样的设备上建立文件也有自己独特的特点,下面我们就以jffs为例进行

分析。

二、jffs体系结构介绍
1、存储结构
在jffs中,所有的文件和目录是一样对待的,都是用一个jffs_raw_inode来表示


整个flash上就是由一个一个的raw inode排列组成,一个目录只有一个raw inode,对于文件则是由一个

或多个raw inode组成。

2、文件组成
在文件系统mount到flash设备上的时候,会扫描flash,从而根据flash上的所有属于一个文件的raw 

inode建立一个jffs_file结构以及node list。
下面的图显示了一个文件的组成


一个文件是由若干个jffs_node组成,每一个jffs_node是根据flash上得jffs_raw_inode而建立的,

jffs_file主要维护两个链表
版本链表:主要是描述该node创建的早晚,就是说version_head指向的是一个最老的node,也就意味着垃

圾回收的时候最该回收的就是这个最老的node。
区域链表:这个链表主要是为读写文件创建的,version_head指向的node代表的文件数据区域是0~~~n-1 

之后依次的节点分别是 n~~~m-1 m~~~~o-1 …….其中n<M<="" p="" />

3、操作
对文件的读操作应该是比较简单,但是写操作,包括更改文件名等操作都是引起一个新的jffs_node的诞

生,同时要写一个相映的raw inode到flash上,这样的操作有可能导致前面的某个jffs_node上面的数据

完全失效,从而导致对应flash上的raw inode的空间成为dirty。
下面举一个例子可能会更清楚一些。

一个文件的range list是由上面的三个jffs_node组成,当我们做如下写操作的时候
lseek( fd, 10, SEEK_SET );
write( fd, buf,40 );
第一个和最后一个node被截短了,第二个node完全被新数据替换,该node会从链表上摘下来,flash上空

间变成dirty。如果做如下写操作的时候
lseek( fd, 23, SEEK_SET );
write( fd, buf,5 );
此时,第二个node被分裂成两个node,同时产生一个新的node,range链表的元素变成五个。
更多的知识链接:[url=http://]http://www.beidaqingniao.org/question/0722215.html[/url]