YAFFS 文件系统
YAFFS(Yet Another Flash File System)是一个专门为 NAND Flash 存储器设计的嵌入式日志型文件系统,适用于大容量的存储设备,并且是在 GPL 协议下发布,可在其网站免费获得源代码。
YAFFS 是基于日志的文件系统,提供磨损平衡和掉电恢复的健壮性。它还为大容量的 Flash 芯片做了很好的调整,针对启动时间和 RAM 的使用做了优化,它适用于大容量的存储设备。
NAND Flash 与 NOR Flash 的区别
NOR Flash 是 Intel 公司 1988 年开发出了 NOR Flash 技术。NOR Flash 的特点是芯片内执行(XIP,Execute In Place),这样应用程序可以直接在 NOR Flash 闪存内运行,不必再把代码读到系统 RAM 中。NOR Flash 的传输效率很高,在 1~4MB 的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响了它的性能。
NAND Flash 结构是东芝公司在 1989 年发布的,其内部采用非线性宏单元模式,因此为固态大容量内存的实现提供了廉价有效的解决方案。NAND Flash 存储器具有容量大、写入和擦除速度快等优点,适用于大量数据的存储,因而在业界得到了越来越广泛的应用,如嵌入式产品中包括数码相机、MP3 随身听记忆卡、体积小巧的 U 盘等。
两种 FLASH 具有相同的存储单元,工作原理也一样,为了缩短存取时间并不是对每个单元进行单独的存取操作,而是对一定数量的存取单元进行集体操作,NAND FLASH 各存储单元之间是串联的,而 NOR FLASH 各单元之间是并联的,为了对全部的存储单元进行有效管理,必须对存储单元进行统一编址。NAND FLASH 的全部存储单元分为若干个块,每个块又分为若干个页,每个页是 512 字节或 2048 字节,就是 512 或 2048 个 8 位数,就是说每个页有 512 或 2048 条位线,每条位线下有 8 个存储单元,那么每页存储的数据正好跟硬盘的一个扇区存储的数据相同,这是设计时为了方便与磁盘进行数据交换而特意安排的,那么块就类似硬盘的簇,容量不同,块的数量不同,组成块的页的数量也不同。在读取数据时,当字线和位线锁定某个晶体管时,该晶体管的控制极不加偏置电压,其他的 7 个都加上偏置电压而导通,如果这个晶体管的浮栅中有电荷就会导通使位线为低电平,读出的数就是 0,反之就是 1。NOR FLASH 的每个存储单元以并联的方式连接到位线,方便对每一位进行随机存取,并且具有专用的地址线,可以实现一次性的直接寻址,缩短了 NOR FLASH 对处理器指令的执行时间。
在 NAND FLASH 闪存中每个块的最大擦写次数是一百万次,而 NOR FLASH 的擦写次数是十万次。与 NOR FLASH 相比 NAND FLASH 存储器具有 10 比 1 的块擦除周期优势,典型的 NAND FLASH 块尺寸要比 NOR FLASH 器件小 8 倍,每个 NAND FLASH 存储器块在给定的时间内的删除次数要少一些,并且 NAND FLASH 控制器接口相对简单。
YAFFS 专用术语
Page:页单元为基础操作(读操作或写操作或坏块标记)的寻址单元,包括通用区和扩展区,通用区主要用于存储数据,扩展区主要用于存储标记性信息;
Block:块单元为擦除操作的寻址单元;
OOB:存在于扩展区,其中包括 ECC、坏块标记、YAFFS 标记等,通常每 512 字节对应 16 字节的 OOB 区,每 2048 字节对应 64 字节的 OOB 区;
YAFFS2 模式下的 YAFFS 标记:
- 4 字节 32-bit 的数据块 ID。
- 4 字节 32-bit 的对象 ID。
- 2 字节本数据块内数据字节数量。
- 4 字节本块的序列号。
- 3 字节标记区的 ECC。
- 12 字节数据区的 ECC(每 256Byte 数据产生 3Byte 的 ECC)。
Chunk:YAFFS 的寻址单元,通常与 Page 大小一致;
Object:YAFFS 对象,通常包括文件、路径、链接、设备等。
常用 NAND Flash 的物理存储单元的阵列组织结构,以 SAMSUNG 公司 K9F4G08 的 NAND Flash 为例,K9F4G08 物理存储单元阵列结构示意图,如下图所示。
Memory Technology Device(MTD)
MTD(Memory Technology Device)即内存技术设备,为了使新加入的存储设备的驱动更加简单,MTD 子系统为存储器操作提供了一个抽象层,此子系统为驱动程序与上层系统提供通用接口,可以确保操作所有的存储器(NAND,OneNAND,NOR,AG-AND,具有 ECC 功能的 NOR 等)使用相同的 API,硬件驱动程序不需要关心具体的数据存储格式,只需要提供基础性的操作,如读操作,写操作和擦除操作等。
MTD 设备既不属于字符设备也不属于块设备,MTD 设备与块设备的对比,如下表所示。
块设备 | MTD设备 |
---|---|
由扇区组成 | 由可擦除的块组成 |
扇区尺寸较小(512或1024 Byte) | 可擦除扇区尺寸较大(128KB) |
读扇区和写扇区 | 读块,写块和擦除块 |
坏的扇区被硬件隐藏或重新映射 | 坏块不能被隐藏且需要软件处理 |
扇区的读写次数没有限制 | 块的擦除次数有限制 |
SylixOS 中 MTD 子系统源码位于“libsylixos/SylixOS/fs/mtd”,其中主要使用了 MTD 子系统的 MTD 原始设备层,Flash 硬件驱动层包括了 NOR Flash 驱动以及 NAND Flash 驱动,其中 NAND Flash 驱动源码则位于 BSP 包中的“SylixOS/driver/mtd/nand”。
YAFFS 分区
在 SylixOS 中 YAFFS 文件系统通常有两个分区分别为/yaffs2/n0 与/yaffs2/n1,其中 n0 为 boot 区,主要存放设备固件及一些常用配置文件,n1 为 comm 区,主要存放通用文件。
YAFFS 文件系统示例目录结构:
# ls
tmp var root home apps
sbin bin usr lib qt
ftk etc boot usb yaffs2
proc media mnt dev
# cd yaffs2/
# ls
n1 n0
# ll n0
drwxr-xr-- root root Mon Jul 27 14:12:39 2015 boot/
drwxr-xr-- root root Mon Jul 27 14:14:58 2015 etc/
drw-rw-rw- root root Tue Aug 04 10:55:20 2015 lost+found/
total items : 3
# ll n1
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 qt/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 lib/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 usr/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 bin/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 tmp/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 sbin/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 apps/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 home/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 root/
drwxr-xr-- root root Thu Jul 30 10:03:41 2015 var/
drw-rw-rw- root root Tue Aug 04 10:55:20 2015 lost+found/
total items : 12
n0 分区示例目录结构说明:
- boot:引导加载器所需文件目录。
- etc:配置文件(passwd,group,shadow,startup.sh 等)目录。
n1 分区示例目录结构说明:
- qt:Qt 跨平台 C++图形用户界面目录。
- lib:动态库及内核模块目录。
- usr:用户目录,存放用户级的文件。
- bin:系统启动时需要的执行文件及可执行程序目录。
- tmp:临时文件目录,系统启动后的临时文件存放在/var/tmp。
- sbin:可执行程序的目录。
- apps:应用程序目录。
- home:普通用户的个人文件目录。
- root:系统核心文件目录。
- var:系统执行过程中经常变化的文件目录。
常用的符号链接:
/yaffs2/n0/boot -—> /boot
/yaffs2/n0/etc -—> /etc
/yaffs2/n1/ftk -—> /ftk
/yaffs2/n1/qt -—> /qt
/yaffs2/n1/lib -—> /lib
/yaffs2/n1/usr -—> /usr
/yaffs2/n1/bin -—> /bin
/yaffs2/n1/sbin -—> /sbin
/yaffs2/n1/apps -—> /apps
/yaffs2/n1/home -—> /home
/yaffs2/n1/root -—> /root
/yaffs2/n1/var -—> /var
/yaffs2/n1/tmp -—> /var/tmp
/yaffs2/n1/tmp -—> /tmp
YAFFS 命令
在 SylixOS 中,可以使用 yaffscmd 命令来操作 YAFFS 文件系统。
【命令格式】
yaffscmd volname [{bad | info | markbad | erase}]
【参数说明】
volname :卷标名,在SylixOS系统中当前使用n0或n1
bad :坏块信息
info :参数信息
markbad :标记坏块
erase :存储器擦除
以下是 yaffscmd 命令查询参数信息的输出结果:
# yaffscmd n1 info
Device : "/n1"
startBlock......... 129
endBlock........... 1023
totalBytesPerChunk. 2048
chunkGroupBits..... 0
chunkGroupSize..... 1
nErasedBlocks...... 894
nReservedBlocks.... 16
nCheckptResBlocks.. nil
blocksInCheckpoint. 0
nObjects........... 18
nTnodes............ 0
nFreeChunks........ 57265
……
以下是 yaffscmd 命令标记坏块的输出结果:
# yaffscmd n1 markbad aa
yaffs: marking block 170 bad
mark the block 0xaa is a bad ok.
以下是 yaffscmd 命令查看坏块信息的输出结果:
[root@sylixos_station:/]# yaffscmd n1 bad
block 0xaa is bad block.
以下是 yaffscmd 命令擦除存储器的输出结果:
# yaffscmd n1 erase
yaffs volume erase ok.