前言:
在嵌入式系统应用开发中,会涉及到数据的保存、读取等功能。当数据存放在不同的存储器上时,有与之相对应的读取方式。
在LINUX系统中有一个重要的概念:一切都是文件。在UNIX系统中,把一切资源都看作是文件,包括硬件设备,通常称为设备文件,这样用户就可以用读写文件的方式实现对硬件的访问。针对于文件的管理而开发的软件系统称为文件管理系统,简称文件系统。
1.存储器的分类
以上的存储器,可从易失性、只读性、速度、可靠性、功耗、价格等方面进行横向比较。
比如SRAM结构复杂,速度快,掉电易失、价格贵,常用于cache(I-cache、D-cache);
SDRAM速度次之,可按字节读取(片内执行),常用于运行程序;
flash按块读写,体积小容量大速度快,且不需要电力来维持保存的信息的特点被广泛用于移动存储。
使用这些硬件设备时,如何才能方便、高效的进行数据的写入和读取呢?
2.文件系统
想象一下,如果没有操作系统提供的现成文件管理系统,你应该如何识别读出来的数是什么?如何识别到具体的数据呢?
在操作系统提供的现成文件系统的条件下,对文件的操作被抽象成:open、close、write、read。
这四个API的实现是基于虚拟文件系统的,虚拟文件系统又是为了统一不同的文件系统而抽象出来的系统。
2.1 基于RAM的文件系统
(1) ramdisk
ramdisk是将一部分固定大小的内存当作分区来使用。它并非一个实际的文件系统,而是一种将实际的文件系统装入内存的机制,并且可以作为根文件系统。将一些经常被访问而又不会更改的文件(如只读的根文件系统)通过ramdisk放在内存中,可以明显地提高系统的性能。
(2)ramfs
ramfs是Linus Torvalds开发的一种基于内存的文件系统,工作于虚拟文件系统(VFS)层,不能格式化,可以创建多个,在创建时可以指定其最大能使用的内存大小。
ramfs文件系统把所有的文件都放在RAM中,所以读/写操作发生在RAM中,可以用ramfs来存储一些临时性或经常要修改的数据,例如/tmp和/var目录,这样既避免了对Flash存储器的读写损耗,也提高了数据读写速度。
2.2 基于FLASH的文件系统
Flash(闪存)作为嵌入式系统的存储设备之一,有其自身的特性。Flash的写入操作只能把对应位置的1修改为0,而不能把0修改为1(擦除Flash就是把对应存储块的内容恢复为1),因此,一般情况下,向Flash写入内容时,需要先擦除对应的存储区间,这种擦除是以块(block)为单位进行的。
在嵌入式Linux下,MTD(Memory Technology Device,存储技术设备)为底层硬件(闪存)和上层(文件系统)之间提供一个统一的抽象接口,即Flash的文件系统都是基于MTD驱动层的(参见上面的Linux下的文件系统结构图)。使用MTD驱动程序的主要优点在于,它是专门针对各种非易失性存储器(以闪存为主)而设计的,因而它对Flash有更好的支持、管理和基于扇区的擦除、读/写操作接口。
顺便一提,一块Flash芯片可以被划分为多个分区,各分区可以采用不同的文件系统;两块Flash芯片也可以合并为一个分区使用,采用一个文件系统。即文件系统是针对于存储器分区而言的,而非存储芯片。
(1) jffs2
JFFS文件系统最早是由瑞典Axis Communications公司基于Linux2.0的内核为嵌入式系统开发的文件系统。JFFS2是RedHat公司基于JFFS开发的闪存文件系统,最初是针对RedHat公司的嵌入式产品eCos开发的嵌入式文件系统,所以JFFS2也可以用在Linux, uCLinux中。
(2) yaffs:Yet Another Flash File System
yaffs/yaffs2是专为嵌入式系统使用NAND型闪存而设计的一种日志型文件系统。与jffs2相比,它减少了一些功能(例如不支持数据压缩),所以速度更快,挂载时间很短,对内存的占用较小。另外,它还是跨平台的文件系统,除了Linux和eCos,还支持WinCE, pSOS和ThreadX等。
yaffs/yaffs2自带NAND芯片的驱动,并且为嵌入式系统提供了直接访问文件系统的API,用户可以不使用Linux中的MTD与VFS,直接对文件系统操作。当然,yaffs也可与MTD驱动程序配合使用。
yaffs与yaffs2的主要区别在于,前者仅支持小页(512 Bytes) NAND闪存,后者则可支持大页(2KB) NAND闪存。同时,yaffs2在内存空间占用、垃圾回收速度、读/写速度等方面均有大幅提升。
3.根文件系统(rootfs)
根文件系统是内核启动时所mount的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序(Uboot)会在根文件系统挂载之后从中把一些基本的初始化脚本(init/rc.S)和服务等加载到内存中去运行。
什么是mount?
mount是Linux下的一个命令,它可以将分区挂接到Linux的一个文件夹下,从而将分区和该目录联系起来,因此我们只要访问这个文件夹,就相当于访问该分区了。
一般来说,linux的根文件系统有以下:
其中的这5个目录是必须的:
/etc/:存储重要的配置文件。
/bin/:存储常用且开机时必须用到的执行文件。
/sbin/:存储着开机过程中所需的系统执行文件。
/lib/:存储/bin/及/sbin/的执行文件所需的链接库,以及Linux的内核模块。
/dev/:存储设备文件。