各種嵌入式根文件系統製作

下面是幾中比較常用的文件系統:

1.jffs2JFFS嵌入式系統文件系統最早是由瑞典 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. yaffsYet Another Flash File Systemyaffs/yaffs2是專爲嵌入式系統使用NAND型閃存而設計的一種日誌型文件系統。與jffs2相比,它減少了一些功能(例如不支持數據壓縮),所以速度更快,掛載時間很短,對內存的佔用較小。另外,它還是跨平臺的文件系統,除了LinuxeCos,還支持WinCE, pSOSThreadX等。yaffs/yaffs2自帶NAND芯片的驅動,並且爲嵌入式系統提供了直接訪問文件系統的API,用戶可以不使用Linux中的MTDVFS,直接對文件系統操作。當然,yaffs也可與MTD驅動程序配合使用。  yaffs與 yaffs2的主要區別在於,前者僅支持小頁(512 Bytes) NAND閃存,後者則可支持大頁(2KB) NAND閃存。同時,yaffs2在內存空間佔用、垃圾回收速度、讀/寫速度等方面均有大幅提升。 

3. CramfsCompressed ROM File SystemCramfsLinux的創始人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

這裏我們掛載的文件系統有3procsysfstmpfs。在內核中procsysfs默認都支持,而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,這兩個IPetc/init.d/rcS文件中指定的IP3IP必須在同一個網段

將內核燒入內存 

# 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.imginitrd.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 FLASH3個分區(/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.c46

 #define pagesPerBlock 128

6) 執行make編譯,出錯,修改yportenv.h22

 //#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 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章