各种嵌入式根文件系统制作

下面是几中比较常用的文件系统:

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

扫描二维码关注公众号,回复: 39198 查看本文章

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 

猜你喜欢

转载自blog.csdn.net/zjy900507/article/details/80014128