隨著32位CPU價(jià)格不斷下跌,片上存儲設(shè)備的容量相比越來越大,越來越多的嵌入式系統(tǒng)開始應(yīng)用各種嵌入式操作系統(tǒng)。一般在嵌入式領(lǐng)域,只要應(yīng)用到操作系統(tǒng)的必然會需要一個,甚至是多個文件系統(tǒng)。所謂文件系統(tǒng),實(shí)際上就是在一個具體的存儲設(shè)備上任何文件的組織和目錄。這個設(shè)備可能是各種RAM、NAND FLASH、NOR FLASH等DOC設(shè)備,還有以NAND FLASH 為基礎(chǔ)的各種存儲卡等[1]。
目前,針對不同的設(shè)備和應(yīng)用有很多文件系統(tǒng)可供選擇,例如EXT2、TEMPFS、RAMDISK、CRAMFS、JFFS1/2、YAFFS1/2、XFS等。除此之外,還有很多供應(yīng)商提供的商用文件系統(tǒng)。
選擇文件系統(tǒng),要根據(jù)具體應(yīng)用的需求。一般,首先要考慮的就是可靠性,健壯性和增強(qiáng)的需求。如果是像工控這樣的不需經(jīng)常更新控制程序的應(yīng)用來說,我們選擇CARAMFS這樣的只讀文件系統(tǒng)已經(jīng)足夠了,而且它還可以帶來的另外一個好處就是CRAMFS的壓縮率高達(dá)50%,可以大大節(jié)省我們的存儲空間。但是如果是像涉及到數(shù)據(jù)采集這類需要保存數(shù)據(jù)的應(yīng)用來說,只讀的文件系統(tǒng)就很難滿足應(yīng)用系統(tǒng)的需求,我們可以選擇JFFS或者YAFFS這樣的可讀寫的文件系統(tǒng)。不過在實(shí)際應(yīng)用中,需要考慮的因素還應(yīng)該更多。
2.文件系統(tǒng)的實(shí)現(xiàn)
2.1文件系統(tǒng)的選擇
在本文涉及的應(yīng)用中,根文件系統(tǒng)并不需要頻繁的更改,但是卻涉及到一些數(shù)據(jù)的存取??紤]到的存儲設(shè)備是NAND FLASH,所以在根文件系統(tǒng)格式的選擇上可以用壓縮率比較高的CRAMFS,而在根文件系統(tǒng)下掛載一個可讀寫的YAFFS2文件系統(tǒng)。
YAFFS2(Yet Another nandFlash FileSytem2)是專門針對NAND設(shè)備的一種文件系統(tǒng)。YAFFS2類似于JFFS/JFFS2文件系統(tǒng),與YAFFS2不同的是JFFSS1/2文件系統(tǒng)最初是針對NOR FLASH的應(yīng)用場合設(shè)計(jì)的。而YAFFS2針對NAND FLASH的特點(diǎn)采用增強(qiáng)的碎片回收和均衡磨損技術(shù),大大提高了讀寫速度,延長了存儲設(shè)備的使用壽命[2],可以更好的支持大容量的NAND FLASH芯片。而且在斷電可靠性上,YAFFS2的優(yōu)勢更加明顯[3]。
2.2建立根文件系統(tǒng)
Linux內(nèi)核啟動以后,根據(jù)參數(shù)linux_cmd_line的指示跳轉(zhuǎn)到根文件系統(tǒng)的地址,完成文件系統(tǒng)的初始化和掛載任務(wù)。根文件系統(tǒng)的建立可以借助各種開發(fā)套件來完成,也可以完全由自己搭建一個。這里介紹如何通過開發(fā)套件的幫助來完成基本的根文件系統(tǒng)。Busybox是由Bruce Perens發(fā)起的一項(xiàng)計(jì)劃,該計(jì)劃最初的目的是協(xié)助Debian發(fā)行套件建立安裝磁盤。由于Busybox小巧但功能不失強(qiáng)大,所以在嵌入式系統(tǒng)中有很廣的應(yīng)用。下載Busybox穩(wěn)定版(www.busybox.net),解壓后直接make menuconfig 進(jìn)入Busybox配置菜單,這個界面根內(nèi)核差不多。在Applets下面選擇你需要命令,然后退出保存, 執(zhí)行make , make install。在Busybox的目錄下就會生成_install目錄,這個目錄就包含了將要配置的命令的工具包。把這個目錄拷貝到工作目錄,更名為rootfs, 這個目錄就是要建立的根文件系統(tǒng)的雛形——但是它還不能工作,需要進(jìn)一步的完善。
在rootfs/下,首先在/rootfs/dev下建立必須的設(shè)備文件。關(guān)于設(shè)備的建立,可以參考Filesystem Hierarchy Standard來確定需要的哪些設(shè)備文件(http://www.pathname.com/fhs/)。下一步就是完成/rootfs/etc這個目錄下的3個比較重要的文件inittab,fstab,init.d/rcS(或者是rc.d/rc.sysinit,這個由inittab決定)。下面給出可供參考的樣例:
Inittab文件
#System initialization .
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::restart:/sbin/init
::shutdown:/bin/umount –a –r
::shutdown:/sbin/swapoff –a
Fstab文件
none
/proc
proc
defaults
0
0
tmpfs
/temp
tmfs
defaults
0
0
fstab指定了設(shè)備的掛載點(diǎn)。要了解關(guān)于fstab文件的格式以及詳細(xì)信息,可以參考
http://www.tuxfiles.org/linuxhelp/fstab.html
Init.d/rcS文件
#!/bin/sh
Mount –o remount, rw /
/bin/mount –a
>/etc/mtab
Echo
“messages”
Hostname
“hostname”
在這個腳本中,還可以定義內(nèi)核的其他一些動作,這在后面掛載YAFFS2文件系統(tǒng)中顯得非常有用。
最后,加入需要的鏈接庫文件就可以了。通常這部分會比較麻煩,因?yàn)槟悴⒉恢滥愕膽?yīng)用具體需要哪些庫文件,可以通過兩種途徑解決這個問題:一是利用工具readelf來找出應(yīng)用程序依存哪些鏈接庫;二是參考linux相關(guān)計(jì)劃網(wǎng)站上的提供的文件系統(tǒng),來確定需要的鏈接庫文件[4]。
2.3制作YAFFS2文件系統(tǒng)
根文件系統(tǒng)做好后,可以通過NFS(http://nfs.sourceforge.net/nfs-howto/)來測試文件系統(tǒng)是否可行,但是最后我們還是要把這個文件系統(tǒng)燒進(jìn)目標(biāo)板。
可以有兩種方式來應(yīng)用YAFFS2文件系統(tǒng),一是CRAMFS+YAFFS2的組合,一種是純YAFFS2文件系統(tǒng)格式。由于在筆者的應(yīng)用中,內(nèi)核和根文件系統(tǒng)并不需要頻繁更新,所以從節(jié)省存儲空間和保護(hù)根文件系統(tǒng)的角度來考慮,我們選用CRAMFS這樣的高壓縮率、只讀文件系統(tǒng),而應(yīng)用程序,用戶空間使用YAFFS2文件系統(tǒng)格式。
對于CRAMFS,可以直接用mkcramfs
/rootfs
~/root.img來制作cramfs鏡像,/rootfs是前面建立的根文件系統(tǒng)目錄,~/root.img指定做好鏡像的保存目錄。由于YAFFS2文件系統(tǒng)當(dāng)初設(shè)計(jì)就是針對nand設(shè)備的,在筆者的應(yīng)用中,文件系統(tǒng)是在NANDFLASH中啟動,因此要使用YAFFS2文件系統(tǒng),就必須先在內(nèi)核添加NAND設(shè)備驅(qū)動[5],并修改archarmmach-s3c2410devs.c文件,增加nand flash分區(qū)。一般情況下bootloader, kernel, root 三個分區(qū)是必須的,也有的加了param分區(qū)來保存內(nèi)核參數(shù),user分區(qū)來作為用戶空間的,但是也可以不要。
在www.aleph.co.uk下載YAFFS2(GPL)源碼,解壓后在YAFFS2目錄下執(zhí)行
patch-ker.sh
~/Linux2.6.14.2
~/Linux2.6.14.2是內(nèi)核的路徑,筆者的內(nèi)核是2.6.14.2。patch后在內(nèi)核的fs目錄下就會生成yaffs2目錄,這樣內(nèi)核就已經(jīng)得到YAFFS2的支持了。
接下來make menuconfig ,配置內(nèi)核時在
Device Drivers->
Memory Technology Device (MTD)->
下選中MTD Partitioning Surpport,這樣我們的分區(qū)信息才有效。在
File System->
Miscellaneous filesystems->下配置YAFFS2如下:
<>EFS file system support(read only) (EXPERIMENTAL)
<*>YAFFS2 file system support
— 512 byte / page devices
Lets Yaffs do its own ECC
Use the same ecc byte order as Steven Hill’s nand_ecc.c
— 2048 byte (or larger) / page devices
Autoselect yaffs2 format
Disable lazy loading
Turn off wide tnodes
Turn off debug chunk erase check
Cache short names in RAM
<>Jounalling Flash File System (JFFS) support
保存配置,退出,執(zhí)行make。Make結(jié)束后就得到了一個具備掛載yaffs2文件系統(tǒng)能力的內(nèi)核鏡像。
在bootloader源文件中,將nand flash分成幾個分區(qū),前面提到的devs.c文件里的分區(qū)也必須與bootloader的分區(qū)一致,因?yàn)?/font>bootloader指定了內(nèi)核和文件系統(tǒng)的地址,最后啟動時也會到相應(yīng)的地址尋找指令。在我們的應(yīng)用中,將flash分成bootloader, param, kernel, root, user。其中root用來掛載CRAMFS根文件系統(tǒng),user分區(qū)掛載YAFFS2文件系統(tǒng)。
在YAFFS2源文件的utils目錄下,執(zhí)行make就可以生成 mkyaffs2image工具,執(zhí)行
./mkyaffs2image (要制作yaffs2的目錄) (目標(biāo)鏡像)
生成yaffs2文件系統(tǒng),不過因?yàn)榍懊娓募到y(tǒng)是CRAMFS格式,YAFFS2可以作為模塊來加載,這樣更加方便,更加靈活。加載模塊也可以在后面給出的腳本中定義。
最后一步就是要讓內(nèi)核在啟動后掛載文件系統(tǒng),掛載文件系統(tǒng)有兩種方式:手動和自動掛載。在實(shí)際應(yīng)用中當(dāng)然是要系統(tǒng)在無需人工干預(yù)的情況下自動掛載文件系統(tǒng)。在Debian系統(tǒng)中,初始化腳本是/etc/init.d/rcS,在Rad Hat中是/etc/rc.d/rc.sysinit。這里面包含了裝入文件系統(tǒng),設(shè)置時間,打開交換分區(qū),得到主機(jī)名等等內(nèi)容?;仡櫱懊娼o出的Inittab和init.d/rcS文件就知道,系統(tǒng)的Init進(jìn)程是如何動作的。對照前面的rcS文件這里給出一個更加詳細(xì)的并給出注釋。
#! /bin/sh
//busybox提供的SHELL
PATH=/sbin:/bin:/usr/sbin:/usr/bin
//設(shè)置系統(tǒng)路徑
runlevel=S
//運(yùn)行級別
prevlevel=N
umask 022
//缺省訪問權(quán)限為022
export PATH runlevel prevlevel
/bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 /
//cramfs作為根文件系統(tǒng)掛到第四個分區(qū)下,即root分區(qū)。
/sbin/insmod -f /lib/yaffs2.ko
//加載 yaffs2模塊
/sbin/mount -t yaffs2 /dev/mtdblock/4 /usr
//yaffs2掛到第五個分區(qū),作為/usr
/sbin/mount -t proc none /proc
//mount命令由busybox提供
/sbin/mount -t tmpfs none /root
//掛載tmpfs到指定目錄,下同
/sbin/mount -t tmpfs none /tmp
/sbin/mount -t tmpfs none /var
/sbin/mkdir -p /var/lib
//創(chuàng)建目錄
/sbin/mkdir -p /var/run
/sbin/mkdir -p /var/log
/etc/rc.d/init.d/leds start
//初試用戶程序leds
/sbin/ifconfig lo 127.0.0.1
//指定lo設(shè)備的IP地址為127.0.0.1
#/sbin/ifconfig eth0 192.168.0.2
/sbin/hostname -F /etc/sysconfig/HOSTNAME
//指定主機(jī)名文件路徑.
將文件系統(tǒng)燒進(jìn)目標(biāo)板對應(yīng)分區(qū),boot,即可運(yùn)行。至此,目標(biāo)板可以通過/usr進(jìn)行讀寫文件,目標(biāo)板完成對yaffs2的支持。
3.結(jié)束語
YAFFS2可靠的掉電保護(hù)和高效率的讀寫以及對nand存儲設(shè)備的保護(hù)等優(yōu)勢使得它在越來越多的嵌入式系統(tǒng)中取得應(yīng)用。在本文的應(yīng)用中,YAFFS2在Linux下表現(xiàn)了良好的性能