uClinux下Nor Flash的JFFS2文件系统构建
- 格式:doc
- 大小:14.54 KB
- 文档页数:4
uclinux下Nand Flash的JFFS2文件系统的移植uclinux下Nand Flash的JFFS2文件系统的移植(写在前面)现在(2005-12-5),linux对mtd设备支持的好得多,远没有我当时(大概2.5年前吧)做得那么复杂了,这里仍然要发原文,是因为想给初学者提供一个参考思路,介绍一下我对linux的学习了解的整个过程,希望对大家有借鉴意义。
但是,建议还是使用最新的mtd补丁,新版本的mtd包括了对2k page 的nand flash的支持,要使用大于128MB的Nand flash,就用这个吧。
文件系统方面,建议在Nor flash上,使用jffs2(jffs3也有,但是,我没用过,没有发言权)。
在Nand flash上强烈建议使用yaffs,这比jffs2快很多,而且支持direct模式,在其他系统,比如:uCOS-II、winCE等都可以使用。
我已经做到了在uCOS-II下和Linux下通过yaffs文件系统实现共享。
但是,要想使用2k page的nand flash,只有使用yaffs2了。
现在,yaffs2开源的代码有点问题,不能直接和mtd设备配合使用,稍作修改可以实现,有兴趣,我可以专门再写一片yaffs2的移植心得。
uclinux下Nand Flash的JFFS2文件系统的移植(1)继续上一篇《uClinux下移植Ne2000兼容的网卡驱动程序》中介绍的平台和操作系统,开始写JFF2的感想。
虽然JFFS2的移植弄出来有一段时间了,但是,前一段时间忙着期末考试,无心写心得。
昨天总算考完了,我就继续罗嗦那段时期的经历吧,希望把我遇到的问题和解决的方法和大家共享。
错误之处也请不吝指出。
我使用的uClinux的硬件平台还是44B0那个板子具体的情况参见《uClinux下移植Ne2000兼容的网卡驱动程序》中的介绍。
Flash我用的是三星公司的K9F2808——16MByte的Nand Flash。
一、烧写一个支持flash擦写的内核1.配置内核JFFS2_FS=yJFFS2_FS_DEBUG=0JFFS2_FS_WRITEBUFFER=yMTD_CONCAT=y2.配置用户应用MTD utils->[*]mtd-utils[*]erase[*]eraseall3. 编译并烧写系统二、编译kernel和制作jffs2文件系统1. 配置内核INITRAMFS_SOURCE 清空该配置项内容SYSFS=y2.修改source/linux-2.6.36.x/drivers/mtd/ralink/ralink_spi.c80-83行增加内容如下:3.修改source/linux-2.6.36.x/drivers/mtd/maps/ralink-flash.h修改30-32行内容如下:内核分配1.5M flash,其余全部给文件系统,实际做错来内核1.4M4.修改启动参数source/linux-2.6.36.x/arch/mips/ralink/cmdline.c 51行console=ttyS1,57600n8 root=/dev/mtdblock5 rootfstype=jffs2 rw5.编译内核6.mkfs.jffs2工具安装a)lzo-2.06.tar.gz ./configure && make && make installb)e2fsprogs-1.42.tar.gz ./configure && make && make install &&make install-libsc)yum install libacl-develd)mtd-utils-1.4.8.tar.gz make && make install7.制作jffs2文件系统镜像mkfs.jffs2 -s 0x1000 -e 0x10000 -p 0xe30000 -d romfs/ -o jffs.img 注:0xe30000为指定文件系统大小,我在这里指定剩余flash大小,除非对flash增加分区,否则使用剩余flash大小,以免flash浪费三、刷kernel 和jffs.img1.启动第一次刷进的系统,并使用tftp将kernel 和jffs.img 上传内存2. 擦除flasheraseall /dev/mtd43.写kerneldd if=kernel of=/dev/mtd44.写文件系统dd if=jffs.img of=/dev/mtd4 bs=65536 seek=24重启系统ok~~~~增加或删除文件后需要执行sync命令方可生效,文件大时虽然命令返回,但仍需等待一会,方可生效。
JFFS2文件系统在μClinux中的实现作者:行喜梁刘树东戴学丰来源:《现代电子技术》2009年第10期摘要:FLASH作为新型非易失性半导体存储器在嵌入式系统的开发中占有重要的地位。
为了在嵌入式系统中实现数据的动态操作,介绍μClinux下的FLASH文件系统,特别是日志型文件系统的设计原理及特点;利用Linux提供的MTD接口,通过添加与FLASH对应的map driver和FLASH驱动,修改设备节点,配置内核等步骤,将JFFS2文件系统移植到s3c44b0使用的FLASH 芯片上。
通过挂载,用户可以像使用普通硬盘分区一样对此目录下面的文件进行操作,从而实现对FLASH的动态操作和管理。
结果表明,在JFFS2 文件系统下,保存的文件是可读写的,系统掉电后创建的文件也不会丢失。
关键词:FLASH;JFFS2;内存技术设备;嵌入式系统中图分类号:TN302文献标识码:A文章编号:1004-373X(2009)10-051-04Realization of JFFS2 File System in μC linuxXING Xiliang,LIU Shudong,DAI Xuefeng(School of Computer and Control Engineering,Qiqihaer University,Qiqihaer,161006,China)Abstract:FLASH as a new type of non-volatile semiconductor memory plays an important role in embedded systems development.For achieving operating the data dynamically under embedded system,the FLASH file system under μClinux,in particular the design principles and charactertistecs of JFFS2(log-file system)is ing MTD interface provided by Linux,through adding map driver and FLASH driver,modifying the device nodes,such as configuring core etc,transplanting JFFS2 file system to the FLASH chips of s3c44b0.Through the mount,users can operate the files under this directory as an ordinary hard driver partition,achieving operating dynamicly and managing for FLASH.The results show that files can be read and write after the creation under the JFFS2 file system.The files can′t be lost even if the power is down.Keywords:FLASH;JFFS2;MTD;embedded system0 引言嵌入式系统开发中,一些重要的工艺参数在控制过程中需要动态地改变和保存,使用硬盘等存储介质又显得不太现实,而FLASH芯片以相对低廉的价格提供了高可靠性和高密度的存储,已成为嵌入式系统重要的存储设备。
Nand flash驱动移植及带硬件Ecc的Jffs2文件系统制作cd /new_disk/weiyan/linux-2.6.25vi arch/arm/mach-s3c2440/mach-smdk2440.c修改板级配置文件,为统一驱动的配置,设备的配置信息一般在此文件中添加。
1)添加头文件#include <linux/mtd/nand.h>#include <linux/mtd/nand_ecc.h>#include <linux/mtd/partitions.h>#include <asm/plat-s3c/nand.h>#include <asm/plat-s3c24xx/pm.h>2)添加nand划分信息static struct mtd_partition wy_nand_part[] = {[0] = { //u-boot及内存存放的分区.name = "BOOT",.size = SZ_2M,.offset = 0,},[1] = { //文件系统存放的分区.name = "ROOTFS",.offset = SZ_2M,.size = SZ_32M,},[2] = { //剩余空间.name = "BACKUP",.offset = SZ_32M + SZ_2M,.size = SZ_32M - SZ_2M,},};static struct s3c2410_nand_set wy_nand_sets[] = {[0] = {.name = "NAND",.nr_chips = 1,.nr_partitions = ARRAY_SIZE(wy_nand_part),.partitions = wy_nand_part,},};3)添加nand flash的读写匹配时间,各时间定义如图static struct s3c2410_platform_nand wy_nand_info = {.tacls = 10,.twrph0 = 25,.twrph1 = 10,.nr_sets = ARRAY_SIZE(wy_nand_sets),.sets = wy_nand_sets,};4)添加nand设备到初始化表static struct platform_device *smdk2440_devices[] __initdata = { ……(此处省略其他设备,添加时请注意。
嵌入式系统文件系统比较jffs2...转载一篇linux 文件比较的。
Linux支持多种文件系统,包括ext2、ext3、vfat、ntfs、iso9660、jffs、romfs和nfs等,为了对各类文件系统进行统一管理,Linux引入了虚拟文件系统VFS(Virtual File System),为各类文件系统提供一个统一的操作界面和应用编程接口。
Linux启动时,第一个必须挂载的是根文件系统;若系统不能从指定设备上挂载根文件系统,则系统会出错而退出启动。
之后可以自动或手动挂载其他的文件系统。
因此,一个系统中可以同时存在不同的文件系统。
不同的文件系统类型有不同的特点,因而根据存储设备的硬件特性、系统需求等有不同的应用场合。
在嵌入式Linux应用中,主要的存储设备为 RAM(DRAM, SDRAM)和ROM(常采用FLASH存储器),常用的基于存储设备的文件系统类型包括:jffs2, yaffs, cramfs, romfs, ramdisk, ramfs/tmpfs等。
1. 基于FLASH的文件系统Flash(闪存)作为嵌入式系统的主要存储媒介,有其自身的特性。
Flash的写入操作只能把对应位置的1修改为0,而不能把0修改为1(擦除Flash就是把对应存储块的内容恢复为1),因此,一般情况下,向Flash写入内容时,需要先擦除对应的存储区间,这种擦除是以块(block)为单位进行的。
闪存主要有NOR和NAND两种技术(简单比较见附录)。
Flash存储器的擦写次数是有限的,NAND闪存还有特殊的硬件接口和读写时序。
因此,必须针对Flash的硬件特性设计符合应用要求的文件系统;传统的文件系统如ext2等,用作Flash的文件系统会有诸多弊端。
在嵌入式Linux下,MTD(Memory T echnology Device,存储技术设备)为底层硬件(闪存)和上层(文件系统)之间提供一个统一的抽象接口,即Flash的文件系统都是基于MTD驱动层的(参见上面的Linux 下的文件系统结构图)。
Linux环境下flash文件系统JFFS2移植指南Linux环境下flash文件系统JFFS2移植指南目录1 文件系统 (3)2 Flash存储器 (3)3 Flash文件系统 (4)3.1 flash文件系统基本结构 (4)3.2 日志文件系统 (4)3.3 MTD驱动程序 (5)3.4 JFFS2文件系统 (5)4 JFFS2移植 (5)4.1 MTD配置 (5)4.2 FLASH分区 (7)4.3 jffs2镜像制作 (8)4.4 jffs2镜像烧写 (9)4.4.1 烧录方法1 (9)4.4.2 烧录方法2 (9)4.5 使用jffs2作为根文件系统rootfs (9)1 文件系统文件系统是一个操作系统中最重要的部分之一,它为操作系统提供了一种结构化存储和管理数据的方式。
文件系统的主要功能是对数据的物理存储进行管理,并向用户提供对数据的访问接口。
用户程序建立在文件系统上,通过文件系统访问数据,而不需要直接对物理存储设备进行操作。
最初的操作系统一般都只支持单一的一种文件系统,并且文件系统和操作系统内核紧密关联在一起,而Linux操作系统的文件系统结构是树状的,在根目录“/’下有许多子目录,每个目录都可以采用各自不同的文件系统类型。
Linux中的文件不仅指的是普通的文件和目录,而且将设备也当作一种特殊的文件,因此,每种不同的设备,从逻辑上都可以看成是一种不同的文件系统。
在Linux操作系统中,为了支持多种不同的文件系统,采用了虚拟文件系统(VFS,Visual Filesystem Switch)技术,虚拟文件系统是对多种实际文件系统的共有功能的抽象,它屏蔽了各种不同文件系统在实现细节上的差异,为用户程序提供了统一的、抽象的、标准的接口对文件系统进行访问,如open(),read(),write()等。
这样,用户程序就不需要关心所操作的具体文件是属于哪种文件系统,以及这种文件系统是如何设计与实现的,对所有文件的访问方式都是完全相同的。
uClinux下Nor Flash的JFFS2文件系统构建目前的系统多用法FLASH作为主存,因此,如何有效管理FLASH上的数据十分重要文章以SST39VF160芯片为例,研究了在Nor Flash上建立的JFFS2文件系统的普通步骤,从而为FLASH上的数据管理提供了抱负的挑选方式嵌入式系统正随着Internet的进展而在各个领域得到广泛的应用,作为嵌入式应用的核心,嵌入式以其自由软件特性正日益被人们看好Linux具有内核小效率高源代码开放等优点,还内涵了完整的TCP/IP 网络协议,因此十分适于嵌入式系统的应用而作为特地运行于没有MMU的微处理器的嵌入式操作系统,uClinux更是得到广泛应用当前的嵌入式系统开发,需要便利灵便的用法Flash NOR和NAND是现在市场上两种主要的非易失闪存技术 Intel于1988年首先开发出NOR flash技术,彻底转变了原先由EPROM和EEPROM一统天下的局面 NOR 的特点是芯片内执行XIP eXe-cute In Place ,这样应用程序可以挺直在flash闪存内运行,不必再把代码读到系统RAM中 NOR的传输效率很高,在1~4MB的小容量时具有很高的成本效益,因此在嵌入式系统得到广泛的应用1 JFFS2文件系统简介uClinux通常默认ROMFS作为根文件系统,它相对于普通的EXT2文件系统具有节省空间的优点但是ROMFS是一种只读的文件系统,不支持动态擦写保存虽然对于需要动态保存的数据可以采纳虚拟ram盘的办法来保存,但当系统掉电后,ram盘的内容将所有走失,而不能永远保存,因此需要实现一个可读写的文件系统 JFFS2文件系统便是一个很好的挑选JFFS文件系统是瑞典Axis通信公司开发的一种基于Flash的日志文件系统,它在设计时充分考虑了Flash的读写特性和用电池供电的嵌入式系统的特点,在这类系统中必须确保在读取文件时,假如系统骤然掉电,其文件的牢靠性不受到影响对Red Hat的David Woodhouse举第1页共7页。
uClinux下NAND FLASH的JFFS2文件系统的构建当前的嵌入式系统开发,需要方便灵活的使用Flash。
Nor和Nand是现在市场上两种主要的非易失闪存技术。
Nor更适合用于存放少量的代码,而Nand则是高数据存储密度的理想解决方案。
2 JFFS2文件系统简介JFFS2的底层驱动主要完成文件系统对Flash芯片的访问控制,如读、写、擦除操作。
在Linux中这部分功能是通过调用MTD驱动实现的。
相对于常规块设备驱动程序,使用MTD驱动程序的主要优点在于MTD驱动程序是专门为基于闪存的设备所设计的,所以它们通常有更好的支持、更好的管理和更好的基于扇区的擦除和读写操作的接口3 Nand Flash及其与ARM CPU的硬件连接本文采用的Nand Flash是三星公司的K9F2808芯片。
它的存储空间以页为单位,一页是由512字节的数据和16字节的备用空间组成,其中备用空间可用来存春ECC纠错码、坏块信息和文件系统相关的数据。
我们只考虑数据空间即可,因此我们认为每页大小为512字节,32页组成一个块,故块的大小为16K。
4 JFFS2底层MTD驱动编写在Linux-2.4.x/drivers/mtd/nand/目录下加入44b0x.c文件,该文件是基于同一目录下其他文件(如spia.c)修改的。
主要修改如下3处:1) #define MYARM_IO_BASE 0x01d20000#define MYARM_FIO_BASE 0x2000000#define MYARM_PEDR 0x0014#define MYARM_PEDDR 0x00102) 定义Nand Flash设备的分区(根据用户需要来确定分区的大小和分区的数量)。
#ifdef CONFIG_MTD_PARTITIONSconst static struct mtd_partition partition_info[]={{ name: "NAND flash partition 1(6MB)",offset: 2*1024*1024,size: 6*1024*1024 },{ name: "NAND flash partition 2(6MB)",offset: 8*1024*1024,size: 6*1024*1024 } };#define NUM_PARTITIONS 2#endif3)定义与特定硬件相关的控制线操作函数void arm_hwcontrol(int cmd){switch(cmd){case NAND_CTL_SETCLE: (*(volatile unsigned *) (arm_io_base + arm_pedr)) |= 0x04; break;case NAND_CTL_CLRCLE: (*(volatile unsigned *) (arm_io_base + arm_pedr)) &= ~0x04; break;case NAND_CTL_SETALE: (*(volatile unsigned *) (arm_io_base + arm_pedr)) |= 0x08; break;case NAND_CTL_CLRALE: (*(volatile unsigned *) (arm_io_base + arm_pedr)) &= ~0x08; break;case NAND_CTL_SETNCE: (*(volatile unsigned *)(arm_io_base + arm_pedr)) &= ~0x02; break;case NAND_CTL_CLRNCE: (*(volatile unsigned *) (arm_io_base + arm_pedr)) |= 0x02; break;}}5 JFFS2文件系统的移植5.1修改MAKEFILE文件obj-$(CONFIG_MTD_NAND_MYARM) += 44b0x.o这样在运行对内核的Make时,就会编译44b0x.c文件了。
建立基于NOR FLASH的JFFS2根文件系统的步骤mafaqing, 2010-6-3文档约定:Host - 为虚拟机系统命令行环境EVM - 为U-Boot命令行环境Target - 为终端linux命令行环境1.把rootfs.jffs2和uImage_nor_jffs2上传到HOST的/opt/tftp目录下2.在HOST下执行下面的命令host # xinetd3.启动板子,并在U-BOOT环境下执行下面命令格式化NOR FLASH的内核和根文件系统分区EVM # protect off 0x02060000 0x03000000EVM # erase 0x02060000 0x03000000注: (1).切不要格式化其他分区(2).0x02040000 ~ 0x03000000为内核和文件系统存放的开始地址及结束地址4.下载新内核uImage_nor_jffs2到内存EVM # tftp 0x80700000 uImage_nor_jffs25.烧写新的内核到FLASH分区(内核)上EVM # cp.b 0x80700000 0x02060000 0x1600006.下载JFFS2文件系统镜像文件到内存EVM # tftp 0x80700000 rootfs.jffs27.烧写JFFS2文件系统镜像到FLASH分区(根文件系统)上EVM # cp.b 0x80700000 0x02240000 0x8da2fc8.修改内核启动参数,使系统使用FLASH上的JFFS2根文件系统,并保存参数EVM # setenv bootargs 'console=ttyS0,115200n8video=dm64xxfb:interface=composite:mode=pal:output=pal noinitrd rw ip=offroot=/dev/mtdblock3 rootfstype=jffs2 rw noinitrd mem=120M'EVM # saveenv9.手动断电复位板子,重新启动系统注: 首次启动系统时因为要对FLASH分区进行一些初始化,因些首次启动系统时需要等待一段时间.10.通过SSH客户端连接板子,把程序上传到FLASH系统下的/opt(不要上传到其他目录),并进行测试IP:192.168.1.33用户名:root密码:dm6446注: (1).测试程序时,在执行完loadmodules.sh后,需要再执行下面的命令target # /sbin/mdev -s(2).上传测试程序时,要注意FLASH的可用空间,如果空间不够时请删掉到/opt目录下的一些不用的程序可使用下面的命令查看当时FLASH的空间的使用情况target # /bin/df -ahFilesystem Size Used Available Use% Mounted onrootfs 13.8M 9.4M 4.4M 68% //dev/root 13.8M 9.4M 4.4M 68% /proc 0 0 0 0% /procsysfs 0 0 0 0% /systmpfs 46.1M 0 46.1M 0% /tmpmdev 64.0k 0 64.0k 0% /devdevpts 0 0 0 0% /dev/ptstmpfs 46.1M 0 46.1M 0% /dev/shmusbdevfs 0 0 0 0% /proc/bus/usbnone 46.1M 8.0k 46.1M 0% /var/runnone 46.1M 0 46.1M 0% /tmp其中 rootfs即为当前FLASH根文件系统分区的使用情况。
JFFS2根文件制作由于使用的ubantu7.04的环境没有安装制作JFFS2文件系统镜像的工具mkfs.jffs2,所以首先在Linux系统中安装mkfs.jffs2工具,安装的过程如下:1.下载MTD工具包本处使用的是mtd-snapshot-20050519.tar.bz2:farsight#tar –jxvf mtd-snapshot-20050519.tar.bz2farsight#cd mtdfarsight#./configurefarsight#makefarsight#make install如果系统中没有安装ZLIB库,那么首先安装ZLIB库。
具体的安装过程如下:farsight#tar –zxvf zlib-1.2.3.tar.gzfarsight#cd zlib-1.2.3farsight#./configurefarsight#makefarsight#make install完成此步骤后,系统中就有了mkfs.jffs2的工具。
注意:这个工具不同于mkfs.ext2工具,它只能制作相应的JFFS2文件系统的镜像,而不具有进行格式化的功能,而mkfs.ext2具备这以上两种功能。
然后用这个工具就可以制作JFFS2文件系统的镜像了。
2、制作JFFS2文件镜像实验平台用到的nand flash 是K9F1208,在制作镜像过程添加的参数需要和它对应。
farsight#mkfs.jffs2 -r /source/rootfs -o rootfs.jffs2 -e 0x4000 --pad=0x800000 -n 这样就会生成一个8M大小的rootfs.jffs2的镜像,它也正是JFFS2文件系统的镜像,关于这个命令行里的选项的内容,可以用man a mkfs.jffs2命令来查看内容。
JFFS2 维护了几个链表来管理擦写块,根据擦写块上的内容,一个擦写块会在不同的链表上。
具体来说,当一个擦写块上都是合法(valid)的节点时,它会在clean_list 上;当一个擦写块包含至少一个过时(obsolete)的节点时,它会在dirty_list 上;当一个擦写块被擦写完毕,并被写入CLEANMARKER 节点后,它会在free_list 上。
JFFS2文件系统及新特性介绍(reset)成逻辑1。
D)闪存的使用寿命是有限的。
具体来说,闪存的使用寿命是由擦写块的最大可擦写次数来决定的。
超过了最大可擦写次数,这个擦写块就成为坏块(bad block)了。
因此为了避免某个擦写块被过度擦写,以至于它先于其他的擦写块达到最大可擦写次数,我们应该在尽量小的影响性能的前提下,使擦写操作均匀的分布在每个擦写块上。
这个过程叫做磨损平衡(wear leveling)。
NOR flash与NAND flash的不同之处:A)NOR flash读/写操作的基本单位是字节;而NAND flash又把擦写块分成页(page),页是写操作的基本单位,一般一个页的大小是512或2K个字节。
对于一个页的重复写操作次数是有限制的,不同厂商生产的NAND flash有不同的限制,有些是一次,有些是四次,六次或十次。
B)按照现在的技术水平,一般来说NOR flash擦写块的最大可擦写次数在十万次左右,NAND flash擦写块的最大可擦写次数在百万次左右。
1.2闪存转换层将磁盘文件系统(ext2,FAT)运行在闪存上的很自然的方法就是在文件系统和闪存之间提供一个闪存转换层(Flash Translation Layer),它的功能就是将底层的闪存模拟成一个具有512字节扇区大小的标准块设备(block device)。
对于文件系统来说,就像工作在一个普通的块设备上一样,没有任何的差别。
图一一个闪存转换层的最简单的实现就是将模拟的块设备一对一的映射到闪存上。
举例来说,当上层的文件系统要写一个块设备的扇区时,闪存转换层要做下面的操作来完成这个写请求:1将这个扇区所在擦写块地数据读到内存中,放在缓存(buffer)中2将缓存中与这个扇区对应的内容用新的内容替换掉3对该擦写块执行擦写操作4将缓冲中的数据写回该擦写块这种实现方式的缺点是很明显的:1效率低,对一个扇区的更新要重写整个擦写块上的数据,造成数据带宽很大的浪费。
在嵌入式Linux系统中挂载 jffs2 根文件系统我已经在《构建基本的嵌入式Linux根文件系统》介绍了如何建立基本的嵌入式Linux根文件系统,并用NFS挂载成功。
如果要以挂载JFFS2格式的根文件系统,其基本方法就是将这个建立好的根文件系统制作成jffs2镜像,烧到FLASH中,改改Linux的启动参数即可。
具体做法如下:一、宿主机HOST编译制做MTD工具从/下载mtd-utils 的tarball,可以下载最新的。
然后解压,并在其目录下make 就好!二、制作根文件系统的JFFS2镜像。
各参数的意义:(1)-r :指定要做成image的源資料夾.(2)-o : 指定輸出image檔案的文件名.(3)-e : 每一塊要抹除的block size,預設是64KB.要注意,不同的flash, 其block size會不一樣.我的是三星的K9F1208U0B.(4)--pad (-p): 用16進制來表示所要輸出檔案的大小,也就是root.jffs2的size。
很重要的是, 為了不浪費flash空間, 這個值最好符合flash driver所規劃的區塊大小.以我的板子來說,就是5MB.(5)如果挂载后会出现类似:CLEANMARKER node found at 0x0042c000 has totlen 0xc != normal 0x0 的警告,则加上-n 就会消失。
(6) 还有的选项,自己看帮助!-h三、烧写JFFS2镜像到NAND FLASH。
将rootfs.jffs2拷贝到NFS共享目录,然后启动开发板。
具体操作看我的开发板信息就好了:NAND: NAND flash probing at 0x4E00000064 MBIn: serialOut: serialErr: serialHit any key to stop autoboot: 0[Tekkaman2440]#nfs 0x30008000192.168.1.22:/home/tekkamanninja/working/nfs/rootfs.jffs2dm9000 i/o: 0x20000300, id: 0x90000a46MAC: 08:08:08:08:12:27operating at 100M full duplex modeFile transfer via NFS from server 192.168.1.22; our IP address is 192.168.1.2Filename '/home/tekkamanninja/working/nfs/rootfs.jffs2'.Load address: 0x30008000Loading:################################################################# ########################################################## ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# #########################################################doneBytes transferred = 5242880 (500000 hex)[Tekkaman2440]#nand erase 0xa00000 0x500000NAND erase: device 0 offset 10485760,size 5242880 ...OK[Tekkaman2440]#nand write 0x30008000 0xa00000 0x500000NAND write: device 0 offset 10485760,size 5242880 ...5242880 bytes written: OK[Tekkaman2440]#setenv bootargs noinitrd root=/dev/mtdblock4 rootfstype=jffs2 rw console=ttySAC0,115200 init=/linuxrc mem=64M[Tekkaman2440]#bootdm9000 i/o: 0x20000300, id: 0x90000a46MAC: 08:08:08:08:12:27operating at 100M full duplex modeFile transfer via NFS from server 192.168.1.22; our IP address is 192.168.1.2Filename '/home/tekkamanninja/working/nfs/zImage.img'.Load address: 0x30008000Loading:################################################################# ########################################################## ################################################################# ################################################################# ############################################################ doneBytes transferred = 1600564 (186c34 hex)## Booting image at 30008000 ...Image Name: tekkamanninjaCreated: 2008-02-15 2:16:28 UTCImage Type: ARM Linux Kernel Image (uncompressed)Data Size: 1600500 Bytes = 1.5 MBLoad Address: 30008000Entry Point: 30008040Verifying Checksum ... OKXIP Kernel Image ... OKStarting kernel ...Uncompressing Linux.............................................................. .......................................... done, booting the kernel. Linux version 2.6.24 (tekkamanninja@Tekkaman-Ninja)(gcc version4.1.1) #1 Fri Feb 15 10:15:36 CST 2008CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177Machine: Tekkaman2440Memory policy: ECC disabled, Data cache writebackCPU S3C2440A (id 0x32440001)S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz S3C24XX Clocks,(c) 2004 Simtec ElectronicsCLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL onCPU0: D VIVT write-back cacheCPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets Built 1 zonelists in Zone order,mobility grouping on.Total pages:16256 Kernel command line: noinitrd root=/dev/mtdblock4 rootfstype=jffs2 rw console=ttySAC0,115200 init=/linuxrc mem=64Mirq: clearing pending ext status 00000200irq: clearing subpending status 00000003irq: clearing subpending status 00000002PID hash table entries: 256 (order: 8, 1024 bytes)timer tcon=00500000, tcnt a4ca, tcfg 00000200,00000000, usec 00001e57 Console: colour dummy device 80x30console [ttySAC0] enabledDentry cache hash table entries: 8192 (order: 3, 32768 bytes)Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)Memory: 64MB = 64MB totalMemory: 61464KB available (2960K code, 306K data, 120K init) Mount-cache hash table entries: 512CPU: Testing write buffer coherency: oknet_namespace: 64 bytesNET: Registered protocol family 16S3C2410 Power Management,(c) 2004 Simtec ElectronicsS3C2440: Initialising architectureS3C2440: IRQ SupportS3C2440: Clock Support, DVS offS3C24XX DMA Driver,(c) 2003-2004,2006 Simtec ElectronicsDMA channel 0 at c4800000, irq 33DMA channel 1 at c4800040, irq 34DMA channel 2 at c4800080, irq 35DMA channel 3 at c48000c0, irq 36usbcore: registered new interface driver usbfsusbcore: registered new interface driver hubusbcore: registered new device driver usbNET: Registered protocol family 2IP route cache hash table entries: 1024 (order: 0, 4096 bytes) TCP established hash table entries: 2048 (order: 2, 16384 bytes) TCP bind hash table entries: 2048 (order: 1, 8192 bytes)TCP: Hash tables configured (established 2048 bind 2048)TCP reno registeredNetWinder Floating Point Emulator V0.97 (double precision)JFFS2 version 2.2.(NAND)©; 2001-2006 Red Hat,Inc.fuse init (API version 7.9)yaffs Feb 15 2008 10:10:34 Installing.io scheduler noop registeredio scheduler anticipatory registered (default)io scheduler deadline registeredio scheduler cfq registeredSerial:8250/16550 driver $Revision:1.90 $ 4 ports,IRQ sharing enabled s3c2440-uart.0: s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440s3c2440-uart.1: s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440s3c2440-uart.2: s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize loop: module loadeddm9000 Ethernet Drivereth0: dm9000 at f6100300,f6100304 IRQ 51 MAC: 08:08:08:08:12:27 Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xxS3C24XX NAND Driver,(c) 2004 Simtec Electronicss3c2440-nand s3c2440-nand: Tacls=1, 9ns Twrph0=4 39ns, Twrph1=1 9ns NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)Scanning device for bad blocksBad eraseblock 3579 at 0x037ec000Creating 7 MTD partitions on "NAND 64MiB 3,3V 8-bit":0x00000000-0x00020000 :"U-Boot-1.3.1"0x00020000-0x00030000 :"U-Boot-1.3.1 Parameter"0x00030000-0x00500000 :"Linux2.6.24 Kernel"0x00500000-0x00a00000 :"Root(cramfs)"0x00a00000-0x00f00000 : "Root(JFFS2)"0x00f00000-0x01400000 :"Root(YAFFS)"0x01400000-0x04000000 :"DATA"usbmon: debugfs is not availables3c2410-ohci s3c2410-ohci: S3C24XX OHCIs3c2410-ohci s3c2410-ohci:new USB bus registered,assigned bus number 1s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000usb usb1: configuration #1 chosen from 1 choicehub 1-0:1.0: USB hub foundhub 1-0:1.0: 2 ports detectedmice: PS/2 mouse device common for all miceS3C24XX RTC,(c) 2004,2006 Simtec Electronicss3c2410-rtc s3c2410-rtc: rtc disabled, re-enablings3c2410-rtc s3c2410-rtc: rtc core: registered s3c as rtc0s3c2440-i2c s3c2440-i2c: slave address 0x10s3c2440-i2c s3c2440-i2c: bus frequency set to 98 KHzs3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapterS3C2410 Watchdog Timer,(c) 2004 Simtec Electronicss3c2410-wdt s3c2410-wdt:watchdog inactive,reset disabled,irq enabled TCP cubic registeredNET: Registered protocol family 1RPC: Registered udp transport module.RPC: Registered tcp transport module.s3c2410-rtc s3c2410-rtc: setting system clock to 2008-02-17 12:46:08 UTC (1203252368)VFS: Mounted root (jffs2 filesystem).Freeing init memory: 120Kinit started: BusyBox v1.9.1 (2008-02-16 15:04:08 CST)starting pid 779, tty '':'/etc/init.d/rcS'。
第一次挂载jffs2文件系统,出现:Node header CRC failed at使用的bootloader:redbootkernel版本:2.6.29flash类型:NOR FLASH.制作jffs2的命令:mkfs.jffs2 -U -d /mnt/winF/tet/romfs -D devtable.jffs2.txt -l -e 0x10000 -p -n -o /tftpboot/jffs2fs.img"-e":表示flash的擦除块大小为0x10000,这个值很重要,可以从datasheet中得到。
"-p":Pad output to SIZE bytes with 0xFF. If SIZE is not specified, the output is padded to the end of the final erase block.烧写命令:load -r -v -h 172.21.73.101 -b 0x8000 kernel.lzofis create -b 0x8000 -l 0x200000 -s 0x200000 -f 0x7F060000 -e 0x8000 kernel.lzoload -r -v -h 172.21.73.101 -b 0x100000 jffs2fs.imgfis write -b 0x100000 -f 0x7F260000 -l 0x250000fis create -f 0x7F260000 -l 0x590000 jffs2.imgreset问题描述:第一次启动,会出现CRC错误信息,如下:Shell invoked to run file: /etc/rcWelcome to____ _ _/ __| ||_|_ _| | | | _ ____ _ _ _ _| | | | | | || | _ \| | | |\ \/ /| |_| | |__| || | | | | |_| |/ \| ___\____|_||_|_| |_|\____|\_/\_/| ||_| ADVANTECH eAutomationFor further information check://eAutomation/Execution Finished, ExitingSash command shell (version 1.1.1)/> JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x06ddc8.{ff5c,ff5c,ff5cff5c,6cedd300}JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x06c8c4. {ff5c,ff5c,ff5cff5c,ff5cff5c}JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x06b3c0. {ff5c,ff5c,ff5cff5c,ff5cff5c}JFFS2 notice: (164) check_node_data: wrong data CRC in data node at 0x0006d394: read 0xc96c7e1f, calculated 0xc6974f8f.JFFS2 notice: (164) check_node_data: wrong data CRC in data node at 0x0006be3c: read 0xfaffca56, calculated 0x4e72e8e5.JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x071460. {ff1c,ff1c,ff1cff1c,ff1cff1c}JFFS2 notice: (164) read_dnode: node CRC failed on dnode at 0x0709ac: read 0x8db9f359, calculated 0x22676b8JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x06fea4. {ff1c,ff1c,ff1cff1c,ff1cff1c}JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x06f3b4. {1985,e002,0000df5e,a5032844}JFFS2 notice: (164) read_dnode: node CRC failed on dnode at 0x06e91c: read 0x603ebf95, calculated 0x28f62bdbJFFS2 notice: (164) check_node_data: wrong data CRC in data node at 0x00071d6c: read 0xe3e40d9c, calculated 0x3b79fefa.JFFS2 warning: (164) jffs2_do_read_inode_internal: Truncating ino #29 to 23732 bytes failed because it only had 12288 bytes to start with!JFFS2 notice: (164) check_node_data: wrong data CRC in data node at 0x0007c694: read 0xe9808a11, calculated 0x98c8ae6e.JFFS2 notice: (164) check_node_data: wrong data CRC in data node at 0x00076ba0: read 0x8207a914, calculated 0xa68949a.0x090240. {ff5c,ff5c,ff5cff5c,ff5cff5c}JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x08dc84. {ff1c,ff1c,ff1cff1c,ff1cff1c}Node totlen on flash (0xdf1edf1e) != totlen from node ref (0x000009d8)JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x08d1e8. {1985,e002,ff5cff5c,415e1f8f}JFFS2 notice: (164) read_dnode: node CRC failed on dnode at 0x08c7b4: read 0x62c24375, calculated 0x4b07ea0JFFS2 notice: (164) jffs2_get_inode_nodes: Node header CRC failed at 0x08b19c./>重启,则不会有如上CRC错误信息。
JFFS2文件系统分析报告本文在深入研究jffs2源代码基础上,对JFFS2文件系统的实现机制进行了分析,包括关键的数据结构及其之间的联系,文件系统的注册和挂载,以及其他主要的操作流程。
1 JFFS2层次结构在Linux系统中,JFFS2文件系统处于虚拟文件系统层VFS与存储技术设备层MTD之间,如图1所示。
VFS为内核中的各种文件系统提供一个统一的抽象层,并为上层用户提供具有统一格式的接口函数;MTD子系统整合底层芯片驱动,为上层文件系统提供了统一访问MTD设备(主要是NOR闪存和NAND闪存等设备)的接口。
JFFS2在内存中建立超级块信息jffs2_sb_info管理文件系统操作,建立索引节点信息jffs2_inode_info管理打开的文件。
VFS层的超级块super_block和索引节点inode分别包含JFFS2文件系统的超级块信息jffs2_sb_info和索引节点信息jffs2_inode_info,它们是JFFS2和VFS间通信的主要接口。
JFFS2文件系统的超级块信息jffs2_sb_info包含底层MTD设备信息mtd_info指针,文件系统通过该指针访问MTD设备,实现JFFS2和底层MTD设备驱动之间的通信。
图1 JFFS2文件系统层次2 JFFS2数据实体JFFS2在Flash上只存储两种类型的数据实体,分别为jffs2_raw_inode和jffs2_raw_ dirent。
■jffs2_raw_dirent:包括文件名、ino号、父节点ino号、版本号、校验码等信息,它用来形成整个文件系统的层次目录结构。
■jffs2_raw_inode:包括文件ino号、版本号、访问权限、修改时间、本节点所包含的数据文件中的起始位置及本节点所包含的数据大小等信息,它用来管理文件的所有数据。
一个目录文件由多个jffs2_raw_dirent组成。
而普通文件,符号链接文件,设备文件,FIFO文件等都由一个或多个jffs2_raw_inode数据实体组成。
uClinux下Nor Flash的JFFS2文件系统构建摘要:目前的嵌入式系统多使用FLASH作为主存,因此,如何有效管理FLASH上的数据非常重要。
文章以SST39VF160芯片为例,讨论了在Nor Flash上建立uClinux的JFFS2文件系统的一般步骤,从而为FLASH上的数据管理提供了理想的选择方式。
关键词:uClinux;Nor Flash;MTD;JFFS2;文件系统嵌入式系统正随着Internet的发展而在各个领域得到广泛的应用,作为嵌入式应用的核心,嵌入式Linux以其自由软件特性正日益被人们看好。
Linux具有内核小、效率高、源代码开放等优点,还内涵了完整的TCP/IP网络协议,因此非常适于嵌入式系统的应用。
而作为专门运行于没有MMU的微处理器的嵌入式操作系统,uClinux更是得到广泛应用。
当前的嵌入式系统开发,需要方便灵活的使用Flash。
NOR和NAND是现在市场上两种主要的非易失闪存技术。
Intel于1988年首先开发出NORflash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面。
NOR的特点是芯片内执行?XIP? eXe-cuteInPlace?,这样应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。
NOR的传输效率很高,在1~4MB的小容量时具有很高的成本效益,因此在嵌入式系统得到广泛的应用。
1JFFS2文件系统简介uClinux通常默认ROMFS作为根文件系统,它相对于一般的EXT2文件系统具有节约空间的优点。
但是ROMFS是一种只读的文件系统,不支持动态擦写保存。
虽然对于需要动态保存的数据可以采用虚拟ram盘的方法来保存,但当系统掉电后,ram盘的内容将全部丢失,而不能永久保存,因此需要实现一个可读写的文件系统。
JFFS2文件系统便是一个很好的选择。
JFFS文件系统是瑞典Axis通信公司开发的一种基于Flash的日志文件系统,它在设计时充分考虑了Flash的读写特性和用电池供电的嵌入式系统的特点,在这类系统中必需确保在读取文件时,如果系统突然掉电,其文件的可靠性不受到影响。
对RedHat的DavidWoodhouse进行改进后,形成了JFFS2。
主要改善了存取策略以提高FLASH的抗疲劳性,同时也优化了碎片整理性能,增加了数据压缩功能。
需要注意的是,当文件系统已满或接近满时,JFFS2会大大放慢运行速度。
这是因为垃圾收集的问题。
JFFS2的底层驱动主要完成文件系统对Flash芯片的访问控制,如读、写、擦除操作。
在Linux中这部分功能是通过调用MTD(memorytechnologydevice内存技术设备)驱动实现的。
相对于常规块设备驱动程序,使用MTD驱动程序的主要优点在于MTD驱动程序是专门为基于闪存的设备所设计的,所以它们通常有更好的支持、更好的管理和更好的基于扇区的擦除和读写操作的接口。
MTD相当于在硬件和上层之间提供了一个抽象的接口,可以把它理解为FLASH的设备驱动程序,它主要向上提供两个接口:MTD字符设备和MTD块设备。
通过这两个接口,就可以象读写普通文件一样对FLASH设备进行读写操作。
经过简单的配置后,MTD在系统启动以后可以自动识别支持CFI或JEDEC接口的FLASH芯片,并自动采用适当的命令参数对FLASH进行读写或擦除。
JFFS2在uClinux中有两种使用方式,一种是作为根文件系统,另一种是作为普通文件系统在系统启动后被挂载。
考虑到实际应用中需要动态保存的数据并不多,且在Linux系统目录树中,根目录和/usr等目录主要是读操作,只有少量的写操作,但是大量的读写操作又发生在/var和/tmp目录(这是因为在系统运行过程中产生大量log文件和临时文件都放在这两个目录中),因此,通常选用后一种方式。
根文件指的是Romfs、var和/tmp,目录采用Ramfs,当系统断电后,该目录所有的数据都会丢失。
综上所述,通常在uClinux下采用的文件系统构成。
对于本文来说,图中Romfs和Ramfs两个文件系统的实现是很方便的,主要需要实现的是NorFlash的底层MTD驱动,下面就以SST39VF160芯片为例来介绍MTD的驱动设计方法。
2JFFS2底层MTD驱动设计本文采用的系统以三星公司的SND-100为母板,CPU为ARM7TDMI芯片S3C4510B,16M的SDRAM,NorFlash为SST39VF160,容量为1M×16bit,速度为70ns,通过16位数据总线与CPU交换数据,擦写次数典型值为10万次。
在\linux-2.4.x\drivers\mtd\maps目录下,每一个文件都是一个具体的MTD原始设备的相关信息,包括该MTD原始设备的起始物理地址、大小、分区情况、读写函数、初始化和清除程序。
设计时,需要对SST39VF160编写相关的程序,假设为S3C4510B.C。
则需要进行以下几点操作:(1) 定义SST39VF160在系统中的起始地址、大小、总线宽度#defineWINDODDR0x1000000|0x04000000//注意FLASH分区地址必须是non-cacheble#defineWINDOWSIZE0x200000#defineBUSWIDTH2(2) 定义SST39VF160分区典型的内存分区应包括:内核引导区、Linux内核区、应用区。
其中内核引导区用来保存内核加载程序,Linux内核区存放的是经过压缩的uClinux内核,应用区则用来保存用户的数据和应用程序,该区设为我们要采用的JFFS2文件系统。
具体如下:staticstructmtd_partitions3c4510_partitions[]={{name: ″bootloader(128K)″,size: 0x20000,offset: 0x0000,mask_flags:MTD_WRITEABLE//设置成只读区域},{name: ″uClinux_kernel(832K)″,size: 0xd0000,offset: 0x20000,},?{name: ″jffs2 (1088K)?″,size: 0x110000,offset: 0xf0000}};?(3) 定义SST39VF160字节、半字、字的读写操作函数。
(4) 初始化SST39VF160函数int_initinit_s3c4510b()。
该操作主要包括两个方面:第一是调用domapprobe()检测搜索MTD设备。
通常检测方式有两种:cfiprobe和jedecprobe,这里采用后一种,该方法在jedec_probe.c文件中定义。
另外,jedecprobe.c中定义了各种jedecprobe类型芯片的信息,有些linux版本没有包含SST39VF160,需要手动添加;而操作的第二方面则是调用add_mtd_partitions()以将your_partiton的各个分区加入mtd_table。
3内核相关配置的设定3.1内核配置文件设置为使内核支持JFFS2,需在内核配置选项菜单里选择相关选项。
首先把SST39VF160的MTD驱动加入配置菜单。
并在mtd/maps/Config.in文件中加入如下程序:if[″$CONFIGARM″= ″y″]; thendep_tristate′CFIFlashdevicemappedonSamsungS3C4510B′CONFIG_MTD_S3C4510B$CONFIG_MTD_CFI相应\mtd\maps\Makefile文件加入obj_$(CONFIG_MTD_S3C4510B)+=s3c4510b.o其次选择Menuconfig下的配置选项。
在linuxKernelv2.4.20-uc0Configuration下MemoryTechnologyDevices?MTD?下CONFIG_MTD=YCONFIG_MTD_DEBUG=YCONFIG_MTD_DEBUG_VERBOSE=3CONFIG_MTD_PARTITIONS=YCONFIG_MTD_CHAR=YCONFIG_MTD_BLOCK=YRAM/ROM/Flashchipdrivers下CONFIG_MTD_CFI=YCONFIG_MTD_JEDECPROBE=YCONFIG_MTD_CFI_AMDSTD=YMappingdriversforchipaccess下CONFIG_S3C4510B=YFilesystems下CONFIG_JFFS2_FS=YCONFIG_JFFS2_FS_DEBUG=2在uClinuxv1.3.4Configuration下FlashTools下CONFIG_USER_MTDUTILS=YCONFIG_USER_MTDUTILS_ERASE=YCONFIG_USER_MTDUTILS_ERASEALL=YCONFIG_USERMTDUTILS_MKFSJFFS2=YBusyBox下选中cat,cp,dd, mount,umount,mkdir工具。
3.2MTD块设备配置下面是修改系统块设备的主设备号。
默认情况下,MTDBLOCK主设备号为31,与BLKMEM的主设备号冲突,因此修改\mtd\mtd.h中MTDBLOCKMAJOR的值为30。
接着应添加MTD设备节点到/vender/--你所使用的目标机类型--/Makefile文件中。
其中字符设备的主设备号为90,次设备号为0、2、4、6...(奇数次设备号为只读设备),块设备的主设备号为31,次设备号为0、1、2、3。
可按以下方式增加DEVICES目标:mtd0,c,90,0mtd1,c,90,1mtd2,c,90,2mtdblock0,b,30,0mtdblock1,b,30,1mtd-block2,b,30,2做完以上步骤,可以运行内核编译命令makedep, make以对内核进行编译。
当系统启动时,可以看到以下信息:s3c4510bflashdevice: 200000at5000000Found: SSTSST39VF160numberofJEDECchips: 1Creating3MTDpartitionson ″S3C4510Bflashde-vice″:0x00000000-0x00020000: ″bootloader(128K)″mtd:Givingoutdevice0tobootloader(128K) 0x00020000-0x00f0000:″uClinux_kernel(832K)″mtd: Givingoutdevice1touClinux_kernel(832K)0x00f0000-0x00200000:″jffs2_usr(1088K)″mtd: Givingoutdevice2tojffs2_usr(1088K) init_mtdchar: allocatedmajornumber90.init_mtdblock: allocatedmajornumber31.……3.3创建文件系统镜像文件系统会编译生成JFFS2的辅助工具:mkfs.jffs2、eraseall、erase。