YAFF2文件系统
YAFFS(Yet Another Flash File System)是第一个专门为NAND Flash存储器设计的嵌入式文件系统,适用于大容量的存储设备;并且是在GPL(General Public License)协议下发布的,可在其网站免费获得源代码。
YAFFS 是基于日志的文件系统,提供磨损平衡和掉电恢复的健壮性。它还为大容量的Flash 芯片做了很好的调整,针对启动时间和RAM 的使用做了优化。它适用于大容量的存储设备,已经在Linux 和WinCE 商业产品中使用。
YAFFS有2个版本:YAFFS1与YAFFS2。
这两个版本有一定的区别,其中文件系统限制如下:
- YAFFS1
- 最多 2^18 个文件(>260,000)
- 最大 2^20 字节单个文件文件大小(512MB)
- 最大 1GB 文件系统尺寸
- YAFFS2
- 最大 2GB 单个文件文件大小
- 由RAM占用空间设置的文件系统(4TB闪存需要1GB RAM)
- MTD设置的4GB最大文件系统大小(32位)
OOB数据区别如下:
- YAFFS1
- 由Smartmedia产生(例如,字节5是坏块标记,Smartmedia通常是FAT+FTL存储方案)
- 16字节:7个标签,2个状态,6个ECC
- YAFFS/Smartmedia/JFFS2格式ECC
- YAFFS2
- 2k页中有64个字节可用
- MTD确定的布局(在linux上)
- MTD或硬件没有ECC --- Linux 2.6.21上有38个字节可用
- 标签通常为28字节(16个字节数据,12个字节ECC)
- 有时不合适(如oneNAND --- 20个字节可用)
这里我们主要了解一下YAFFS2文件系统,首先我们需要创建YAFFS2文件系统映像,这里使用的是mkyaffs2image,源码可以在这里下载,编译命令如下。
| cd yaffs2/utils make |
编译好的程序如下所示:

首先我们来创建一个目录rootfs,里面包含001目录,002.txt文件内容为test002,003.txt文件内容为test003,002.link为001/002.txt的链接。

使用命令mkyaffs2image打包为一个JFFS2文件系统映像
| ./mkyaffs2image rootfs/ rootfs.yaffs2 |
使用二进制命令hexdump -C rootfs.yaffs2,查看文件:
00000000 03 00 00 00 01 00 00 00 ff ff 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000100 00 00 00 00 00 00 00 00 00 ff ff ff fd 41 00 00 |.............A..|
00000110 e9 03 00 00 e9 03 00 00 e1 33 97 62 e0 33 97 62 |.........3.b.3.b|
00000120 e0 33 97 62 ff ff ff ff ff ff ff ff ff ff ff ff |.3.b............|
00000130 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
000001c0 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 |................|
000001d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000800 00 10 00 00 01 00 00 00 00 00 00 00 ff ff 00 00 |................|
00000810 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000840 02 00 00 00 01 00 00 00 ff ff 30 30 32 2e 6c 69 |..........002.li|
00000850 6e 6b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |nk..............|
00000860 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000940 00 00 00 00 00 00 00 00 00 ff ff ff ff a1 00 00 |................|
00000950 e9 03 00 00 e9 03 00 00 e0 33 97 62 e0 33 97 62 |.........3.b.3.b|
00000960 e0 33 97 62 ff ff ff ff ff ff ff ff 30 30 31 2f |.3.b........001/|
00000970 30 30 32 2e 74 78 74 00 00 00 00 00 00 00 00 00 |002.txt.........|
00000980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000a00 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 00 |................|
00000a10 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00001040 00 10 00 00 01 01 00 00 00 00 00 00 ff ff 00 00 |................|
00001050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00001080 01 00 00 00 01 00 00 00 ff ff 30 30 33 2e 74 78 |..........003.tx|
00001090 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |t...............|
000010a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001180 00 00 00 00 00 00 00 00 00 ff ff ff b4 81 00 00 |................|
00001190 e9 03 00 00 e9 03 00 00 5c 1b 97 62 48 d9 96 62 |........\..bH..b|
000011a0 48 d9 96 62 08 00 00 00 ff ff ff ff ff ff ff ff |H..b............|
000011b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00001240 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 |................|
00001250 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00001880 00 10 00 00 02 01 00 00 00 00 00 00 ff ff 00 00 |................|
00001890 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
000018c0 74 65 73 74 30 30 33 0a ff ff ff ff ff ff ff ff |test003.........|
000018d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
000020c0 00 10 00 00 02 01 00 00 01 00 00 00 08 00 00 00 |................|
000020d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00002100 03 00 00 00 01 00 00 00 ff ff 30 30 31 00 00 00 |..........001...|
00002110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002200 00 00 00 00 00 00 00 00 00 ff ff ff fd 41 00 00 |.............A..|
00002210 e9 03 00 00 e9 03 00 00 4b d9 96 62 48 d9 96 62 |........K..bH..b|
00002220 48 d9 96 62 ff ff ff ff ff ff ff ff ff ff ff ff |H..b............|
00002230 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
000022c0 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 |................|
000022d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00002900 00 10 00 00 03 01 00 00 00 00 00 00 ff ff 00 00 |................|
00002910 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00002940 01 00 00 00 03 01 00 00 ff ff 30 30 32 2e 74 78 |..........002.tx|
00002950 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |t...............|
00002960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002a40 00 00 00 00 00 00 00 00 00 ff ff ff b4 81 00 00 |................|
00002a50 e9 03 00 00 e9 03 00 00 4f d9 96 62 48 d9 96 62 |........O..bH..b|
00002a60 48 d9 96 62 08 00 00 00 ff ff ff ff ff ff ff ff |H..b............|
00002a70 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00002b00 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 |................|
00002b10 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00003140 00 10 00 00 04 01 00 00 00 00 00 00 ff ff 00 00 |................|
00003150 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00003180 74 65 73 74 30 30 32 0a ff ff ff ff ff ff ff ff |test002.........|
00003190 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00003980 00 10 00 00 04 01 00 00 01 00 00 00 08 00 00 00 |................|
00003990 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
000039c0
通过分析源码结合文件,可以知道每块0x800字节有效数据,后面包含0x40字节的spare空间:
| 序号 | 偏移 | 说明 |
| 1 | 0x00000000-0x0000083F | 根目录 |
| 2 | 0x00000840-0x0000107F | 链接文件 002.link |
| 3 | 0x00001080-0x000018BF | 普通文件 003.txt |
| 4 | 0x000018C0-0x000020FF | 003.txt 的文件内容 |
| 5 | 0x00002100-0x0000293F | 目录 001 |
| 6 | 0x00002940-0x0000317F | 普通文件 002.txt |
| 7 | 0x00003180-0x000039BF | 002.txt 的文件内容 |
挑选0x0-0x840之间的数据分析一下,与一般的nand spare area有一些区别,前16个字节(0x800-0x80F)有区块的信息:
| 序号 | 偏移 | 说明 |
| 1 | 0x00-0x03 | 对象类型,值0x00000003,表示文件夹 |
| 2 | 0x04-0x07 | 父对象编号,值0x00000001 |
| 3 | 0x08-0x09 | 名称的checksum,保留未使用,值0xFFFF |
| 4 | 0x10-0x10B | 名称,最大长度为255字节 |
| 5 | 0x10C-0x10F | 文件的类型和存取的权限,值0x000041FD |
| 6 | 0x110-0x113 | 用户id,值0x000003E9 |
| 7 | 0x114-0x117 | 组id,值0x000003E9 |
| 8 | 0x118-0x11B | 访问时间,值0x629733E1 |
| 9 | 0x11C-0x11F | 修改时间,值0x629733E0 |
| 10 | 0x120-0x123 | 创建时间,值0x629733E0 |
| 11 | 0x124-0x127 | 文件大小,值0xFFFFFFFF,表示空 |
| 12 | 0x128-0x12B | 硬链接对等的对象编号 |
| 13 | 0x12C-0x1CB | 别名,软链接的指向路径,最大长度为159字节 |
| 14 | 0x1CC-0x1CF | 块和字符设备,值0x00000000 |
| 15 | 0x1D0-0x1F7 | roomToGrow,未知用途,大小40字节,数据全为0xFF |
| 16 | 0x1F8-0x1FB | shadows 对象,值0xFFFFFFFF |
| 17 | 0x1FC-0x1FF | isShrink,是否压缩? |
| 18 | 0x200-0x7FF | 块数据,数据全为0xFF |
| 19 | 0x800-0x803 | 序列号,值0x00001000 |
| 20 | 0x804-0x807 | 对象编号,值0x00000001 |
| 21 | 0x808-0x80B | 块编号,值0x00000000 |
| 22 | 0x80C-0x80F | 字节总数,值0x0000FFFF |
| 23 | 0x810-0x811 | ECC,colParity,值0xFF |
| 24 | 0x812-0x815 | ECC,lineParity,值0xFFFFFFFF |
| 25 | 0x816-0x819 | ECC,lineParityPrime,值0xFFFFFFFF |
| 26 | 0x81A-0x83F | 填充,数据全为0xFF |
对象类型:
| 序号 | 值 | 定义 |
| 1 | 0x00 | YAFFS_OBJECT_TYPE_UNKNOWN |
| 2 | 0x01 | YAFFS_OBJECT_TYPE_FILE |
| 3 | 0x02 | YAFFS_OBJECT_TYPE_SYMLINK |
| 4 | 0x03 | YAFFS_OBJECT_TYPE_DIRECTORY |
| 5 | 0x04 | YAFFS_OBJECT_TYPE_HARDLINK |
| 6 | 0x05 | YAFFS_OBJECT_TYPE_SPECIAL |
参考链接:
https://baike.baidu.com/item/yaffs/3324920