制作嵌入式根文件系统.docx
《制作嵌入式根文件系统.docx》由会员分享,可在线阅读,更多相关《制作嵌入式根文件系统.docx(14页珍藏版)》请在冰豆网上搜索。
制作嵌入式根文件系统
制作嵌入式根文件系统
5.1根文件系统简介
Linux引导启动时,默认使用的文件系统是根文件系统。
根文件系统是存放Linux系统所必须的各种工具软件、库文件、脚本、配置文件和其他特殊文件的地方,也可以包括各种软件包。
根文件系统一般包括如下内容:
1)基本的文件系统结构,包含一些必须的目录,比如:
/dev,/proc,/bin,/etc,/lib,/usr,/tmp。
2)基本程序运行所需的库函数,如:
Glibc/uC-libc。
3)基本的系统配置文件,如:
rc,inittab等脚本文件。
4)必要的设备支持文件,如:
/dev/hd*,/dev/tty,/dev/fd0。
5)基本的应用程序,如:
sh,ls,cp,mv等。
根文件系统的内容
建立必须的Linux目录
一个Linux系统一般有以下目录:
/dev:
设备文件,I/O操作时需要
/lib:
一般是系统启动运行共享C库,内核模块
/proc:
内核情况的映射虚拟目录
/mnt:
其它磁盘系统挂接点,手工挂接点
/etc:
系统配置文件的存放
/boot:
引导加载程序所使用的静态文件
/sbin:
Linux系统命令
/home:
用户主目录,包括共服务器帐号所使用的主目录
/bin:
Linux必须命令
/var:
系统工具所存的数据
/tmp:
临时文件
/usr:
其它工具以及用户程序的存放处
而/home/mnt/opt/root是针对多用户的,所以嵌入式系统中可以不要,是否要boot目录取决于加载程序是否会在内核启动之前从根文件系统取回内核。
注意存放二进制的几个目录:
/bin/sbin/usr/bin/usr/sbin的区别,/bin存放用户和管理员都必需的命令,/sbin存放管理员必备的命令而普通用户不需要的,/usr/bin存放的不是用户必备的命令,/usr/sbin不是管理员必备的命令。
$mkdirbindevetclibprocsbintmpusrvar
$chmod1777tmp
建立tmp目录时开启了stickybit,主要作用是只能建立文件的用户才能删除。
根文件系统重要目录介绍
/lib目录
/lib里的文件可以用glibc的也可以选用uClibc的,后者与前者兼容,体积小很多。
必须包含的库文件主要有两类:
以*.so结尾实际的库文件和以*.so.1version主修版本连接文件,它们是在程序运行时使用。
必须包括下列文件:
ld–2.1.3.solibutil–2.1.3.so
ld–linux.so.2libutil.so.1
libc–2.1.3.solibtermcap.so.2.0.8
libc.so.6libtermcap.so.2
libcrypt–2.1.3.solibresolv.so.2
libcrypt.so.1libresolv–2.1.3.so
libdb–2.1.3.solibpthread.so.0
libdb.so.3libpthread–0.8.so
libdl–2.1.3.solibproc.so.2.0.0
libdl.so.2libnss–files.so.2
libm–2.1.3.solibnss-files–2.1.3.so
libm.so.6libnss–dns.so.2
libnsl–2.1.3.solibnss-dns–2.1.3.so
libnsl.so.1
/etc目录
/etc目录包含了Linux的配置文件,它们决定Linux的引导,运行特性。
目前Linux已经支持了很多种文件系统:
1.Ramdisk上的Ext2
Ext2是Linux事实上的标准文件系统,它已经取代了它的前任———扩展文件系统(或Extfs)。
Extfs支持的文件大小最大为2GB,支持的最大文件名称大小为255个字符,而且它不支持索引节点(包括数据修改时间标记)[12]。
Ext2做得更好,它的优点是:
(1)Ext2支持达4TB的内存;
(2)Ext2文件名称最长可以到1012个字符;
(3)当创建文件系统时,管理员可以选择逻辑块的大小(通常大小可选择1024、2048和4096字节);
(4)Ext2实现了快速符号链接。
不需要为此目的而分配数据块,并且将目标名称直接存储在索引节点(inode)表中。
这使性能有所提高,特别是在速度上。
因为Ext2的稳定性、可靠性和健壮性,所以几乎在所有基于Linux的系统(包括台式机、服务器和工作站—并且甚至一些嵌入式设备)上都使用Ext2。
然而,当在嵌入式设备中使用Ext2时,它有一些缺点:
(1)Ext2是为IDE设备那样的块设备设计的,这些设备的逻辑块大小是512字节,1K字节等这样的倍数。
这不太适合于扇区大小因设备不同而不同的闪存设备。
(2)Ext2没有提供对基于扇区的擦除/写操作的良好管理。
在Ext2中,为了在一个扇区中擦除单个字节,必须将整个扇区复制到RAM,然后擦除,然后重写入。
考虑到闪存设备具有有限的擦除寿命(大约能进行100,000次擦除),在此之后就不能使用它们,所以这不是一个特别好的方法。
(3)在出现电源故障时,Ext2不是防崩溃的。
Ext2不支持损耗平衡,因此缩短了扇区/闪存的寿命(损耗平衡确保将地址范围的不同区域轮流用于写和/或擦除操作延长闪存设备的寿命)。
Ext2没有很完美的扇区管理,这使设计块驱动程序十分困难。
2.JFFS2
日志闪存文件系统,版本2(JFFS2)。
瑞典的AxisCommunications开发了最初的JFFS,RedHat的DavidWoodhouse对它进行了改进。
第二个版本,JFFS2,作为用于微型嵌入式设备的原始闪存芯片的实际文件系统而出现。
JFFS2文件系统是日志结构化的,这意味着它基本上是一长列节点。
每个节点包含有关文件的部分信息—可能是文件的名称、也许是一些数据[7]。
相对于Ext2,JFFS2因为有以下这些优点而在无盘嵌入式设备中越来越受欢迎。
(1)JFFS2在扇区级别上执行闪存擦除/写/读操作要比Ext2好。
(2)JFFS2提供了比Ext2fs更好的崩溃/掉电安全保护。
当需要更改少量数据时,Ext2将整个扇区复制到内存(DRAM)中,在内存中合并新数据,并写回整个扇区。
这意味着为了更改单个字,必须对整个扇区(64KB)执行读/擦除/写例程—这样做的效率非常低。
JFFS2附加文件而不是重写整个扇区,并且具有崩溃/掉电安全保护这一功能。
(3)JFFS2是专门为闪存芯片那样的嵌入式设备创建的,所以它的整个设计提供了更好的闪存管理。
3.CRAMF
CRAMFS文件系统,是一种被压缩的只读文件系,其中压缩比例能达到50%,是界于RAMDISK和JFSS2之间的一种文件系统。
4.YAFFS
YAFFS是第一个专门为NANDFlash存储器设计的嵌入式文件系统,适用于大容量的存储设备;并且是在GPL(GeneralPublicLicense)协议下发布的,可在其网站免费获得源代码。
YAFFS中,文件是以固定大小的数据块进行存储的,块的大小可以是512字节、1024字节或者2048字节。
这种实现依赖于它能够将一个数据块头和每个数据块关联起来。
每个文件(包括目录)都有一个数据块头与之相对应,数据块头中保存了ECC(ErrorCorrectionCode)和文件系统的组织信息,用于错误检测和坏块处理。
充分考虑了NANDFlash的特点,YAFFS把这个数据块头存储在Flash的16字节备用空间中。
当文件系统被挂载时,只须扫描存储器的备用空间就能将文件系统信息读入内存,并且驻留在内存中,不仅加快了文件系统的加载速度,也提高了文件的访问速度,但是增加了内存的消耗[5]。
为了在节省内存的同时提高文件数据块的查找速度,YAFFS利用更高效的映射结构把文件位置映射到物理位置。
文件的数据段被组织成树型结构,这个树型结构具有32字节的节点,每个内部节点都包括8个指向其他节点的指针,叶节点包括16个2字节的指向物理地址的指针。
YAFFS在文件进行改写时总是先写入新的数据块,然后将旧的数据块从文件中删除。
这样即使在修改文件时意外掉电,丢失的也只是这一次修改数据的最小写入单位,从而实现了掉电保护,保证了数据完整性。
结合贪心算法的高效性和随机选择的平均性,YAFFS实现了兼顾损耗平均和减小系统开销的目的。
当满足特定的小概率条件时,就会尝试随机选择一个可回收的页面;而在其他情况下,则使用贪心算法来回收最“脏”的块。
YAFFS文件系统是按层次结构设计的,分成以下4部分:
yaffs_guts.c,文件系统的主要算法,这部分代码完全是用可移植的C语言编写的;yaffs_fs.c,LinuxVFS层的接口;NAND接口,yaffs_guts和NAND内存访问函数之间的包装层;可移植函数,服务的包装函数。
最重要的一点是,为了获得更好的移植性,YAFFS提供直接调用的模式,这才使得我们有机会来实现YAFFS文件系统在C51系统上的移植。
5.2开源软件Busybox简介
根文件系统的制作就是生成包含上述各种文件的文件系统的过程,我们可以通过直接拷贝宿主机上交叉编译器处的文件来制作根文件系统,但是这种方法制作的根文件系统一般过于庞大。
也可以通过一些工具如Busybox来制作根文件系统,用Busybox制作的根文件系统可以做到短小精悍并且运行效率较高。
Busybox被形象的称为“嵌入式Linux的瑞士军刀”,它是一个UNIX工具集。
它可提供一百多种GNU常用工具、shell脚本工具等。
虽然Busybox中的这些工具相对于GNU提供的完全工具有所简化,但是它们都很实用。
Busybox的特色是所有命令都编译成一个文件——Busybox,其他命令工具(如sh、cp、ls等)都是指向Busybox文件的连接。
在使用Busybox生成的工具时,会根据工具的文件名散转到特定的处理程序。
这样,所有这些程序只需被加载一次,而所有的Busybox工具组件都可以共享相同的代码段,这在很大程度上节省了系统的内存资源和提高了应用程序的执行速度。
Busybox仅需用几百kB的空间就可以运行,这使得Busybox很适合嵌入式系统使用。
同时,Busybox的安装脚本也使得它很容易建立基于Busybox的根文件系统。
通常只需要添加/dev、/etc等目录以及相关的配置脚本,就可以实现一个简单的根文件系统。
Busybox源码开放,遵守GPL协议,它提供了类似Linux内核的配置脚本菜单,很容易实现配置和裁减,通常只需要指定编译器即可[12]。
5.3根文件系统的选择原则
如果系统只配备了极小的flash,相对而言具有大量的RAM,那么Ramdisk或许是最佳选择,因为RAMdisk上的文件系统是经过压缩的,通常压缩比比原生文件系统(CRAMFS和JFFS2)高很多,然而RAMdisk的优势却被较高的RAM使用量抵消,此外如果需要永久性存储,便不适合使用Ramdisk,尽管如此,如果永久性存储器需求有限,正如前面的提示,可以使用Ramdisk来安装根文件系统的大部分内容,只有数据目录才从支持永久性存储的文件系统安装,尽管RAM价格便宜,但却比flash耗电,因此RAMdisk使用的RAM对某些系统并不适合[8]。
如果系统拥有稍微大一点的flash,或者如果会尽可能给实际在目标板上执行的应用程序保留RAM空间,而且可以为运行时解压缩出若干额外的CPU周期,那么CRAMFS是个非常好的选项,CRAMFS的压缩比低于RAMdisk,但它的能力对大多数不需要永久存储性嵌入式的应用来说已经够了。
所以,你可以选择在CRAMFS中安装不需要改变的部分,在具有永久性的文件系统上安装其余部分。
如果需要随时改变文件系统任何部分,JFFS2将会是最好的选择。
尽管JFFS2的压缩比比较低,不如CRAMFS,更不如RAMdisk。
但是JFFS2会为垃圾回收功能维护空间,并且它的原数据的结构允许文件系统的写入操作,所以JFFS2可以提供断电可靠性和损耗平衡这两个对使用flash系统来说非常重要的特性,可以通过使用JFFS2来延长flash的寿命,如果使用的是NAND形式的flash设备,便不适合使用JFFS2。
5.4制作yaffs根文件系统
根文件系统制作步骤(所修改部分均用黑体标出):
打开内核源码下的“fs”目录可以看到一个名为“yaffs”的目录,这说明2.6版的内核已经支持了yaffs文件系统,因此移植yaffs文件系统是很容易的。
1.获取BusyBox源码
首先从
2.修改并配置BusyBox
解压BusyBox,使用命令#tarxvfjbusybox-1.13.0.tar.bz2–C/opt/liu/解压到我的工作目录下。
然后进入到源码中,修改Makefile文件,修改如下:
ARCH ?
=arm
CROSS_COMPILE?
=/usr/local/arm/3.4.1/bin/arm-linux-
然后输入:
#makemenuconfig,进入到配置菜单,如图5-1所示。
然后配置如下:
A)BusyboxSettings--->
InstallationOptions--->
[*]Don'tuse/usr//这一选项在编译过程中选上,因为不选的话Busybox将默认安装到原系统的/usr目录下面,将覆盖掉系统原有的命令。
BuildOptions--->
[]BuildBusyBoxasastaticbinary(nosharedlibs)//采用动态链接。
BusyboxSettings配置菜单如图5-2所示。
B)BusyboxLibraryTuning--->
(2)MD5:
TradeBytesforSpeed
[*]Faster/procscanningcode(+100bytes)
[*]Supportfor/etc/networks
[*]Commandlineediting
(1024)Maximumlengthofinput
[*]Additionaleditingkeys
[*]vi-stylelineeditingcommands
(15)Historysize
[*]Historysaving
[*]Tabcompletion
[*]Usernamecompletion
[*]Fancyshellprompts
C)BusyboxSettings--->
---Applets
ArchivalUtilities--->
.......................
.......................
Shells--->
---AshShellOptions下面的项全选
BusyboxLibraryTuning配置菜单如图5-3所示。
D)LinuxModuleUtilities--->
[*]Supportversion2.6.xLinuxkernels
LinuxModuleUtilities配置菜单如图5-4所示。
图5-1Busybox配置菜单
图5-2BusyboxSettings配置菜单
图5-3BusyboxLibraryTuning配置菜单
图5-4LinuxModuleUtilities配置菜单
3.编译并安装busybox
使用命令#make;makeinstall编译busybox。
编译结束后,会在busybox-1.13.0目录下生成一个名为“_install”的目录,该目录下面情况如图5-5所示。
图5-5_install目录
4.构建文件系统框架
在工作目录下创建一个名为root_2.6.25.8的目录,然后复制上一步产生的文件到该目录下,再新建“dev”、“etc”、“home”、“lib”等目录,如图5-6所示。
图5-6文件系统框架
5.给文件添加内容
(1)“dev”目录
以root身份建立节点文件/dev/console,/dev/null
mknod-m600dev/consolec51
mknod-m666dev/nullc13
(2)“etc”目录
etc/profile内容如下:
#/etc/profile:
exportLD_LIBRARY_PATH=/lib
PATH=/bin:
/sbin:
/usr/bin:
/usr/sbin
exportPATH
USER="`id-un`"
LOGNAME=$USER
PS1='[\u@\h\W]\$'
PATH=$PATH
echo
etc/fstab内容如下:
proc/procprocdefaults00
none/tmpramfsdefaults00
mdev/devramfsdefaults00
sysfs/syssysfsdefaults00
etc/inittab内容如下:
#/etc/inittab
:
:
sysinit:
/etc/init.d/rcS
s3c2410_serial0:
:
askfirst:
-/bin/sh
:
:
ctrlaltdel:
/sbin/reboot
:
:
shutdown:
/bin/umount-a–r
/etc/mdev.conf内容为空,复制主机/etc下面的文件passwd,group,shadow文件到当前目录/etc下,并修改用户passwd中用户使用的shell名称。
FC6上默认的为bash,uboot中只支持ash。
修改前:
root:
x:
0:
0:
root:
/root:
/bin/bash
修改后:
root:
x:
0:
0:
root:
/root:
/bin/ash
6.编译文件系统镜像
下载源代码文件root.tar.gz,解压缩得到Development目录,里面有yaffs和yaffs2两个子目录。
这两个目录的utils目录里面是工具mkyaffsimage和mkyaffs2image的源代码,前者用来制作yaffs映象文件,后者用来制作yaffs2映象文件。
接着制作yaffs映象文件。
使用一下命令编译文件系统镜像:
#cd/opt/liu
#mkyaffsimageroot_2.6.25.8/root_2.6.25.8
编译出文件系统镜像文件后就能使用uboot在超级终端下进行烧写。
如图5-7所示。
图5-7yaffs烧写界面