基于Linux2.6的YAFFS文件系统移植

来源:百度文库 编辑:神马文学网 时间:2024/04/27 16:48:51
一、YAFFS文件系统简介
YAFFS,Yet Another Flash File System,是一种类似于JFFS/JFFS2的专门为Flash设计的嵌入式文件系统。与JFFS相比,它减少了一些功能,因此速度更快、占用内存更少。
YAFFS和JFFS都提供了写均衡,垃圾收集等底层操作。它们的不同之处在于:
(1)JFFS是一种日志文件系统,通过日志机制保证文件系统的稳定性。YAFFS仅仅借鉴了日志系统的思想,不提供日志机能,所以稳定性不如JAFFS,但是资源占用少。
(2)JFFS中使用多级链表管理需要回收的脏块,并且使用系统生成伪随机变量决定要回收的块,通过这种方法能提供较好的写均衡,在YAFFS中是从头到尾对块搜索,所以在垃圾收集上JFFS的速度慢,但是能延长NAND的寿命。
(3)JFFS支持文件压缩,适合存储容量较小的系统;YAFFS不支持压缩,更适合存储容量大的系统。
YAFFS还带有NAND芯片驱动,并为嵌入式系统提供了直接访问文件系统的API,用户可以不使用Linux中的MTD和VFS,直接对文件进行操作。NANDFlash大多采用MTD+YAFFS的模式。MTD( Memory TechnologyDevices,内存技术设备)是对Flash操作的接口,提供了一系列的标准函数,将硬件驱动设计和系统程序设计分开。
二、YAFFS文件系统的移植
yaffs代码可以从http://www.aleph1.co.uk/armlinux/projects/下载(yaffs代码包括yaffs_ecc
.c,yaffs_fileem.c,yaffs_fs.c,yaffs_guts.c,yaffs_mtdif.c,yaffs_ramem.c。)
表一 Yaffs文件系统源代码相关文件及功能描述
文件名 功    能
yaffs_ecc.c ECC校验算法
yaffs_fileem.c 测试flash
yaffs_fs.c 文件系统接口函数
yaffs_guts.c Yaffs文件系统算法
yaffs_mtdif.c NAND函数
yaffs_ramem.c Ramdisk实现
1.内核中没有YAFFS,所以需要自己建立YAFFS目录,并把下载的YAFFS代码复制到该目录下面。

#mkdir fs/yaffs
#cp *.c(yaffs source code) fs/yaffs
2.修改fs/Kconfig,使得可以配置yaffs :
source "fs/yaffs/Kconfig"
3.修改fs/makefile,添加如下内容:
obj-$(CONFIG_YAFFS_FS)           += yaffs/
4.在fs目录下生成yaffs目录,并在里面生成一个makefile 和Kconfig
Makefile 内容为:
yaffs-objs := yaffs_fs.o yaffs_guts.o yaffs_mtdif.o yaffs_ecc.o
EXTRA_CFLAGS += $(YAFFS_CONFIGS) -DCONFIG_KERNEL_2_6
Kconfig内容为:
#
# YAFFS file system configurations
#
config YAFFS_FS
tristate "Yet Another Flash Filing System(YAFFS) file system support"
help
    YAFFS, for Yet Another Flash Filing System, is a filing system
    optimised for NAND Flash chips.

    To compile the YAFFS file system support as a module, choose M here:
    the module will be called yaffs.

    If unsure, say N.

    Further information on YAFFS is available at
    <http://www.aleph1.co.uk/yaffs/>.

config YAFFS_MTD_ENABLED
bool "NAND mtd support"
depends on YAFFS_FS
help
    This adds the yaffs file system support for working with a NAND mtd.

    If unsure, say Y.

config YAFFS_RAM_ENABLED
bool "yaffsram file system support"
depends on YAFFS_FS
help
    This adds the yaffsram file system support. Nice for testing on x86,
    but uses 2MB of RAM. Don't enable for NAND-based targets.

    If unsure, say N.

comment "WARNING: mtd and/or yaffsram support should be selected"
depends on YAFFS_FS && !YAFFS_MTD_ENABLED && !YAFFS_RAM_ENABLED

config YAFFS_USE_OLD_MTD
bool "Old mtd support"
depends on YAFFS_FS && 0
help
    Enable this to use the old MTD stuff that did not have yaffs support.
    You can use this to get around compilation problems, but the best
    thing to do is to upgrade your MTD support. You will get better speed.

    If unsure, say N.

config YAFFS_USE_NANDECC
bool "Use ECC functions of the generic MTD-NAND driver"
depends on YAFFS_FS
default y
help
    This enables the ECC functions of the generic MTD-NAND driver.
    This will not work if you are using the old mtd.

    NB Use NAND ECC does not work at present with yaffsram.

    If unsure, say Y.

config YAFFS_ECC_WRONG_ORDER
bool "Use the same ecc byte order as Steven Hill's nand_ecc.c"
depends on YAFFS_FS
help
    This makes yaffs_ecc.c use the same ecc byte order as
    Steven Hill's nand_ecc.c. If not set, then you get the
    same ecc byte order as SmartMedia.

    If unsure, say N.

config YAFFS_USE_GENERIC_RW
bool "Use Linux file caching layer"
default y
depends on YAFFS_FS
help
    Use generic_read/generic_write for reading/writing files. This
    enables the use of the Linux file caching layer.

    If you disable this, then caching is disabled and file read/write
    is direct.

    If unsure, say Y.

config YAFFS_USE_HEADER_FILE_SIZE
bool "Use object header size"
depends on YAFFS_FS
help
    When the flash is scanned, two file sizes are constructed:
    * The size taken from the object header for the file.
    * The size figured out by scanning the data chunks.
    If this option is enabled, then the object header size is used,
    otherwise the scanned size is used.

    If unsure, say N.

config YAFFS_DISABLE_CHUNK_ERASED_CHECK
bool "Turn off debug chunk erase check"
depends on YAFFS_FS
default y
help
    Enabling this turns off the test that chunks are erased in flash
    before writing to them. This is safe, since the write verification
    will fail. Suggest enabling the test (ie. say N)
    during development to help debug things.

    If unsure, say Y.

#config YAFFS_DISABLE_WRITE_VERIFY
# bool "Disable write verify (DANGEROUS)"
# depends on YAFFS_FS && EXPERIMENTAL
# help
#    I am severely reluctant to provide this config. Disabling the
#    verification is not a good thing to do since NAND writes can
#    fail silently. Disabling the write verification will cause your
#    teeth to rot, rats to eat your corn and give you split ends.
#    You have been warned. ie. Don't uncomment the following line.
#
#    If unsure, say N.
#

config YAFFS_SHORT_NAMES_IN_RAM
bool "Cache short names in RAM"
depends on YAFFS_FS
default y
help
    If this config is set, then short names are stored with the
    yaffs_Object. This costs an extra 16 bytes of RAM per object,
    but makes look-ups faster.

    If unsure, say Y.
5.在/arch/arm/mach-s3c2410/mach-smdk2410.c找到smdk_default_nand_part结构,修改nand分区,如下:
struct mtd_partition smdk_default_nand_part[] = {
         [0] = {
                 .name    = "vivi",
                 .size    = 0x00020000,
                 .offset = 0x00000000,
         },
         [1] = {
                 .name    = "param",
                 .size    = 0x00010000,
                 .offset = 0x00020000,
         },
         [2] = {
                 .name    = "kernel",
                 .size    = 0x00100000,
                 .offset = 0x00030000,
         },
         [3] = {
                 .name    = "root",
                 .size    = 0x01900000,
                 .offset = 0x00130000,
         },
         [4] = {
                 .name    = "user",
                 .size    = 0x025d0000,
                 .offset = 0x01a30000,
         }
};
注:此分区要结合vivi里面的分区来进行设置。
6.配置内核时选中MTD支持:
Memory Technology Devices (MTD) --->
<*> Memory Technology Device (MTD) support
    [*]    MTD partitioning support
     ……
    --- User Modules And Translation Layers
    <*> Direct char device access to MTD devices
    <*> Caching block device access to MTD devices
    ……
NAND Flash Device Drivers --->
<*> NAND Device Support
<*> NAND Flash support for S3C2410 SoC
[*]    S3C2410 NAND driver debug
7.配置内核时选中YAFFS支持:
File systems --->
Miscellaneous filesystems --->
    <*> Yet Another Flash Filing System(YAFFS) file system support
    [*]    NAND mtd support
    [*]    Use ECC functions of the generic MTD-NAND driver
    [*]    Use Linux file caching layer
    [*]    Turn off debug chunk erase check
    [*]    Cache short names in RAM
8.编译内核并将内核下载到开发板的flash中。
三、Yaffs文件系统测试:
1.内核启动之后,在启动信息里面可以看到如下内容:
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 5 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00020000 : "vivi"
0x00020000-0x00030000 : "param"
0x00030000-0x00130000 : "kernel"
0x00130000-0x01a30000 : "root"
0x01a30000-0x04100000 : "user"
2.如果在内核里面添加了proc文件系统的支持那么你在proc里面可以看到有关yaffs的信息
~ # cat proc/filesystems
nodev    sysfs
nodev    rootfs
nodev    bdev
nodev    proc
nodev    sockfs
nodev    pipefs
nodev    futexfs
nodev    tmpfs
nodev    eventpollfs
nodev    devpts
nodev    ramfs
         vfat
nodev    devfs
nodev    nfs
         yaffs
nodev    rpc_pipefs
3.查看dev目录下相关目录可以看到:
~ # ls dev/mtd -al
drwxr-xr-x     1 root      root             0 Jan 1 00:00 .
drwxr-xr-x     1 root      root             0 Jan 1 00:00 ..
crw-rw-rw-     1 root      root       90,    0 Jan 1 00:00 0
cr--r--r--     1 root      root       90,    1 Jan 1 00:00 0ro
crw-rw-rw-     1 root      root       90,    2 Jan 1 00:00 1
cr--r--r--     1 root      root       90,    3 Jan 1 00:00 1ro
crw-rw-rw-     1 root      root       90,    4 Jan 1 00:00 2
cr--r--r--     1 root      root       90,    5 Jan 1 00:00 2ro
crw-rw-rw-     1 root      root       90,    6 Jan 1 00:00 3
cr--r--r--     1 root      root       90,    7 Jan 1 00:00 3ro
crw-rw-rw-     1 root      root       90,    8 Jan 1 00:00 4
cr--r--r--     1 root      root       90,    9 Jan 1 00:00 4ro

~ # ls dev/mtdblock/ -al
drwxr-xr-x     1 root      root             0 Jan 1 00:00 .
drwxr-xr-x     1 root      root             0 Jan 1 00:00 ..
brw-------     1 root      root       31,    0 Jan 1 00:00 0
brw-------     1 root      root       31,    1 Jan 1 00:00 1
brw-------     1 root      root       31,    2 Jan 1 00:00 2
brw-------     1 root      root       31,    3 Jan 1 00:00 3
brw-------     1 root      root       31,    4 Jan 1 00:00 4
4.mount、umount
建立mount目录
~ #mkdir /mnt/flash0
~ #mkdir /mnt/flash1
Mountblockdevice设备
~ #mount –t yaffs /dev/mtdblock/3 /mnt/flash0
~ #mount –t yaffs /dev/mtdblock/4 /mnt/flash1
~ #cp 1.txt /mnt/flash0
~ #cp 2.txt /mnt/flash1
查看mount上的目录,可以看到该目录下有刚才拷贝的文件,将其umount后,再次mount上来可以发现拷贝的文件仍然存在,这时删除该文件然后umount,再次mount后,可以发现拷贝的文件已经被删除,由此可以该分区可以正常读写。
5.在flash上建立根文件系统
~ # mount –t yaffs /dev/mtdblock/3 /mnt/flash0
~ #cp (your rootfs) /mnt/flash0
~ #umount /mnt/flash0
重新启动,改变启动参数:
param set linux_cmd_line "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"
重新启动,开发板就可以从flash启动根文件系统了。
注:这里你得在内核中添加devfs文件系统的支持,否则内核无法找到/dev/mtdblock/3目录

目前flash的文件系统比较多,用的比较多的就是JFFS2文件系统。基于NOR flash上的JFFS2文件系统可以说算是比较成熟了,支持NAND flash的JFFS2也已经发布了。源代码可以到http://www.linux-mtd.infradead.org上面下载。但是在我的测试过程中,在nandflash上挂接的JFFS2文件系统很不稳定,经常有CRC错误产生。特别是进行写操作的时候,每次复位都会产生CRC错误,可以说支持NANDflash的JFFS2文件系统目前还不成熟。而YAFFS文件系统则是专门针对NAND flash的,源代码可以到
http://www.aleph1.co.uk/yaffs/index.html上下载。在测试过程中稳定性能比JFFS2文件系统要稳定的多,而且mount分区的时间也比JFFS2文件系统少的多。用JFFS2 mount一个2m的文件系统大约需要1s。下面分别介绍在uclinux下面使用JFFS2和YAFFS文件系统。
1、JFFS2
http://www.linux-mtd.infradead.org上面下载最新的MTD和JFFS2压缩包。压缩包里面还有有关的内核补丁和一些MTD的相关工具。主要的补丁就是ilookup-2.4.23.patch,因为最新的MTD驱动中要用到一个ilookup()函数。打完补丁、更新了MTD驱动和JFFS2文件系统之后就开始写自己nandflash驱动了。如果不想把JFFS2作为根文件系统的话,还需要修改MTD_BLOCK_MAJOR。驱动可以参考里面的例子,最简单的就是参考spia.c。
写驱动主要工作是定义flash分区结构、定义flash读写地址、写控制flash的**_hwcontrol()函数。具体的操作要看所用的nand flash的芯片资料。相对NOR flash来说驱动要简单多了。:)
改完之后再配置
Memory Technology Devices(MTD)下
   CONFIG_MTD=Y
   CONFIG_MTD_DEBUG=Y
   CONFIG_MTD_DEBUG_VERBOSE=3
   CONFIG_MTD_PARTITIONS=Y
   CONFIG_MTD_CHAR=Y
   CONFIG_MTD_BLOCK=Y
NAND Flash Device Drivers下
   CONFIG_MTD_NAND=Y
   定义自己的驱动文件
File systems下
CONFIG_JFFS2_FS=Y
   CONFIG_JFFS2_FS_DEBUG=2
CONFIG_JFFS2_FS_NAND=y /*这个是新加的*/
在uClinux v1.3.4 Configuration下
Flash Tools下
CONFIG_USER_MTDUTILS=Y
   CONFIG_USER_MTDUTILS_ERASE=Y
   CONFIG_USER_MTDUTILS_ERASEALL=Y
   CONFIG_USER_MTDUTILS_MKFSJFFS2=Y
最后就是辛苦了调试工作了。:(MTD驱动调试完之后,就可以在上面挂接JFFS2文件系统了。参看flash分区情况:cat /proc/mtd,擦除分区:eraseall /dev/mtd*.例如把第一个分区mount到/mnt目录下面:
先:eraseall /dev/mtd0
然后:mount -t jffs2 /dev/mtdblock0 /mnt
2、YAFFS
YAFFS意义为'yet another flash file system',也是一个开源的文件系统。YAFFS是目前为止唯一一个专门为NAND flash设计的文件系统,具有很好的可移植性,能够在linux,uclinux,和wince
下面运行。
http://www.aleph1.co.uk/yaffs/index.html上下载源代码。压缩包里面也包含YAFFS的说明文档。YAFFS文件系统的源文件就devextras.h,yaffs_ecc.c, yaffs_ecc.h,yaffs_guts.c,yaffs_guts.h,yaffs_mtdif.h,yaffs_mtdif.c和 yportenv.h
另外需要配置的宏:CONFIG_YAFFS_FS 和CONFIG_YAFFS_MTD_ENABLED,就是配置在mtd上面挂接YAFFS,其它还有一些辅助配置需要时也可以配置。
在fs目录下面建一个yaffs目录,把以上说的文件考里面去,新建一个makefile:
O_TARGET := yaffs.o
obj-y := yaffs_fs.o yaffs_guts.o yaffs_mtdif.o yaffs_ecc.o
obj-m := $(O_TARGET)
include $(TOPDIR)/Rules.make
接下来就是改fs目录下面config.in和makefile,在配置YAFFS的时候,把YAFFS连接进去。
如果像前面一样已经把NAND MTD驱动调好了,加YAFFS就很简单了。因为YAFFS是自己做ECC校验的,所以要把MTD驱动里面的ECC去掉。在驱动里面改成this->eccmode = NAND_ECC_NONE就可以了。
另外YAFFS是用mkyaffs来擦除flash,所以在mtd-utils中加上mkyaffs.c,一起编译进去。
最后就是编译了,呵呵。中间会有一些警告没有关系的,就是写没有用的变量和函数,不过话说回来YAFFS的代码写的确实不太规范。当然它的性能确实没话说。有兴趣的可以试一下。