基于Linux的嵌入式文件系统构建与设计


摘 要:
Linux是当今一种十分流行的嵌入式操作系统。由于其具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,因此被广泛应用于工业控制领域。该文对其文件系统进行了简单的介绍,结合嵌入式系统应用中的实际情况,建立起一套简单的文件系统。
引言:
在便携电子设备中,随着系统复杂性的增加,存储容量的扩大,嵌入文件系统成为一种必然趋势。而Flash存储器由于具有存储容量大、掉电数据不丢 失、何种小以及可多次擦写等许多优点,正逐步取代其他半导体存储器件而广泛应用于便携电子产品中。在Flash存储器中使用文件系统,可将存储空间当作直 观的名称空间,不用在每次应用开发中都从头使用存储器,还可方便地利用标准接口同主系统通信。
一、文件系统:
文件系统(File system)指代贮存在计算机上的文件和目录。文件系统可以有不同的格式,叫做文件系统类型(file system types)。这些格式决定信息是如何被贮存为文件和目录。某些文件系统类型贮存重复数据,某些文件系统类型加快硬盘驱动器的存取速度。因此文件系统就是操作系统用于明确磁盘或分区上的文件的方法和数据结构;即在磁盘上组织文件的方法。也指用于存储文件的磁盘或分区,或文件系统种类。

上图是一个完整操作系统的文件系统构架,下文中将对文件系统中各个部件进行一定的介绍。
1.1 Linux系统文件类型:

● Linux系统中文件的类型包括:普通文件、目录文件、连接文件、设备文件、管道(FIFO)文件和套接字文件。
● 普通文件:是流式文件,
● 目录文件:用于表示表示和管理系统中的全部文件
● 连接文件:用于不同目录下文件的共享
● 设备文件:包括块设备文件和字符设备文件。块设备文件表示磁盘、关盘等,字符设备文件联系着按照字符进行操作的终端、键盘等设备。
● 管道(FIFO)文件:提供进程间通信的一种方式。
● 套接字(socket)文件和网络通信有关。

1.2 逻辑文件系统:

文件的逻辑结构是用户可见结构,即从用户角度观察到的文件系统。可以分为两大类:字节流式的无结构文件和记录式有结构文件。由字节流(字节序列)组成的文件是一种无结构文件或流式文件,不考虑文件内部的逻辑结构,只是简单地看作式一系列字节的序列,便于在文件任意位置添加内容。很多操作系统多采用这种形式,如UNIX/Linux、DOS、Windows等。由记录组成的文件称为记录式文件,记录是这种文件的基本信息单位,记录式文件通常用于信息管理。

1.3 虚拟文件系统:

Linux在传统的逻辑文件系统的基础上,增加了一个虚拟文件系统(Virtual File System,VFS)的接口层,VFS在最上层,管理各种逻辑文件系统,屏蔽了他们之间的差异,为用户命令、函数调用和内核其他部分提供访问文件和设备的统一接口,使得不同的逻辑文件系统按照同样的模式呈现在使用者面前,对于用户来讲,觉察不到逻辑文件系统的差异,可以使用同样的命令来操作不同的逻辑文件系统所管理的文件,可以在他们之间自由地复制文件。

二、文件系统:
嵌入式
系统与通用PC机不同,一般没有硬盘这样的
存储
设备而是使用Flash闪存芯片、小型闪存卡等专为嵌入式系统设计的存储装置。因此在
嵌入式
系统很少使用PC上常用的文件系统,取而代之是根据其特点定制的文件系统。

2.1 嵌入式系统存储设备及其管理机制分析:

构建适用于嵌入式系统的Linux文件系统,必然会涉及到两个关键点,一是文件系统类型的选择,它关系到文件系统的读写性能、尺寸大小;另一个就是根文件系统内容的选择,它关系到根文件系统所能提供的功能及尺寸大小。

嵌入式设备中使用的存储器是像Flash闪存芯片、小型闪存卡等专为嵌入式系统设计的存储装置。Flash是目前嵌入式系统中广泛采用的主流存储器,它的 主要特点是按整体/扇区擦除和按字节编程,具有低功耗、高密度、小体积等优点。目前,Flash分为NOR, NAND两种类型。

NOR型闪存可以直接读取芯片内储存的数据,因而速度比较快,但是价格较高。NOR型芯片,地址线与数据线分开,所以NOR型芯片可以像SRAM一样连在数据线上,对NOR芯片可以“字”为基本单位操作,因此传输效率很高,应用程序可以直接在Flash内运行,不必再把代码读到系统RAM中运行。它与SRAM的最大不同在于写操作需要经过擦除和写入两个过程。

NAND型闪存芯片共用地址线与数据线,内部数据以块为单位进行存储,直接将NAND芯片做启动芯片比较难。NAND闪存是连续存储介质,适合放大文件。 擦除NOR器件时是以64-128KB的块进行的,执行一个写入/擦除操作的时间为5s;擦除NAND器件是以8-32KB的块进行的,执行相同的操作最多只需要4ms。

NAND Rash的单元尺寸几乎是NOR器件的一半,由于生产过程更为简单,NAND结构可以在给定的模具尺寸内提供更高的容量,也就相应地降低了价格。NOR flash占据了容量为1―16MB闪存市场的大部分,而NAND flash只是用在8―128MB的产品当中,这也说明NOR主要应用在代码存储介质中,NAND适合于数据存储。

寿命(耐用性),在NAND闪存中每个块的最大擦写次数是一百万次,而NOR的擦写次数是十万次。NAND存储器除了具有10比1的块擦除周期优势,典型的NAND块尺寸要比NOR器件小8倍,每个NAND存储器块在给定的时间内的删除次数要少一些。

所有嵌入式系统的启动都至少需要使用某种形式的永久性存储设备,它们需要合适的驱动程序,当前在嵌入式Linux中有三种常用的块驱动程序可以选择。

Blkmem驱动层:

Blkmem驱动是为uclinux专门设计的,也是最早的一种块驱动程序之一,现在仍然有很多嵌入式Linux操作系统选用它作为块驱动程,尤其是在 uClinux中。它相对来说是最简单的,而且只支持建立在NOR型Flash和RAM中的根文件系统。使用Blkmem驱动,建立Flash分区配置比 较困难,这种驱动程序为Flash提供了一些基本擦除/写操作。

RAMdisk驱动层:

RAMdisk驱动层通常应用在标准Linux中无盘工作站的启动,对Flash存储器并不提供任何的直接支持, RAM disk就是在开机时,把一部分的内存虚拟成块设备,并且把之前所准备好的档案系统映像解压缩到该RAM disk环境中。当在Flash中放置一个压缩的文件系统,可以将文件系统解压到RAM,使用RAM disk驱动层支持一个保持在RAM中的文件系统。

MTD驱动层:

为了尽可能避免针对不同的技术使用不同的工具,以及为不同的的技术提供共同的能力,Linux内核纳入了MTD子系统(memory Technology Device)。它提供了一致且统一的接口,让底层的MTD芯片驱动程序无缝地与较高层接口组合在一起。
JFFS2, Cramfs, YAFFS等文件系统都可以被安装成MTD块设备。MTD驱动也可以为那些支持CFI接口的NOR型Flash提供支持。虽然MTD可以建立在RAM上, 但它是专为基于Flash的设备而设计的。MTD包含特定Flash芯片的驱动程序,开发者要选择适合自己系统的Flash芯片驱动。Flash芯片驱动 向上层提供读、写、擦除等基本的操作,MTD对这些操作进行封装后向用户层提供MTD char和MTD block类型的设备。

MTD char类型的设备包括/dev/mtd0, /dev/mtdl等,它们提供对Flash原始字符的访问。MTD block类型的设备包括/dev/mtdblock0,/dev/mtdblock1等,MTD block设备是将Flash模拟成块设备,这样可以在这些模拟的块设备上创建像Cramfs, JFFS2等格式的文件系统。

MTD驱动层也支持在一块Flash上建立多个Flash分区,每一个分区作为了一个MTD block设备,可以把系统软件和数据等分配到不同的分区上,同时可以在不同的分区采用不用的文件系统格式。这一点非常重要,正是由于这一点才为嵌入式系统多文件系统的建立提供了灵活性。
2.2 基于Flash的文件系统:

鉴于Flash存储介质的读写特点,传统的Linux文件系统己经不适合应用在嵌入式系统中,像Ext2fs文件系统是为像IDE那样的块设备设计的,这些设备的逻辑块是512字节、1024字节等大小,没有提供很好的扇区擦写支持,不支持损耗平衡,没有掉电保护,也没有特别完美的扇区管理,这不太适合于扇区大小因设备类型而划分的闪存设备。基于这样的原因,产生了很多专为Flash设备而设计的文件系统,常见的专用于闪存设备的文件系统如下:

2.2.1 Romfs

传统型的Romfs文件系统是最常使用的一种文件系统,它是一种简单的、紧凑的、只读的文件系统,不支持动态擦写保存;它按顺序存放所有的文件数据,所以这种文件系统格式支持应用程序以XIP方式运行,在系统运行时,可以获得可观的RAM节省空间。uClinux系统通常采用Romfs文件系统。

2.2.2 Cramfs

Cramfs是Linux的创始人Linus Torvalds开发的一种可压缩只读文件系统在Cramfs文件系统中,每一页被单独压缩,可以随机页访问,其压缩比高达2:1,为嵌入式系统节省大量 的Flash存储空间。Cramfs文件系统以压缩方式存储,在运行时解压缩,所以不支持应用程序以XIP方式运行,所有的应用程序要求被拷到RAM里去 运行,但这并不代表比Ramfs需求的RAM 空间要大一点,因为Cramfs是采用分页压缩的方式存放档案,在读取档案时,不会一下子就耗用过多的内存空间,只针对目前实际读取的部分分配内存,尚没有读取的部分不分配内存空间,当我们读取的档案不在内存时, Cramfs文件系统自动计算压缩后的资料所存的位置,再即时解压缩到RAM中。

另外,它的速度快,效率高,其只读的特点有利于保护文件系统免受破坏,提高了系统的可靠性;但是它的只读属性同时又是它的一大缺陷,使得用户无法对其内容 对进扩充。Cramfs映像通常是放在Flash中,但是也能放在别的文件系统里,使用loopback设备可以把它安装别的文件系统里。使用 mkcramfs工具可以创建Cramfs映像。

2.2.3 Ramfs/Tmpfs

Ramfs也是Linus Torvalds开发的,Ramfs文件系统把所有的文件都放在RAM里运行,通常是Flash系统用来存储一些临时性或经常要修改的数据,相对于 ramdisk来说,Ramfs的大小可以随着所含文件内容大小变化,不像ramdisk的大小是固定的。Tmpfs是基于内存的文件系统,因为 tmpfs驻留在RAM 中,所以写/读操作发生在RAM 中。tmpfs文件系统大小可随所含文件内容大小变化,使得能够最理想地使用内存;tmpfs驻留在RAM,所以读和写几乎都是瞬时的。tmpfs的一个缺点是当系统重新引导时会丢失所有数据。

2.2.4 JFFS2

JFFS2是RedHat公司基于JFFS开发的闪存文件系统,最初是针对RedHat公司的嵌入式产品eCos开发的嵌入式文件系统,所以JFFS2也 可以用在Linux,uCLinux中。JFFS文件系统最早是由瑞典Axis Communications公司基于Linux2.0的内核为嵌入式系统开发的文件系统。JFFS2是一个可读写的、压缩的、日志型文件系统,并提供了 崩溃/掉电安全保护,克服了JFFS的一些缺点:使用了基于哈希表的日志节点结构,大大加快了对节点的操作速度;支持数据压缩;提供了“写平衡”支持;支持多种节点类型;提高了对闪存的利用率,降低了内存的消耗。这些特点使JFFS2文件系统成为目前Flash设备上最流行的文件系统格式,它的缺点就是当文件系统已满或接近满时,JFFS2运行会变慢,这主要是因为碎片收集的问题。

2.2.5 YAFFS

YAFFS/YAFFS2是一种和JFFSx类似的闪存文件系统,它是专为嵌入式系统使用NAND型闪存而设计的一种日志型文件系统。和JFFS2相比它减少了一些功能,所以速度更快,而且对内存的占用比较小。此外,YAFFS自带NAND芯片的驱动,并且为嵌入式系统提供了直接访问文件系统的API,用户可以不使用Linux中的MTD与VFS,直接对文件系统操作。YAFFS2支持大页面的NAND设备,并且对大页面的NAND设备做了优化。JFFS2在NAND闪存上表现并不稳定,更适合于NOR闪存,所以相对大容量的NAND闪存,YAFFS是更好的选择。
在具体的嵌入式系统设计中可根据不同目录存放的内容不同以及存放的文件属性,确定使用何种文件系统。对于Romfs采用XIP技术显然过于复杂,YAFFS在资源有限的FLASH中没有优势,JFFS2在最近遇到的十几个case中都没有人提议使用,我也无法评论,可能在以后再补充关于JFFS2的内容。下面将介绍制做Ramfs,cramfs,squashfs三种文件系统的详细过程。


三、根文件目录:
根文件目录在嵌入式系统启动以后被挂载到/ 下。一个linux的最简根文件系统应该包括支持linux系统正常运行的基本内容,包括系统使用的软件和库,以及所有用来为用户提供基本支持的架构和指令。
在根文件目录rootfs下建立bin、dev、etc、lib、proc、sbin、root、tmp等一系列必备的目录,把所需的配置文件、动态函数库放到相应的目录。采用BusyBox是缩小根文件系统的好办法。BusyBox以很小的体积集成了最常用的linux命令和应用程序,大大简化了制作 linux根文件系统的过程。
3.1 建一个目录rootfs 用来装文件系统;

3.2 在该目录下mkdir bin dev etc lib proc sbin tmp usr var;

3.3 ln -fs bin/busybox linuxrc(使用busybox简化文件系统);

3.4 到系统 /dev 把所有的device打一个包,拷贝到 dev下面(最省事的做法);或者直接使用mknod来自己建所需要的device,我自己用的如下:

crwxrwxrwx 1 root root 5, 1 2007-10-08 10:12 console
crwxrwxrwx 1 root root 5, 64 2007-10-08 10:12 cua0
crwxrwxrwx 1 root root 63, 0 2007-10-08 10:12 dk0
crwxrwxrwx 1 root root 63, 1 2007-10-08 10:12 dk1
drwxrwxrwx 2 root root 4096 2007-10-08 10:12 flash
brwxrwxrwx 1 root root 3, 0 2007-10-08 10:12 hda
crwxrwxrwx 1 root root 36, 10 2007-10-08 10:12 ipsec
crwxrwxrwx 1 root root 241, 0 2007-10-08 10:12 ixNpe
crwxrwxrwx 1 root root 1, 2 2007-10-08 10:12 kmem
crwxrwxrwx 1 root root 126, 0 2007-10-08 10:12 ledman
lrwxrwxrwx 1 root root 16 2007-10-08 13:20 log -> /tmp/var/log/log
crwxrwxrwx 1 root root 1, 1 2007-10-08 10:12 mem
crwxrwxrwx 1 root root 90, 0 2007-10-08 10:12 mtd0
brwxrwxrwx 1 root root 31, 0 2007-10-08 10:12 mtdblock0
brwxrwxrwx 1 root root 31, 1 2007-10-08 10:12 mtdblock1
brwxrwxrwx 1 root root 31, 2 2007-10-08 10:12 mtdblock2
brwxrwxrwx 1 root root 31, 3 2007-10-08 10:12 mtdblock3
brwxrwxrwx 1 root root 31, 4 2007-10-08 10:12 mtdblock4
brwxrwxrwx 1 root root 31, 5 2007-10-08 10:12 mtdblock5
brwxrwxrwx 1 root root 31, 6 2007-10-08 10:12 mtdblock6
crwxrwxrwx 1 root root 90, 1 2007-10-08 10:12 mtdr0
crwxrwxrwx 1 root root 1, 3 2007-10-08 10:12 null
crwxrwxrwx 1 root root 108, 0 2007-10-08 10:12 ppp
crwxrwxrwx 1 root root 5, 2 2007-10-08 10:12 ptmx
drwxrwxrwx 2 root root 4096 2007-10-08 10:12 pts
crwxrwxrwx 1 root root 2, 0 2007-10-08 10:12 ptyp0
brwxrwxrwx 1 root root 1, 0 2007-10-08 10:12 ram0
crwxrwxrwx 1 root root 1, 8 2007-10-08 10:12 random
crwxrwxrwx 1 root root 5, 0 2007-10-08 10:12 tty
crwxrwxrwx 1 root root 4, 0 2007-10-08 10:12 tty0
crwxrwxrwx 1 root root 3, 0 2007-10-08 10:12 ttyp0
crwxrwxrwx 1 root root 4, 64 2007-10-08 10:12 ttyS0
crwxrwxrwx 1 root root 1, 9 2007-10-08 10:12 urandom
crwxrwxrwx 1 root root 1, 5 2007-10-08 10:12 zero

举例: mknod console c 5 1 这样 crw-rw-rw- 1 root root 5, 1 2007-10-08 13:12 console。

对2.6.x内核,要使系统启动后进入BusyBox控制台,在/rootfs/dev下添加控制台设备文件:“mknod -m 600 console c 5 1”是必须的。

3.5 将编译好的busybox拷贝到/bin下面,除了busybox外,所有其他的命令都是他的link;

lrwxrwxrwx 1 root root 7 2007-10-08 13:42 ash -> busybox
-rwxr-xr-x 1 root root 246052 2007-10-08 13:42 busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 cat -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 chmod -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 chown -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 cp -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 df -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 dmesg -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 echo -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 egrep -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 fgrep -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 grep -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 gzip -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 hostname -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 ip -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 kill -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 ln -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 ls -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 mkdir -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 mount -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 mv -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 netstat -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 ping -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 ping2file -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 ps -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 pwd -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 rm -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 sh -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 sleep -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 sysinfo -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 tar -> busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 uname -> busybox

3.6 同样/sbin下面也是busybox的link;

lrwxrwxrwx 1 root root 14 2007-10-08 13:42 ifconfig -> ../bin/busybox
lrwxrwxrwx 1 root root 14 2007-10-08 13:42 init -> ../bin/busybox
lrwxrwxrwx 1 root root 14 2007-10-08 13:42 insmod -> ../bin/busybox
lrwxrwxrwx 1 root root 7 2007-10-08 13:42 klogd -> syslogd
lrwxrwxrwx 1 root root 14 2007-10-08 13:42 losetup -> ../bin/busybox
lrwxrwxrwx 1 root root 14 2007-10-08 13:42 lsmod -> ../bin/busybox
lrwxrwxrwx 1 root root 14 2007-10-08 13:42 modprobe -> ../bin/busybox
lrwxrwxrwx 1 root root 14 2007-10-08 13:42 reboot -> ../bin/busybox
lrwxrwxrwx 1 root root 14 2007-10-08 13:42 rmmod -> ../bin/busybox
lrwxrwxrwx 1 root root 14 2007-10-08 13:42 route -> ../bin/busybox

3.7 同样/usr/bin下面也是busybox的link;

lrwxrwxrwx 1 root root 17 2007-10-08 13:42 [ -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 dirname -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 expr -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 free -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 id -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 killall -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 sort -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 test -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 tr -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 traceroute -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 tty -> ../../bin/busybox
lrwxrwxrwx 1 root root 17 2007-10-08 13:42 wc -> ../../bin/busybox

当然这样做是有一点点麻烦了,因此最简单的办法是在 “busybox/applets/install.sh”中改变“prefix=../../rootfs”。在busybox使用”make menuconfig”选择你想要的命令,不要忘记在build option中指定编译器。

3.8 在/usr/sbin下面放着所有编译完的可执行文件,具体就不多说了;.

3.9 非常重要之/lib,务必重视;

-rwxrwxrwx 1 root root 19640 2007-10-08 10:12 ld-uClibc-0.9.28.so
lrwxrwxrwx 1 root root 19 2007-10-08 13:20 ld-uClibc.so.0 -> ld-uClibc-0.9.28.so
-rwxrwxrwx 1 root root 10964 2007-10-08 10:12 libcrypt-0.9.28.so
lrwxrwxrwx 1 root root 18 2007-10-08 13:20 libcrypt.so.0 -> libcrypt-0.9.28.so
lrwxrwxrwx 1 root root 19 2007-10-08 13:20 libc.so.0 -> libuClibc-0.9.28.so
-rwxrwxrwx 1 root root 6972 2007-10-08 10:12 libdl-0.9.28.so
lrwxrwxrwx 1 root root 10 2007-10-08 13:20 libdl.so -> libdl.so.0
lrwxrwxrwx 1 root root 15 2007-10-08 13:20 libdl.so.0 -> libdl-0.9.28.so
lrwxrwxrwx 1 root root 13 2007-10-08 13:20 libgcc_s.so -> libgcc_s.so.1
-rwxrwxrwx 1 root root 28428 2007-10-08 10:12 libgcc_s.so.1
lrwxrwxrwx 1 root root 11 2007-10-08 13:20 libiw.so -> libiw.so.27
-rwxrwxrwx 1 root root 18808 2007-10-08 10:12 libiw.so.26
-rwxrwxrwx 1 root root 22860 2007-10-08 10:12 libiw.so.27
-rwxrwxrwx 1 root root 36300 2007-10-08 10:12 libixml.so
-rwxrwxrwx 1 root root 54656 2007-10-08 10:12 libm-0.9.28.so
-rwxr-xr-x 1 root root 76828 2007-10-08 13:42 libmatrixssl.so
lrwxrwxrwx 1 root root 9 2007-10-08 13:20 libm.so -> libm.so.0
lrwxrwxrwx 1 root root 14 2007-10-08 13:20 libm.so.0 -> libm-0.9.28.so
-rwxr-xr-x 1 root root 6592 2007-10-08 13:42 libnvram.so
-rwxrwxrwx 1 root root 87557 2007-10-08 10:12 libpthread-0.9.28.so
lrwxrwxrwx 1 root root 20 2007-10-08 13:20 libpthread.so.0 -> libpthread-0.9.28.so
-rwxrwxrwx 1 root root 1952 2007-10-08 10:12 libresolv-0.9.28.so
lrwxrwxrwx 1 root root 14 2007-10-08 13:20 libresolv.so -> libresolv.so.0
lrwxrwxrwx 1 root root 19 2007-10-08 13:20 libresolv.so.0 -> libresolv-0.9.28.so
-rwxrwxrwx 1 root root 16140 2007-10-08 10:12 libthreadutil.so
-rwxrwxrwx 1 root root 313620 2007-10-08 10:12 libuClibc-0.9.28.so
-rwxrwxrwx 1 root root 4468 2007-10-08 10:12 libutil-0.9.28.so
lrwxrwxrwx 1 root root 12 2007-10-08 13:20 libutil.so -> libutil.so.0
lrwxrwxrwx 1 root root 17 2007-10-08 13:20 libutil.so.0 -> libutil-0.9.28.so

找到你编译环境的target目录,把需要的lib文件先用strip压縮(非target目录下的,而是编译环境提供的strip),先把最基本的libc, ld等等,必须同样做跟target/lib里面一样的link。然后根据特定的应用加相应的lib,不要把不用的加进去,lib比较占空间。

3.10 在/etc下面加上需要的配置文件,最最重要的是rcS;
#!/bin/sh
export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin/scripts:/usr/sbin/ath

UTC=yes

mount -n -t proc proc /proc
mount -n -t ramfs ramfs /tmp (如果不是ramfs,必须加上这个形成一个可以读写的目录)

insmod /lib/gpio.o
insmod /lib/ixp400.o
insmod /lib/ixp400_eth.o

# build var directories
/bin/mkdir -m 0777 /tmp/var
/bin/mkdir -m 0777 /var/lock
/bin/mkdir -m 0777 /var/log
/bin/mkdir -m 0777 /var/run
/bin/mkdir -m 0777 /var/tmp

# start ethnet
ifconfig eth1 up
/usr/sbin/brctl addbr br0
ifconfig br0 up
/usr/sbin/brctl addif br0 eth1
/usr/sbin/brctl setfd br0 0.1
ifconfig br0 mtu 1490

ifconfig lo 127.0.0.1
route add -net 127.0.0.0 netmask 255.255.0.0 lo > /dev/null 2>&1

下面的具体应用没有再举例加上了,这个是系统init必须的。

四、生成ramfs文件:
#!/bin/sh

MODULE_NAME=ramdisk
RAMPATH=`pwd`
TMPPATH=${RAMPATH}/tmp
SOURCE=${RAMPATH}/../target

if [ ! -d ${TMPPATH} ]
then
mkdir ${TMPPATH}
fi

if [ `whoami` != 'root' ]
then {
echo "You should run the shell as root, Please rerun as a root."
echo "Aborting."
exit 1
}
fi

# Clear in tmp path
rm -rf ${TMPPATH}/tmpmnt
rm -rf ${TMPPATH}/ramrootfs
mkdir ${TMPPATH}/tmpmnt

# Clear the old ramdisk
rm -f ${RAMPATH}/$MODULE_NAME

# Make a temp file which size is suitable
dd if=/dev/zero of=${TMPPATH}/ramrootfs bs=1k count=6144

# Create a ext2 filesystem
mke2fs -F -m 0 -i 2000 ${TMPPATH}/ramrootfs

# Mount it to tmpmnt/
mount -o loop -t ext2 ${TMPPATH}/ramrootfs ${TMPPATH}/tmpmnt

# Copy everything from kernel to this.
cd ${TMPPATH}/tmpmnt
echo ${SOURCE}
cp -av ${SOURCE}/* .
cd ${TMPPATH}
# Unmount it the ext2 filesystem
cp ${TMPPATH}/tmpmnt ${RAMPATH}/filesystem -fr
umount ${TMPPATH}/tmpmnt
cat ${TMPPATH}/ramrootfs | gzip -9 > /${RAMPATH}/ramdisk
echo Copying ramdisk image to ${RAMPATH}
sync

这里给出一个自动生成脚本,在启动的时候先把这个文件拷贝到ram里面,然后告诉kernel它的地址在什么地方就可以了。

五、生成一个cramfs:

找到cramfs的toolchain,
./mkcramfs -r $(FS_DIR) $(FS_NAME).bin;

六、生成一个mksquashfs:
找到squashfs的toolchain,
./mksquashfs $(FS_DIR) $(FS_NAME) -noappend -be -lzma -no-fragments –noI;
总结:
Ramfs是生成rootfs中最复杂的一个,但是在执行中是最快的一个;squashfs是和kernel的patch一起发布的,打上补丁后使用还是比较方便,但是使用时候必须注意是否目录可写;cramfs现在已经整合到kernel中,可能使用会有bug,我也没有查出来。因此推荐使用的时候Ramfs和squashfs,Ramfs比较快但是可写的空间比较小,squashfs稍微慢点,但是有比较大的空间储存文件。

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/66039/showart_572511.html

 

posted @ 2015-08-27 15:20  eric0803  阅读(651)  评论(0编辑  收藏  举报