下面是幾中比較常用的文件系統:
1.jffs2:JFFS嵌入式系統文件系統最早是由瑞典 Axis Communications公司基於Linux2.0的內核爲嵌入式系統開發的文件系統。基於JFFS開發的閃存文件系統,最初是針對RedHat公司的嵌入式產品eCos開發的嵌入式文件系統,所以JFFS2也可以用在Linux, uCLinux中。Jffs2: 日誌閃存嵌入式系統文件系統版本2 (Journalling Flash FileSystem v2),主要用於NOR型閃存,基於MTD驅動層,特點是:可讀寫的、支持數據壓縮的、基於哈希表的日誌型文件系統,並提供了崩潰/掉電安全保護,提供“寫平衡”支持等。缺點主要是當文件系統已滿或接近滿時,因爲垃圾收集的關係而使jffs2的運行速度大大放慢。目前jffs3正在開發中。關於jffs系列文件系統的使用詳細文檔,可參考MTD補丁包中mtd-jffs-HOWTO.txt。jffsx不適合用於NAND閃存主要是因爲NAND閃存的容量一般較大,這樣導致jffs爲維護日誌節點所佔用的內存空間迅速增大,另外,jffsx文件系統在掛載時需要掃描整個FLASH的內容,以找出所有的日誌節點,建立文件結構,對於大容量的NAND閃存會耗費大量時間。
2. yaffs:Yet Another Flash File Systemyaffs/yaffs2是專爲嵌入式系統使用NAND型閃存而設計的一種日誌型文件系統。與jffs2相比,它減少了一些功能(例如不支持數據壓縮),所以速度更快,掛載時間很短,對內存的佔用較小。另外,它還是跨平臺的文件系統,除了Linux和eCos,還支持WinCE, pSOS和ThreadX等。yaffs/yaffs2自帶NAND芯片的驅動,並且爲嵌入式系統提供了直接訪問文件系統的API,用戶可以不使用Linux中的MTD與VFS,直接對文件系統操作。當然,yaffs也可與MTD驅動程序配合使用。 yaffs與 yaffs2的主要區別在於,前者僅支持小頁(512 Bytes) NAND閃存,後者則可支持大頁(2KB) NAND閃存。同時,yaffs2在內存空間佔用、垃圾回收速度、讀/寫速度等方面均有大幅提升。
3. Cramfs:Compressed ROM File SystemCramfs是Linux的創始人Linus Torvalds參與開發的一種只讀的壓縮文件系統。它也基於MTD驅動程序。在cramfs文件系統中,每一頁(4KB)被單獨壓縮,可以隨機頁訪問,其壓縮比高達2:1,爲嵌入式系統節省大量的Flash存儲空間,使系統可通過更低容量的FLASH存儲相同的文件,從而降低系統成本。Cramfs文件系統以壓縮方式存儲,在運行時解壓縮,所以不支持應用程序以XIP方式運行,所有的應用程序要求被拷到RAM裏去運行,但這並不代表比 Ramfs需求的RAM空間要大一點,因爲Cramfs是採用分頁壓縮的方式存放檔案,在讀取檔案時,不會一下子就耗用過多的內存空間,只針對目前實際讀取的部分分配內存,尚沒有讀取的部分不分配內存空間,當我們讀取的檔案不在內存時,Cramfs文件系統自動計算壓縮後的資料所存的位置,再即時解壓縮到RAM中。另外,它的速度快,效率高,其只讀的特點有利於保護文件系統免受破壞,提高了系統的可靠性。由於以上特性,Cramfs在嵌入式系統中應用廣泛。但是它的只讀屬性同時又是它的一大缺陷,使得用戶無法對其內容對進擴充。Cramfs映像通常是放在Flash中,但是也能放在別的文件系統裏,使用 loopback 設備可以把它安裝別的文件系統裏。
4. 網絡文件系統NFS (Network File System)NFS是由Sun開發並發展起來的一項在不同機器、不同操作系統之間通過網絡共享文件的技術。在嵌入式Linux系統的開發調試階段,可以利用該技術在主機上建立基於NFS 的根文件系統,掛載到嵌入式設備,可以很方便地修改根文件系統的內容。以上討論的都是基於存儲設備的文件系統(memory-based file system),它們都可用作Linux的根文件系統。實際上,Linux還支持邏輯的或僞文件系統(logical or pseudo file system),例如procfs(proc文件系統),用於獲取系統信息,以及devfs(設備文件系統)和sysfs,用於維護設備文件。
5.ramdisk:適用於系統閃存比較小,但RAM先對充足
下面講解各種文件系統的製作:
1.根文件系統製作
1) 下載busybox源碼http://www.busybox.net/downloads/ 我使用的是busybox-1.17.3
2) 解壓源碼 root@zjh:/home/work# tar -jxvf busybox-1.17.3.tar.bz2
3) 進入源碼並配置源碼
root@zjh:/home/work# cd busybox-1.17.3
root@zjh:/home/work/busybox-1.17.3# make menuconfig
Busybox Settings --->
Build Options --->
[ ] Build BusyBox as a static binary (no shared libs) 編譯成動態庫
(arm-none-linux-gnueabi-) Cross Compiler prefix 根據自己的環境制定交叉編譯前綴
Installation Options --->
(../rootfs) BusyBox installation prefix 根據自己的環境制定安裝路徑
保存並退出
4) 編譯並安裝
root@zjh:/home/work/busybox-1.17.3# make
root@zjh:/home/work/busybox-1.17.3# make install 這時會安裝到我們剛纔指定的路徑
5) 拷貝busybox自帶的etc目錄到剛纔指定的安裝目錄
root@zjh:/home/work/busybox-1.17.3# cp -a examples/bootfloppy/etc/ ../rootfs
6) 進入rootfs目錄並創建相關目錄
root@zjh:/home/work/busybox-1.17.3# cd ../rootfs
root@zjh:/home/work/rootfs# ls
bin etc linuxrc sbin usr
root@zjh:/home/work/rootfs# mkdir -p dev mnt proc var tmp sys root lib usr/lib
7) 添加最基本的庫
root@zjh:/home/work/rootfs# arm-none-linux-gnueabi-readelf -d bin/busybox | grep Shared
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libc.so.6]
readelf -d可查看elf 文件依賴的庫
還需要一個庫:加載器(ld-linux.so.3)
注意:上面所列出的庫名都是鏈接文件
首先查看一下上面的鏈接文件鏈接到哪個庫
進入庫所在路徑(根據自己的實際環境)
root@zjh:/home/work/rootfs# cd /usr/local/arm-none-linux-gnueabi-4.5.1/arm-none-linux-gnueabi/libc/lib/
root@zjh:/usr/local/arm-none-linux-gnueabi-4.5.1/arm-none-linux-gnueabi/libc/lib# ll libc.so.6 libm.so.6 ld-linux.so.3
lrwxrwxrwx 1 root root 12 2012-09-24 10:20 ld-linux.so.3 -> ld-2.11.1.so*
lrwxrwxrwx 1 root root 14 2012-09-24 10:20 libc.so.6 -> libc-2.11.1.so*
lrwxrwxrwx 1 root root 14 2012-09-24 10:20 libm.so.6 -> libm-2.11.1.so*
下面開始拷貝
root@zjh:/usr/local/arm-none-linux-gnueabi-4.5.1/arm-none-linux-gnueabi/libc/lib# cp -a libc.so.6 libc-2.11.1.so libm.so.6 libm-2.11.1.so ld-linux.so.3 ld-2.11.1.so /home/work/rootfs/lib/
對庫進行瘦身以減小文件系統的大小
root@zjh:/home/work/rootfs# arm-none-linux-gnueabi-strip lib/*
8) 配置inittab文件
root@zjh:/home/work/rootfs# vi etc/inittab
#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
# Start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# Stuff to do when restarting the init process
::restart:/sbin/init
# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
9) 配置fstab文件
root@zjh:/home/work/rootfs# vi etc/fstab
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
這裏我們掛載的文件系統有3個proc、sysfs和tmpfs。在內核中proc和sysfs默認都支持,而tmpfs是沒有支持的,我們需要添加tmpfs的支持
File systems --->
Pseudo filesystems --->
[*] Tmpfs POSIX Access Control Lists
重新編譯內核
10) 配置rcS文件
root@zjh:/home/work/rootfs# vi etc/init.d/rcS
#!/bin/sh
#This is the first script called by init process
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
ifconfig lo 127.0.0.1
ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
route add default gw 192.168.1.1
#根據自己的實際情況設置ip
11) 配置profile文件
root@zjh:/home/work/rootfs# vi etc/profile
#!/bin/sh
export HOSTNAME=tq2440
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
echo "Processing /etc/profile... "
echo "Done"
12) 創建設備文件
root@zjh:/home/work/rootfs# mknod dev/console c 5 1
root@zjh:/home/work/rootfs# mknod dev/null c 1 3
2.NFS測試
重新設置u-boot啓動參數
# setenv bootargs root=/dev/nfs nfsroot=192.168.1.8:/home/work/rootfs init=/linuxrc ip=192.168.1.100 console=ttySAC0,115200
注意:192.168.1.8爲虛擬機IP,/home/workspace/rootfs爲根文件系統目錄,192.168.1.100爲指定開發板IP,這兩個IP和etc/init.d/rcS文件中指定的IP這3個IP必須在同一個網段
將內核燒入內存
# tftp 30008000 uImage
# bootm 30008000
3.製作ramdisk文件系統
1) 製作一個大小爲8M的虛擬磁盤
root@zjh:/home/workspace# dd if=/dev/zero of=initrd.img bs=1k count=8192
2) 格式化這個虛擬磁盤爲ext2
root@zjh:/home/workspace# mkfs.ext2 -F initrd.img
3) 創建一個目錄initrd作爲掛載點,並將這個虛擬磁盤掛載到initrd目錄下
root@zjh:/home/workspace# mkdir initrd
root@zjh:/home/workspace# mount -t ext2 -o loop initrd.img initrd
注意:一定要加-o loop選項
4) 將我們的文件系統寫入initrd.img並卸載initrd
root@zjh:/home/workspace# cp -a rootfs/* initrd
root@zjh:/home/workspace# umount initrd
5) 壓縮initrd.img爲initrd.img.gz
root@zjh:/home/workspace# gzip --best -c initrd.img > initrd.img.gz
6) 配置內核支持RAMDISK
General setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
Device Drivers --->
SCSI device support --->
<*> SCSI disk support
[*] Block devices --->
<*> RAM block device support
(1) Default number of RAM disks
(8192) Default RAM disk size (kbytes)
7) 重新設置u-boot啓動參數
# setenv bootargs root=/dev/ram init=/linuxrc initrd=0x30800000,8M console=ttySAC0,115200
8) 將內核燒入內存
# tftp 30008000 uImage
9) 將initrd.img.gz燒入內存
# tftp 30800000 initrd.img.gz
# bootm 30008000
4.製作cramfs文件系統
1) 系統提供的cramfs文件系統工具可以直接使用
root@zjh:/home/work# mkfs.cramfs rootfs rootfs.cramfs
2) 將rootfs.cramfs拷貝到/tftpboot目錄下
root@zjh:/home/work# cp rootfs.cramfs /tftpboot/
3) 將rootfs.cramfs固化到NAND FLASH第3個分區(/dev/mtdblock2)(根據自己內核的分區情況)
u-boot下執行
# tftp 32000000 rootfs.cramfs
# nand erase 400000 400000
# nand write 32000000 400000 400000
4) 重新設置u-boot啓動參數
# set bootargs root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200
# save
5) 下載內核到內存
# tftp 30008000 uImage
# bootm 30008000
注:cramfs文件系統是隻讀的
5.製作jffs2文件系統
1) zlib的編譯 http://www.zlib.net/
解壓zlib-1.2.3.tar.bz2並進入zlib-1.2.3目錄配置編譯安裝
root@zjh:/home/work# tar -jxvf zlib-1.2.3.tar.bz2
root@zjh:/home/work# cd zlib-1.2.3
root@zjh:/home/work/zlib-1.2.3# ./configure
root@zjh:/home/work/zlib-1.2.3# make
root@zjh:/home/work/zlib-1.2.3# make install
2) mtd工具的編譯 http://115.com/file/dpgxqn5g
解壓mtd-snapshot-20050519.tar.bz2並進入mtd/util編譯安裝
root@zjh:/home/work# tar -jxvf mtd-snapshot-20050519.tar.bz2
root@zjh:/home/work# cd mtd/util/
root@zjh:/home/work/mtd/util# make
root@zjh:/home/work/mtd/util# make install
這樣我們的系統裏就有了mkfs.jffs2這個工具了
3) jffs2文件系統鏡像的製作
root@zjh:/home/work# mkfs.jffs2 -d rootfs -o rootfs.jffs2 -s 2048 -e 0x20000 -n
-d:指定根文件系統目錄
-o:指定輸出文件
-s:指定頁大小2K(根據NAND FLASH芯片手冊)
-e:指定塊擦除大小128K (根據NAND FLASH芯片手冊)
-n:指定不要在每個擦除塊上添加清除標記
4) jffs2文件系統鏡像的燒寫
root@zjh:/home/work# cp rootfs.jffs2 /tftpboot/
啓動u-boot
# tftp 32000000 rootfs.jffs2
# nand erase 400000 400000
# nand write.jffs2 32000000 400000 $(filesize)
5) 重新設置u-boot啓動參數
# set root=/dev/mtdblock2 init=/linuxrc rootfstype=jffs2 console=ttySAC0,115200
6) 燒寫內核
# tftp 30008000 uImage
# bootm 30008000
6.製作yaffs2文件系統
1) 下載源碼http://www.aleph1.co.uk/gitweb?p=yaffs2.git;a=summary ,點擊 snapshot ,並解壓
root@zjh:/home/work# tar -zxvf yaffs2-9ee5d06.tar.gz
2) 進入yaffs源碼目錄併爲內核打補丁
root@zjh:/home/work/yaffs2-9ee5d06# ./patch-ker.sh c m ../linux-2.6.36.4
Updating ../linux-2.6.36.4/fs/Kconfig
Updating ../linux-2.6.36.4/fs/Makefile
3) 配置內核支持yaffs2文件系統
File systems --->
[*] Miscellaneous filesystems --->
<*> yaffs2 file system support
-*- 2048 byte (or larger) / page devices
[*] Autoselect yaffs2 format (NEW)
4) 重新編譯內核
5) 要製作yaffs2文件系統鏡像需要使用mkyaffs2image工具,該工具由yaffs源碼utils目錄下的mkyaffs2image.c編譯得到,如果是大頁nand需要修改該文件。我們使用的是大頁nand
進入utils目錄,修改mkyaffs2image.c第46行
#define pagesPerBlock 128
6) 執行make編譯,出錯,修改yportenv.h第22行
//#ifdef CONFIG_YAFFS_DEFINES_TYPES
#if 1
再執行make通過,將生成的可執行文件mkyaffs2image 拷貝到/usr/bin目錄
7) 製作yaffs2文件系統鏡像
root@zjh:/home/work# mkyaffs2image rootfs rootfs.yaffs2
8) 燒寫內核和yaffs2文件系統鏡像到nand flash
# tftp 32000000 rootfs.yaffs2
# nand erase 400000 400000
#nand write.yaffs 32000000 400000 $(filesize)
設置u-boot啓動參數
# set root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200
# save
# tftp 30008000 uImage
# bootm 30008000