JFFS2文件系统在μClinux中的实现
- 格式:doc
- 大小:80.50 KB
- 文档页数:10
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。
嵌入式linux下常见的文件系统RomFS:只读文件系统,可以放在ROM空间,也可以在系统的RAM中,嵌入式linux中常用来作根文件系统• RamFS:利用VFS自身结构而形成的存文件系统,使用系统的RAM空间• JFFS/JFFS2:为Flash设计的日志文件系统• Yaffs:专门为Nand Flash设计• proc:为核和核模块将信息发送给进程提供一种机制,可以查看系统模块装载的信息• devFS:设备文件系统Linux上的Ext2fs• 支持4 TB 存储、文件名称最长1012 字符• 可选择逻辑块• 快速符号• Ext2不适合flash设备• 是为象IDE 设备那样的块设备设计的,逻辑块大小必须是512 byte、1 KB、2KB等• 没有提供对基于扇区的擦除/写操作的良好管理• 如果在一个扇区中擦除单个字节,必须将整个扇区复制到RAM,然后擦除,再重写入• 在出现电源故障时,Ext2fs 是不能防止崩溃的• 文件系统不支持损耗平衡,缩短了flash的寿命jffs/jffs2文件系统的优缺点• 日志文件系统• 提供了更好的崩溃、掉电安全保护• jffs2支持对flash的均匀磨损• 在扇区级别上执行闪存擦除/写/读操作要比Ext2文件系统好• 文件系统接近满时,JFFS2 会大大放慢运行速度——垃圾收集Nand上yaffs文件系统的优势• 专门为Nand flash设计的日志文件系统• jffs/jffs2不适合大容量的Nand flash• jffs的日志通过jffs_node建立在RAM中,占用RAM空间:对于128MB的Nand大概需要4MB的空间来维护节点• 启动的时候需要扫描日志节点,不适合大容量的Nand flash• FAT系统没有日志编译yaffs文件系统• mtd的最新补丁升级?• 接口更新,适合与yaffs• 与原有的mtd驱动程序不兼容,需要重写• 如果使用旧mtd驱动需要定义Makefile中MTD_OLD = -DCONFIG_YAFFS_USE_OLD_MTD• 参考文档:yaffs-rootfs-howto• 最新版的yaffs:使用yaffs文件系统• 通过cat /proc/yaffs命令可以看到yaffs系统的相关信息• mount -t yaffs /dev/mtdblock/0 /mnt/yaffs关于Linux文件系统JFFS全称为:The Journalling Flash File System(日志闪存文件系统)最初由瑞典的Axis Communications 开发,Red Hat 的David Woodhouse 对它进行了改进。
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数据实体组成。
在嵌入式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'。
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下JFFS2文件系统的实现
黄布毅;郑安平;陈晓雷;刘国梅
【期刊名称】《单片机与嵌入式系统应用》
【年(卷),期】2004(000)005
【摘要】uClinux默认的根文件系统ROMFS是一个只读文件系统.不支持动态擦写保存。
虽然对于需要系统动态保存的数据可以采用虚拟RAM盘的方法,但系统掉电后RAM盘的内容全部丢失,不能永久保存数据。
而家庭网关需要动态保存少量的数据.例如.用户登陆时的信息、网络家电的注册信息等,所以有必要实现一个可读写的文件系统。
这里,JFFS2文件系统是一个很好的选择。
【总页数】3页(P69-70,76)
【作者】黄布毅;郑安平;陈晓雷;刘国梅
【作者单位】郑州轻工业学院;郑州轻工业学院;郑州轻工业学院;郑州轻工业学院【正文语种】中文
【中图分类】TP311.5
【相关文献】
1.JFFS2文件系统在uClinux上的实现 [J], 杜睿;潘琢金;王晓菊
2.uClinux下Nor Flash的JFFS2文件系统构建 [J], 贾东耀
3.uClinux下多文件系统的研究与实现 [J], 肖建;张宇
4.嵌入式Linux下JFFS2文件系统的实现 [J], 张勇;裘雪红
5.嵌入式LINUX下的JFFS2文件系统实现 [J], 范韶辉
因版权原因,仅展示原文概要,查看原文内容请购买。
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文件了。
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芯片以相对低廉的价格提供了高可靠性和高密度的存储,已成为嵌入式系统重要的存储设备。
在很多嵌入式系统中,操作系统及应用程序直接固化在FLASH上,系统启动时,代码可以直接在FLASH上开始运行。
但是仅将FLASH作为ROM使用是大材小用,需要充分发挥FLASH可擦写的优势,在系统运行过程中,动态擦写FLASH来保存数据。
然而,μClinux的文件系统可以有多种选择,ROMFS是使用得较多的文件系统。
它是一种简单、紧凑的文件系统,占用的空间小,但由于是只读的,使用起来有局限性。
若采用EXT2作为文件系统,虽然可以把信息保存在ramdisk盘中,但系统掉电后,ramdisk中的信息将丢失,这对于需要保存运行过程中参数的应用程序是不允许的。
建立在FLASH设备上的JFFS文件系统就是为解决这个问题而诞生的。
1 JFFS/MTD/JFFS2介绍日志闪存文件系统(The Journalling FLASH File System,JFFS)最初由瑞典的Axis Communications开发,Red Hat的David Woodhouse对它进行了改进。
通过JFFS文件系统,Linux 用户就可以将FLASH作为系统的硬盘来使用,可以像操作硬盘上的文件一样操作FLASH芯片上的文件和数据。
系统运行的参数可以实时保存到FLASH芯片中,在系统断电后数据仍然存储在FLASH芯片中。
但是在使用过程中,JFFS设计中的局限被不断地暴露出来。
2001年年初,Red Hat 决定实现一个新的JFFS2。
JFFS2在闪存上顺序地存储包含数据和原数据的meta-data的节点。
JFFS2的日志结构存储方式使得它能对闪存进行out-of-place更新,它提供的垃圾回收机制,只需要对擦写越界的块设置一个“脏”块标志。
当可用的块数不足时,垃圾回收机制才开始回收这些节点。
目前,市场上的FLASH芯片千差万别,而JFFS2文件系统并不考虑这些差异,它只是要求下面有一个抽象平台屏蔽底层硬件差异,提供统一访问接口。
这个抽象平台就是MTD层。
内存技术设备(Memory Technology Device,MTD)是用于访问Memory设备(ROM,FLASH)的μClinux的子系统。
它的主要目标是在系统硬件驱动程序的上层或用户模块之间提供通用接口。
硬件驱动程序不需要知道像JFFS和FTL那样的用户模块所使用的方法,它们真正需要提供的就是一组对底层闪存系统进行read,write和erase操作的简单例程,以及对MTD原始设备层的统一接口。
MTD支持的FLASH芯片主要有两种:HAND FLASH和NOR FLASH,它们的驱动程序有着很大的差异。
NOR和HAND是现在市场上两种主要的非易失闪存技术,其主要区别在于:(1) NOR的特点是芯片内执行(eXecute In Place,XIP),这样应用程序可以直接在FLASH闪存内运行,不必再把代码读到系统RAM中。
NOR的传输效率很高,在1~4 MB的小容量时具有很高的成本效益,但是较低的写入和擦除速度大大影响了它的性能。
而HAND结构能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快。
应用HAND的困难在于FLASH的管理和需要特殊的系统接口。
(2) 在对FLASH芯片中存储器单元块进行编程之前必须先执行擦除。
HAND器件执行擦除操作是十分简单的,而NOR则要求在进行擦除前先将目标块内所有的位都写为0。
(3) NOR FLASH带有SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节。
HAND器件使用复杂的I/O口来串行地存取数据,各个产品或厂商的方法可能各不相同。
8个引脚用来传送控制、地址和数据信息。
引入MTD和JFFS2概念后,FLASH设备驱动在Linux内核中的组织层次如图1所示。
从图1中可以看出,MTD设备分为四层(从设备节点直到底层硬件驱动),这四层从上到下依次是:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。
设备节点:通过mknod在根文件系统/dev子目录下建立MTD字符设备节点(主设备号为90)和MTD块设备节点(主设备号为31)。
这些节点为应用程序访问FLASH设备提供了通道,通过访问此设备节点即可访问MTD字符设备和块设备。
MTD设备层提供了两种不同访问MTD原始设备的方式,即字符设备、块设备。
MTD原始设备:为MTD的块设备(主设备号31)和字符设备(设备号90)提供一个统一的底层抽象。
FLASH硬件驱动层:负责具体FLASH芯片的读写,向内核注册FLASH设备上的分区等任务。
由于目前μClinux内核支持的ramdisk只能运行ROMFS,EXT2FS两种文件系统,所以JFFS2格式的FLASH分区必须通过mount命令挂载到根文件系统上才能使用。
2 在FLASH上建立JFFS2过程JFFS2文件系统在μC linux下有两种使用方式:一种是作为μClinux的根文件系统,另一种是作为一般文件系统,在系统启动时或启动以后挂载到系统上。
针对JFFS2文件系统所保存的数据比较少,这里选择后者。
具体的实现步骤有以下几个:添加与FLASH对应的map driver和FLASH驱动;修改设备节点;配置内核。
进行试验的s3c44b0使用的FLASH是intel 28f320b,大小为4 MB,类型为NOR FLASH,工作在16 b双字节模式。
使用的μClinux包为μClinux-dist-20040408.tar.gz。
设计NOR FLASH驱动程序时,只要让它能够被其上层MTD原始设备层正确地识别和操作,就能保证其正常工作。
现实NOR FLASH驱动核心是定义map_info 结构体,它指定了NOR FLASH的基址、位宽、大小等信息及FLASH的读写函数,见图2。
其中:name用来在内核中惟一标识这块芯片的字符串;width用来访问FLASH芯片的总线宽度;size是FLASH芯片的容量,在该芯片中用字进行读取。
其主要的函数原型为:void(*read) (struct map_info *,unsignde long);void(*write) (struct map_info *,const map_word,unsignde long);void(*copy_from) (struct map_info *,void *,unsignde long,ssize_t);void(*copy_to) (struct map_info *,unsignde long const void *,ssize_t);2.1 添加FLASH上的map文件和FLASH的驱动在μClinux-dist/linux-2.4.x/drivers/mtd/maps下添加自己的map文件。
map文件可以根据具体的FLASH和挂载方式选择合适的文件加以修改,本系统是选择m5272c3.c修改的,并命名为s3c44b0.c。
修改的关键点有:(1) 定义FLASH的基地址、容量和宽度#define WINDOW_ADDR 0x00000000#define WINDOW_SIZE 0x00400000#define BUSWIDTH 2(2) 根据系统要求建立FLASH设备中的分区static struct mtd_partition s3c44b0_partitions[ ] = { {name: "bootloader (64K)",size: 0x00010000,offset: 0x00000000},{name: "μClinux kernel (960K)",size: 0x00100000,offset: 0x00010000},{name: "ramdisk (1024K)"size: 0x00100000,offset: 0x00200000},{name: "jffs2 (1024K)"size: 0x00100000,offset: 0x00300000}};(3) FLASH芯片的内存映射s3c44b0x_map.map_priv_1=(unsigned long)ioremap(WINDOW_ ADDR,WINDOW_SIZE);// if( !s3c44b0x_m ap.m ap_priv_1){// printk(”Failed to ioremap\\n");// return -EIO;// }这里的ioremap()主要是将I/O端口映射到虚拟内存区域。