嵌入式Linux上JFFS文件系统的实现方法

1 引言
近年来,随着电子技术的不断进步,嵌入式系统开发已成为热点,而linux作为一个自由软件 ,也得到了极大的发展 ,嵌入式系统与linux的结合,正日益被人们看好。linux具有内核小,效率高,源代码开放等优点,还内含了完整的tcp/在嵌入式系统开发中,flash 芯片以相对低廉的价格提供了高可靠性和高密度的存储,已成为嵌入式系统的重要组成部分。在很多嵌入式系统中,操作系统及应用程序直接固化在flash上,系统启动时,代码直接在flash上开始运行。
2 在嵌入式系统中使用flash
当前的嵌入式系统开发,需要方便灵活地使用flash,以嵌入式的web server为例,在运行过程中,要求能够动态地保存一些数据,并且当系统重新上电时,保存的数据依然存在。又比如将嵌入式处理器应用于工控领域,可能整个系统都集成在一小块电路板上,一些重要的工艺参数在控制过程中需要动态地改变并保存,而使用硬盘等存储介质又不太现实,在这种场合下,仅仅将flash作为保存系统代码的rom使用是“大材小用”了。需要充分发挥flash可擦写的优势,在系统运行过程中,动态地擦写flash来保存数据。针对嵌入式系统多样、灵活、专用性强等特点,可以发挥嵌入式操作系统软件复用的优点,找到一种方便、快捷地使用flash 的方法来缩短开发时间,提升系统性能,嵌入式linux就提供了这样一条捷径。由遍布全世界的自由软件开发者为linux提供支持,使得在嵌入式linux上使用flash变的十分容易。
3 jffs 文件系统简介
我们使用的uclinux系统采用romfs作为根文件系统,它相对于一般的ext2文件系统,具有节约空间的优势。但是romfs是一种只读的文件系统,不支持动态擦写保存,对于系统需要动态保存的数据只能采用虚拟ram盘的方法(ram盘使用ext2文件系统)。
针对romfs文件系统存在的问题,我们可以使用jffs文件系统(journaling flash file system)。jffs文件系统是瑞典的axis communications公司(www.axis.com) 在gnu general public license下发布的自由软件,主要用于嵌入式linux。只需要在自己的嵌入式linux中加入jffs文件系统并做少量的改动,就可以使用jffs文件系统。通过jffs文件系统,可以用flash来保存数据,即将flash作为系统的硬盘来使用。可以像操作硬盘上的文件一样操作flash芯片上的文件和数据。系统运行的参数可以实时保存到flash芯片中,在系统断电后数据仍然存储在flash芯片中。
作为一种eeprom,flash可分为两种主要类型:nor flash 和nand flash。一片没有使用过的flash,每一位的值都是逻辑1,对flash的写操作就是将特定位的逻辑1改变为逻辑0。而擦除就是将逻辑1改变为逻辑0。flash的数据存储是以块(block)为单位来组织的,flash只能整块擦除,而flash的寿命是以擦除次数来计算的,一般是每块100,000次。为了保证某块不早于其他块到达其寿命,就有必要在所有块中尽可能地平均分配擦除次数,这就是“损耗平衡”。jffs 文件系统是一种“追加式”的文件系统,新的数据总是被追加到上次写入数据的后面。这种“追加式”的结构就自然实现了“损耗平衡”。
要加入jffs文件系统,需实现linux下对flash芯片的驱动,axis communications公司提供了实现代码。在这个系统中,代码包括uclinux/linux/drivers/block/flash.c 和uclinux/linux/include/linux/flash.h。
在flash.c中的设备初始化函数 flash—init()里,将flash作为块设备向系统注册:
4 开发环境简介
这里采用的是宿主机+目标板的开发模式,宿主机为pc+redhat7.2 ,目标板为motorola coldfire5272+uclinux, uclinux版本为2.0.38,在宿主机上将uclinux和应用程序编译后,下载到目标板的flash中运行。我们使用的flash是2片amd am29lv160bt,大小为2m字节,工作在16bit双字节模式。对于motorola coldfire5272,其ram、flash、外设i/o 参与统一平坦编码,也没有地址变换。2片flash的地址范围设置为:0xffb00000-0xffcfffff 和0xffd00000-0xffefffff。每片flash共有35个扇区,除前四个扇区不规则,大小分别为:16k,8k,8k,32k 外,剩余31个扇区均为64k字节大小。?
5 实现jffs 文件系统的实例
为实现flash上的jffs文件系统,需要在内核中加入对jffs文件系统和flash设备的支持;针对具体的flash 芯片修改设备驱动程序;生成设备节点并将jffs文件系统挂接到flash 设备上。
5.1在内核中加入对jffs文件系统和flash 设备的支持
标准 linux可以模块的形式加载各种类型的设备驱动,要求在设备驱动中编制两个入口点:init—module() 和 cleanup—module() ; uclinux 2.0 内核不支持内核模块 lkm(loadable kernel modules),设备驱动及文件系统要静态地编译进内核。我们需要:?
完成上述修改并编译后,jffs文件系统和flash设备就被编译入内核,同时在系统引导时加入了对jffs 文件系统和 flash设备的初始化函数的调用。?
5.2针对具体设备修改flash设备驱动程序
axis communications在发布jffs的同时,也给出了flash 设备的驱动程序。此驱动程序支持amd,toshiba等公司的主流系列flash芯片,需要根据自己系统中具体flash芯片的型号及配置,修改驱动程序,使flash设备能够在嵌入式系统中正常工作。如果读者使用的是此驱动尚未支持的flash芯片,只需仿照其他型号,将flash型号加入此驱动程序即可。
下面,以系统中的flash为例,给出uclinux/linux/drivers/block/flash.c中需要的修改:
(1) 在文件的开头处,加入#define config—blk—dev—flash。
(2) 在flash—probe(),chips〔0〕.start = (unsigned char *)(0xf0200000),这个值取决于系统中实现jffs的flash芯片的起始地址,在第2片flash上实现jffs ,其起始地址为0xffd00000,所以将其改为 chips〔0〕.start = (unsigned char *)(0xffd00000),随后,需要根据芯片型号设置4个起始扇区的大小,系统中flash的型号是am29lv160bt。以下代码定义了起始4个扇区的大小:chip→bootsectorsize〔0〕= 0x8000; chip→bootsectorsize〔3〕 = 0x2000; chip→bootsectorsize〔0〕= 0x2000; chip→bootsectorsize〔3〕 = 0x4000。
我们使用的flash起始4个扇区的大小前文已经给出,所以需要将这4个值依次改为0x4000,0x2000,0x2000,0x8000即可。
(3) 在uclinux/linux/drivers/block/ll-rw-blk.c中的blk—dev—init()函数中,在flash—init()前加入flash—probe()调用执行对flash的检测。
5.3 将jffs文件系统挂接到flash设备上
首先在宿主机的uclinux/romfs/dev目录下新增设备节点:mknod flash0 b 60 16;mknod flash1 b 60 17;mknod flash2 b 60 18。
在flash芯片上建立起分区。这样,当重新编译内核并将内核下载到flash中后,就可以在目标板的/dev目录下新增flash设备文件供我们使用,目标板的uclinux系统启动之后,在目标板上执行mount-t jffs /dev/flash1/mnt,就在flash1分区上建立起了jffs 文件系统,jffs文件系统挂接在目标板 /mnt目录下,可在此挂接目录上执行建立、删除目录,文件等操作。
6结束语
开发的实例表明,开放源代码的linux在嵌入式系统开发中有极大的优势,借助于linux的开放性,我们能够灵活快捷地开发嵌入式系统应用。

深度解析阿维塔的电池系统
工业机器人如何推动食品行业的发展
用于肌肉-血管活动的原位双模监测的透明离子电子电极
智能物联新技术赋能新时代
苹果未来十年有望彻底改造12个市场 搜索或领先谷歌
嵌入式Linux上JFFS文件系统的实现方法
AYANEO成为全球首款采用7nm处理器的Windows掌机
超声波传感器与红外传感器哪个更好
Avago新推三款高速光耦合器
组合开关的选型及型号含义
当前人工智能的商业模式挑战
音响制作技术规范
DC/DC转换器的基板布局-输入电容器和二极管的配置
美国国家半导体推出SIMPLE SWITCHER 电源模块
一文了解IBM Spectrum LSF分布式工作负载管理平台
非洲猪瘟检测器用途有哪些?市场价多少
道氏技术再度加速其在锂电材料领域的布局
康耐视推出DataMan 503 扩展物流业条码读码器系列
变量液压马达电控比例控制放大器
什么是蓝牙堆栈 Simply Blue精简蓝牙系统的设计案例