Arm嵌入式开发之Flash文件系统建立
来源:互联网 发布:数据交互是什么意思 编辑:程序博客网 时间:2024/04/28 23:43
Flash转换层
Flash无法重复在同一块存储位置做写入操作(要擦除),硬盘上的文件系统沿用时要通过一层转换层:FTL用于NOR Flash,NFTL用于NAND Flash。但其效率不高,尽量避免使用依赖于转换层的文件系统。
Cramfs
Cramfs是一种压缩的只读文件系统,当浏览Flash中的目录或读取文件时,Cramfs文件系统会动态地计算出压缩后的数据所存储的位置,实时的解压缩到内存中,对用户来说与使用ramdisk感觉不出差异。、
通过一下命令创建Cramfs文件系统映像:(源码位于linux/fs/cramfs)
Mkcramfs my_cramfs/ cramfs.img (my_cramfs为要创建映像的目录)
将映像复制到Flash的第一个分区并mount到/mnt/nor
cp cramfs.img /dev/mtd1
mount –cramfs /dev/mtdblock1 /mnt/nor
JFFS/JFFS2
JFFS/JFFS2是管理在MTD设备上实现的日志型文件系统。
制作JFFS2文件系统的工具mkfs.jffs2(包含在mtd-utils中),执行如下命令可生成所要的映像:
./mkfs.jffs2 –d my_jffs2/ -o jffs2.img
将jffs2.img复制到Flash第一个分区,挂载到linux目录
Cp jffs2.img /dev/mtd1
mount –t jffs2 /dev/mtdblock1 /mnt/nor
Yaffs/Yaffs2
Yaffs(Yet Another Flash File System)文件系统是专门针对NAND闪存设计的嵌入式文件系统,目前有YAFFS和YAFFS2两个版本,两个版本的主要区别之一在于YAFFS2能够更好的支持大容量的NAND FLASH芯片。
Yaffs文件系统有些类似于JFFS/JFFS2文件系统,与之不同的是JFFS1/2文件系统最初是针对NOR FLASH的应用场合设计的,而NOR FLASH和NAND FLASH本质上有较大的区别,所以尽管JFFS1/2文件系统也能应用于NAND FLASH,但由于它在内存占用和启动时间方面针对NOR的特性做了一些取舍,所以对NAND来说通常并不是最优的方案。
yaffs/yaffs2在2.6.9中的移植
(1),下载YAFFS文件系统代码,下载网址:
http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/
点击页面左下角的Download tarball即可下载全部相关代码。
(2),将下载的文件yaffs.tar.gz拷贝到你的一个临时文件夹中,假设是/tmp,并解压:
# cd /tmp
# tar xzvf yaffs.tar.gz
解压后得到Development文件夹,该文件夹里有两个子文件:yaffs和yaffs2。考虑到现在的NAND FLASH容量越做越大,而且yaffs2可以自动选择挂载是yaffs1还是yaffs2文件系统,这里我们移植yaffs2。当然如果你的NAND FLASH只是512+16B的,可以只移植yaffs,因为即使你移植了yaffs2,它也会自动选择挂载yaffs1的。
(3)在要移植的内核目录下建立yaffs2文件夹,并将需要的文件拷贝过来:
# cd $(linuxdir)/fs
# mkdir yaffs2
# cd yafs2
# cp /tmp/Development/yaffs2/*.c .
# cp /tmp/Development/yaffs/*.h .
# cp /tmp/Development/yaffs2/Makefile-kernel Makefile
# cp /tmp/Development/yaffs2/Kconfig .
(4),修改$(linuxdir)/fs/yaffs2中的文件:
在开始未修改该目录.c文件前,会出现很多的built-in.o的错误,要么是提示某些函数未定义,要么是某些函数重复定义,花了我很长的时间,终于找到问题所在。部分错误提示如下:(这是我开始编译yaffs时的错误,yaffs2的错误更多,但类型差不多)
fs/built-in.o(.text+0x8478c): In function `yaffs_internal_read_super_mtd':
: undefined reference to `nandmtd_WriteChunkToNAND'
fs/built-in.o(.text+0x84790): In function `yaffs_internal_read_super_mtd':
: undefined reference to `nandmtd_ReadChunkFromNAND'
fs/built-in.o(.text+0x84794): In function `yaffs_internal_read_super_mtd':
: undefined reference to `nandmtd_EraseBlockInNAND'
fs/built-in.o(.text+0x84798): In function `yaffs_internal_read_super_mtd':
: undefined reference to `nandmtd_InitialiseNAND'
查看.c文件,我发觉有很多是通过Kconfig文件里定义的CONFIG常量来判断执行的,而这些常量在你make menuconfig/xconfig后退出后会将你的选择保存到文件中,但yaffs2目录下的有些.c文件中引用了这些常量来判断,却并未加入引用config.h文件,从而会出错。将yaffs2目录下所有引用了这些常量的.c文件中加入对config.h的引用即可:#include
(5),修改$(linuxdir)/fs/Makefile和Kconfig文件。
# cd $(linuxdir)/fs
# vi Makefile (将下面一行添加到Makefile中)
obj-$(CONFIG_YAFFS_FS) += yaffs2/
# vi Kconfig (将下面一行添加到Kconfig中)
source "fs/yaffs2/Kconfig
(6),在编译内核时选择:
<*> YAFFS2 file system support
<*> 512 byte / page devices
<*> Lets Yaffs do its own ECC
<*> 2048 byte (or larger) / page devices
<*> Autoselect yaffs2 format
<*> Disable lazy loading
<*> Turn off wide tnodes
<*> Turn off debug chunk erase check
通过mkyaffsimage制做出来的image其OOB中也包含它自己计算的ECC校验数据,其校验算法有可能和MTD NAND驱动的校验算法不同,如果在内核中由MTD来处理ECC,会造成MTD认为所有的page都校验错误。所以,这也是我前面说最好把Lets Yaffs do its own ECC选上的原因,同时,要把MTD NAND驱动中的ECC校验关闭。在$(linuxdir)/drivers/mtd/nand/your_nand.c的初始化函数中设置this-eccmode = NAND_ECC_NONE.这样做实际是使用了yaffs的ECC,但在读写yaffs分区时分出现提示说:
Reading data from NAND FLASH without ECC is not recommended
Writing data without ECC to NAND-FLASH is not recommended
个人认为,其实已经使用了yaffs的ECC,只是在传给MTD时,MTD没认可,参考mtd/nand/nand_base.c文件里的nand_read_ecc函数以及yaffs2/yaffs_fs.c文件中在于ECC的定义。这里应该是提示没用NAND的ECC,而使用的是yaffs的ECC。这可以通过mkyaffsimage制作一个image来验证。解决方法:要么使用nand的ECC,将yaffs的ECC屏蔽掉;要么将nand_base.c里的相关错误信息屏蔽掉。
(7),修改你要移植的芯片中的Makefile,在devices后面添加mtdX和mtdblockX设备,设备个数视你的nand的分区个数而定,这里我的flash在your_nand.c中分成了三个区。
\
mtd0,c,90,0 mtd1,c,90,1 mtd2,c,90,2 \
\
mtdblock0,b,31,0 mtdblock1,b,31,1 mtdblock2,b,31,2
(8),编译后将kernel和文件系统下载到板子上,查看结果并挂载。
# cat /proc/mtd (查看分区情况)
mtd0: 00400000 00004000 "EV40 flash partition 1"
mtd1: 00400000 00004000 "EV40 flash partition 2"
mtd2: 00800000 00004000 "EV40 flash partition 3"
# cat /proc/filesystems (查看内核支持的文件系统)
nodev sysfs
nodev rootfs
nodev bdev
nodev proc
nodev sockfs
nodev futexfs
nodev pipefs
nodev eventpollfs
ext2
nodev ramfs
nodev devfs
nodev nfs
nodev jffs2
romfs
yaffs
yaffs2
nodev rpc_pipefs
我们发现系统已经支持yaffs和yaffs2文件系统了。
# eraseall /dev/mtd0 (在挂载之前可以先将该分区里的内容擦除掉)
# mount –t yaffs2 /dev/mtdblock0 /mnt (将第1个分区挂载到/mnt目录下)
yaffs: dev is 32505856 name is "mtdblock0"
yaffs: Attempting MTD mount on 31.0, "mtdblock0"
yaffs: auto selecting yaffs1
我们发现如果你的flash是512+16B / page的,即使你选择的是yaffs2文件系统,内核也会自动选择挂载yaffs1文件系统。
- Arm嵌入式开发之Flash文件系统建立
- Arm嵌入式开发之Flash设备驱动
- arm嵌入式开发之终端设备
- ARM flash文件系统分区
- 嵌入式系统实现FLASH文件系统存储之我见一
- 嵌入式系统开发之根文件系统
- [ARM嵌入式系统开发]第一章之Dhrystone
- Arm嵌入式开发之I2C总线
- Arm嵌入式开发之网络设备驱动
- arm嵌入式开发之linux音频设备
- Arm嵌入式开发之LCD驱动
- 嵌入式系统开发之环境的建立
- 嵌入式系统开发之环境的建立
- 嵌入式开发之DRAM/SARM/NOR FLASH/NAND FLASH
- [ARM嵌入式系统开发]第一章之嵌入式系统的软硬件
- ARM嵌入式开发
- Arm 嵌入式 开发 要点
- 嵌入式arm开发学习
- C语言的那些小秘密之【volatile】
- C语言的那些小秘密之【预处理】
- Arm嵌入式开发之LCD驱动
- C语言的那些小秘密之【异常处理】
- Arm嵌入式开发之Flash设备驱动
- Arm嵌入式开发之Flash文件系统建立
- java设计模式六大原则(5):迪米特法则
- Arm嵌入式开发之USB主机与设备驱动
- Android学习笔记---android数据存储与访问
- module_param与MODULE_PARM_DESC
- 代码之美——Doom3源代码赏析
- Linux应用程序编译,模块编译
- java设计模式六大原则(6):开闭原则
- Linux中的并发 竞态控制