嵌入式linux系统开发概述之五----文件系统(FileSystem)

2019-07-13 02:45发布

  5  文件系统     系统需要一种以结构化格式存储和检索信息的方法这就需要文件系统的参与文件系统指文件存在的物理空间,linux系统中每个分区都是一个文件系统,都有自己的目录层次结构。Linux会将这些分属不同分区的、单独的文件系统按一定的方式形成一个系统的总的目录层次结构。一个操作系统的运行离不开对文件的操作,因此必然要拥有并维护自己的文件系统。     用户可以根据可靠性、健壮性和/或增强的功能的需求来选择文件系统的类型。下一节将讨论几个可用选项及其优缺点。
5.1 第二版扩展文件系统(Ext2fs
    Ext2fslinux事实上的标准文件系统,它已经取代了它的前任 — 扩展文件系统(或Extfs)。Extfs支持的文件大小最大为2GB,支持的最大文件名称大小为255个字符 — 而且它不支持索引节点(包括数据修改时间标记)。Ext2fs做得更好;它的优点是:
Ext2fs
支持达4TB 的内存。 
Ext2fs
文件名称最长可以到1012个字符。 
当创建文件系统时,管理员可以选择逻辑块的大小(通常大小可选择 102420484096字节)。 
Ext2fs
实现快速符号链接:不需要为此目的而分配数据块,并且将目标名称直接存储在索引节点(inode)表中。这使性能有所提高,特别是在速度上。
    因为Ext2文件系统的稳定性、可靠性和健壮性,所以几乎在所有基于 linux的系统(包括台式机、服务器和工作站 — 并且甚至一些嵌入式设备)上都使用Ext2文件系统。然而,当在嵌入式设备中使用Ext2fs时,它有一些缺点:
Ext2fs
是为象IDE设备那样的块设备设计的,这些设备的逻辑块大小是512字节,1K字节等这样的倍数。这不太适合于扇区大小因设备不同而不同的闪存设备
    Ext2
文件系统没有提供对基于扇区的擦除/写操作的良好管理。在Ext2fs中,为了在一个扇区中擦除单个字节,必须将整个扇区复制到RAM,然后擦除,然后重写入。考虑到闪存设备具有有限的擦除寿命(大约能进行100,000次擦除),在此之后就不能使用它们,所以这不是一个特别好的方法
在出现电源故障时,Ext2fs不是防崩溃的
Ext2
文件系统不支持损耗平衡,因此缩短了扇区/闪存的寿命(损耗平衡确保将地址范围的不同区域轮流用于写和/或擦除操作以延长闪存设备的寿命) 
Ext2fs
没有特别完美的扇区管理,这使设计块驱动程序十分困难。
    由于这些原因,通常相对于Ext2fs,在嵌入式环境中使用MTD/JFFS2组合是更好的选择。
5.2  Ramdisk 挂装 Ext2fs     Ramdisk是通过将计算机的RAM用作设备来创建和挂装文件系统的一种机制,它通常用于无盘系统(当然包括微型嵌入式设备,它只包含作为永久存储媒质的闪存芯片)。
    通过使用Ramdisk的概念,可以在嵌入式设备中创建并挂装Ext2文件系统(以及用于这一目的的任何文件系统)。
    下面的操作创建一个简单的基于Ext2fsRamdisk  #mke2fs -vm0 /dev/ram 4096
#mount -t ext2 /dev/ram /mnt
#cd /mnt
#cp /bin, /sbin, /etc, /dev ... files in mnt
#cd ../
#umount /mnt
#dd if=/dev/ram bs=1k count=4096 of=ext2ramdisk mke2fs是用于在任何设备上创建ext2文件系统的实用程序 — 它创建超级块、索引节点以及索引节点表等等。
    在上面的用法中,/dev/ram 是上面构建有4096个块的ext2文件系统的设备。然后,将这个设备(/dev/ram)挂装在名为/mnt的临时目录上并且复制所有必需的文件。一旦复制完这些文件,就卸装这个文件系统并且设备(/dev/ram)的内容被转储到一个文件(ext2ramdisk)中,它就是所需的 RamdiskExt2文件系统)。
    上面的顺序创建了一个4MBRamdisk,并用必需的文件实用程序来填充它。
    一些要包含在 Ramdisk 中的重要目录是:
/bin  
— 保存大多数象initbusyboxshell、文件管理实用程序等二进制文件。 
/dev 
— 包含用在设备中的所有设备节点 
/etc  
— 包含系统的所有配置文件 
/lib  
— 包含所有必需的库,如libclibdl 

5.3 日志闪存文件系统,版本 2JFFS2
    瑞典的Axis Communications开发了最初的JFFSRed HatDavid Woodhouse对它进行了改进。 第二个版本,JFFS2,作为用于微型嵌入式设备的原始闪存芯片的实际文件系统而出现。JFFS2文件系统是日志结构化的,这意味着它基本上是一长列节点。每个节点包含有关文件的部分信息 — 可能是文件的名称、也许是一些数据。相对于 Ext2fsJFFS2 因为有以下这些优点而在无盘嵌入式设备中越来越受欢迎:
JFFS2
在扇区级别上执行闪存擦除/写/读操作要比Ext2文件系统好;
JFFS2
提供了比Ext2fs更好的崩溃/掉电安全保护。当需要更改少量数据时,Ext2文件系统将整个扇区复制到内存(DRAM)中,在内存中合并新数据,并写回整个扇区。这意味着为了更改单个字,必须对整个扇区(64KB)执行读/擦除/写例程 — 这样做的效率非常低。要是运气差,当正在DRAM中合并数据时,发生了电源故障或其它事故,那么将丢失整个数据集合,因为在将数据读入DRAM后就擦除了闪存扇区。JFFS2附加文件而不是重写整个扇区,并且具有崩溃/掉电安全保护这一功能。 
    这可能是最重要的一点:JFFS2是专门为象闪存芯片那样的嵌入式设备创建的,所以它的整个设计提供了更好的闪存管理。
    因为本文主要是写关于闪存设备的使用,所以在嵌入式环境中使用 JFFS2的缺点很少:
当文件系统已满或接近满时,JFFS2会大大放慢运行速度。这是因为垃圾收集的问题
    linux下,用mkfs.jffs2命令创建JFFS2文件系统(基本上是使用JFFS2Ramdisk)。
    下面的操作创建 JFFS2 文件系统 
#mkdir jffsfile 
#cd jffsfile 

/* copy all the /bin, /etc, /usr/bin, /sbin/ binaries and /dev entries 
that are needed for the filesystem here */ 

/* Type the following command under jffsfile directory to create the JFFS2 Image */ 

#./mkfs.jffs2 -e 0x40000 -p -o ../jffs.image 
    上面显示了 mkfs.jffs2 的典型用法。-e选项确定闪存的擦除扇区大小(通常是64千字节)。-p选项用来在映像的剩余空间用零填充。         -o选项用于输出文件,通常是JFFS2文件系统映像 — 在本例中是jffs.image。一旦创建了 JFFS2文件系统,它就被装入闪存中适当的位置(引导装载程序告知内核查找文件系统的地址)以便内核能挂装它。

5.4 tmpfs
    当linux运行于嵌入式设备上时,该设备就成为功能齐全的单元,许多守护进程会在后台运行并生成许多日志消息。另外,所有内核日志记录机制, syslogddmesgklogd,会在/var/tmp目录下生成许多消息。由于这些进程产生了大量数据,所以允许将所有这些写操作都发生在闪存是不可取的。由于在重新引导时这些消息不需要持久存储,所以这个问题的解决方案 是使用tmpfs
    tmpfs
是基于内存的文件系统,它主要用于减少对系统的不必要的闪存写操作这一唯一目的。因为tmpfs驻留在RAM中,所以写/读/擦除的操作发生在RAM中而不是在闪存中。因此,日志消息写入RAM而不是闪存中,在重新引导时不会保留它们。tmpfs还使用磁盘交换空间来存储,并且当为存储文件而请求页面时,使用虚拟内存(VM)子系统。     tmpfs的优点包括: 动态文件系统大小 — 文件系统大小可以根据被复制、创建或删除的文件或目录的数量来缩放。使得能够最理想地使用内存; 速度                   — 因为tmpfs驻留在RAM,所以读和写几乎都是瞬时的。即使以交换的形式存储文件,I/O操作的速度仍非常快。     tmpfs的一个缺点是当系统重新引导时会丢失所有数据。因此,重要的数据不能存储在tmpfs上。 诸如Ext2fsJFFS2等大多数其它文件系统都驻留在底层块设备之上,而tmpfs与它们不同,它直接位于VM上。因而,挂装tmpfs文件系统是很简单的事: /* Entries in /etc/rc.d/rc.sysinit for creating/using tmpfs */ # mount -t tmpfs tmpfs /var -o size=512k # mkdir -p /var/tmp # mkdir -p /var/log 
# ln -s /var/tmp /tmp 
    上面的命令将在/var上创建tmpfs并将tmpfs的最大大小限制为512K。同时,tmp/log/目录成为tmpfs的一部分以便在RAM中存储日志消息。
    如果您想将tmpfs的一个项添加到/etc/fstab,那么它看起来象这样:
tmpfs /var tmpfs size=32m 0 0
这将在/var上挂装一个新的tmpfs文件系统。