王恒亮,王俊超
(西安电子科技大学电子信息攻防对抗与仿真重点实验室,陕西西安 710071)
嵌入式Linux凭借其良好的实时性、安全性和免费开源等特征,在电子信息、医疗、军工和工业生产等各个领域占据了重要地位。Ext 2文件系统(The Second Extended File System)是Linux操作系统中的标准文件系统,其通过对Minix文件系统扩展得到,具有较好的文件存取特性,对于中小型的文件更有明显优势。本文即在嵌入式Linux的基础上分析了Ext 2格式根文件系统制作的关键步骤,并进行了测试运行
PowerPC 是1991年,由 Apple、IBM、Motorola,3 家公司组成的AIM联盟推出的一种精简指令集微处理器构架。因其具有优异的性能、较低的能量损耗以及较少的散热量,因此从高端服务器CPU到嵌入式CPU市场都有着广泛的应用,特别是在嵌入式领域,具有良好的表现。飞思卡尔(FreeScale)公司出品的MPC8379E就是基于PowerPC构架下的一款低功耗高集成主控芯片,其主要应用于消费类电子产品、工业控制、VPN路由器、图像采集和印刷打印、无线局域网和网络访问服务器等多个领域。同样由飞思卡尔推出的MPC8379E-RDB开发板即是基于该芯片的拓展开发设备,本文所涉及的Ext 2根文件系统就是在该开发板上测试运行的。
制作根文件系统所需的一系列工具软件都要基于桌面Linux系统,然而由于Linux系统的开源性,目前存在着众多不同的发行版本。从理论上说各个版本均可完成制作,可由于不同发行版本的兼容性和默认包含的组件均有不同,因此在实际操作中无论是对于桌面Linux系统的版本、嵌入式Linux内核的版本亦或整个过程所用到的各个制作工具的版本,均要引起足够的重视,其都会不同程度地影响制作结果。本文选用经典版本Red Hat Linux 9.0。
其次是交叉编译环境。本文使用ELDK(Embedded Linux Development Kit),版本为:ELDK-version-4.2-Build-2008-04-01,安装完成后选择配置的编译器版本是ppc_6xx。关于ELDK的下载可在denx官网进入其ftp服务站点查看选择。关于编译器版本的选择要根据自己的目标处理器芯片,查看过ELDK安装镜像文件里的README.html之后再决定。
此外,由于移植嵌入式Linux的整个过程都要用到ELDK交叉编译环境,因此在环境变量中配置完编译器安装路径和编译器版本后,为了方便工作,最好将处理器构架也一起配置,需配置的文件是/etc/profile文件,配置结果如图1所示。
图1 Profile文件设置
最后是Linux内核版本的支持。本文使用的内核版本是Linux-2.6.25,编译时需要保证在File System配置里选中Ext 2文件系统的相关选项。
BusyBox是一个集成了一百多个常用Linux命令和工具的脚本软件,通常在制作文件系统时都会用其来简化生成Linux命令文件的过程。本文使用的BusyBox版本是BusyBox-1.11.2,可从官网下载。
图2 BusyBox文本交互配置界面
BusyBox的配置选项大部分均可保持默认,需留意在Busybox Settings→Build Options→下有一个名为Build BusyBox as a static binary(no shared libs)的选项,含义为是否静态编译BusyBox包含的各种命令。若选择该选项即静态编译,则最终编译好的各种可执行命令文件就可以脱离lib静态库文件直接运行,否则需要各种lib库文件的支持才能运行。在本文制作过程中选择静态编译。
配置安装完成后就会在默认BusyBox根路径中的_install目录下生成Ext 2根文件系统内将要包含的所有可执行命令文件。编译安装结果如图3所示。
图3 BusyBox编译安装结果
新建一个名为rootfs的文件夹作为整个根文件系统的根目录。在rootfs路径下新建如下根文件系统要用到的目录:etc,dev,home,lib,mnt,lost+found,opt,proc,root,sys,tmp,var。再拷贝_install目录中的所有文件到rootfs下。至此,整个根文件系统的雏形就完成,如图4所示。
图4 根文件系统雏形
1.3.1 生成mdev.conf文件和inittab文件
在rootfs/etc路径下新建一个 mdev.conf文件。mdev是一个udev的简化版本,主要用于支持一些热插拔设备。可以通过修改文件mdev.conf的内容自定义一些设备节点名称或链接来满足特定的需求,在此处为空即可。
在etc路径下新建一个名为inittab的文件。这个文件可以理解为整个根文件系统启动后首先要执行的脚本和命令的列表,也可以包括环境变量的export等。如果要将一个编写的程序、进程开机自启动,则需要在这个文件里添加相关的路径和命令。本文在inittab文件里添加了如下内容。
::sysinit:/etc/init.d/rcS
ttyS0::respawn:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/rc.d/rcS stop
::restart:/sbin/init
1.3.2 生成rcS文件
创建inittab文件的第一个行为:/etc/init.d/rcS脚本文件,当内核解析完inittab文件后就将首先执行rcS。在/etc路径下依次建立init.d文件夹和rcS文件,在rcS文件中添加如下内容。
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount-a
echo/sbin/mdev>/proc/sys/kernel/hotplug
mdev-s
1.3.3 生成fstab文件
回到etc路径下新建fstab文件,添加如下内容。
#file system mounttype optionsdumppass
proc/procproc defaults00
tmpfs/tmptmpfs defaults00
devpts/dev/ptsdevpts gid=5,mode=62000
sysfs/syssysfs defaults00
usbfs/proc/bus/usb usbfs defaults00
/dev/cdrom/mnt/cdrom iso9660 noauto,owner,ro00
/dev/sda1/mnt/hdd0 ext2 defaults12
该文件列出了系统上电后默认挂载的文件和文件系统。其中需要说明的是:第5列为dump选项,用来设置是否让备份程序dump备份文件系统,0为忽略,1为备份。第6列为fsck选项,告诉fsck程序以什么顺序检查文件系统,0为忽略。
以最后一行为例,假设现有一块已经格式化完成的Ext 2文件格式硬盘,于是在fstab文件中添加设备路径(/dev/sda1)和挂载路径(/mnt/hdd0),声明挂载选项为默认等必要信息,这样通电后系统就能自动挂载该硬盘。
1.3.4 生成mnt路径下的常用挂载点和控制台设备文
在mnt路径建立常用的挂载路径供系统使用,例如fstab文件中提到的mnt/hdd0和mnt/cdrom等。
在dev路径,执行如下两条命令建立设备节点来作为标准输入输出控制台。
mknod console c 5 1
mknod null c 1 3
因为 mdev通过初始化进程来启动的,在使用mdev构造/dev目录之前,init进程至少要用到设备文件/dev/console和/dev/null,所以必须要建立这两个设备文件。
1.3.5 复制用户控制文件和库文件
复制Red Hat Linux系统/etc路径下的三个文件:passwd、group和shadow到rootfs/etc路径下作为本文根文件系统的用户控制文件,也可以进入这三个文件进行修改用户名、删除登陆密码或者修改用户组等操作。
最后一步是拷贝相关lib库文件到rootfs/lib路径下。本文的交叉编译环境所使用的库文件在Red Hat Linux桌面系统的/usr/ppc/eldk/ppc_6xx/lib下,该目录达到了105 MB,显然不能完全拷贝,那么下面的问题就是:要拷贝哪些作为Ext 2根文件系统的lib库文件。该目录下的子目录和文件共分7类:(1)目标文件(.o),用于gcc链接可执行文件。(2)库工具文件(libtool),一般后缀是.la,在链接库文件时这些文件会被用到,他们列出了当前库文件所依赖的其它库文件,程序运行时就不需要这些文件了。(3)gconv目录,里面是各种链接脚本,在编译应用程序时,他们用于指定程序的运行地址,各段的位置等。(4)静态库文件(.a),例如libm.a。(5)动态库文件(.so、.so.[0 -9]*)。(6)动态链接库加载器,如ld-2.3.6.so。(7)其他目录及文件。显然,第(1)~(4)和第(7)类是不需要拷贝的。
由于动态链接的应用程序本身并不含有它所调用的库函数的代码,因此执行时需要动态链接库加载器来为它加载相应的库文件,所以第6类文件是需要拷贝的。除此之外,第5类文件当然也要拷贝,但这两类文件也相当大。通过执行powerpc-linux-readelf-d命令可以查看rootfs/bin/busybox文件知:busybox用到了3个库:通用C库(libc)、数学库(libm)和加密库(libcrypt)。因此,在不需要运行其他程序的情况下,本文只需要拷贝这3个库相关的文件即可。
以上在etc路径下建立的几个文件均可参考Red Hat Linux系统/etc中的内容,或者busybox-1.11.2/examples/bootfloppy/etc下的模板文件,只不过要注意根据自己的目标系统环境做适当修改,不可盲目复制粘贴。已完成的rootfs/etc文件如图5所示。
图5 rootfs根路径下的/etc文件目录
本文使用Genext2fs脚本工具版本是genext2fs-1.4.1,使用该工具来生成Ext 2格式的根文件系统需要得到blocks和inodes两个参数,还需要一个device_table.txt文件作为device table传入。关于device_table.txt文件可以在google搜索得到,关于blocks和inodes参数的计算可以按照如下关系进行。
fs_count=find/rootfs|wc-l
inodes=fs_count+400
fs_size=LANG=C du-slk/rootfs|cut-f1
blocks=fs_size+2400
所有参数都准备好之后就可以运行如下命令来生成Ext 2根文件系统
genext2fs-U-b$blocks-i$inodes-D/device_table.txt-d/rootfs rootfs.ext2
关于genext2fs命令的具体使用细节可以运行genext2fs-help来查看。然后用gzip-9 rootfs.ext2命令将该文件系统打包,这时会生成一个名为rootfs.ext2.gz的压缩文件。
最后使用uboot源代码tools目录下的mkimage工具来为压缩包添加一个0x40字节的文件头,这0x40字节中记录了各种必备信息,这样uboot就能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种压缩类型的以及映象名是什么等信息。
mkimage-n‘uboot ext2 ramdisk rootfs’-A ppc-O linux-T ramdisk-C gzip-d rootfs.ext2.gz rootfs.ext2.gz.uboot
至此整个根文件系统生成结束,如图6所示。
图6 利用Genext2fs等脚本工具生成镜像文件
利用tftp协议从上位机传输根文件系统镜像到目标板RAM,再从RAM烧写到Flash固化。首先要配置好IP地址、tftp路径等信息,可通过ping命令来检测是否连接成功。
图7 在uboot下确定IP连接和tftp路径
当确认连接成功后,即可开始tftp操作,具体步骤和结果见图8。
图8 tftp操作和烧写结果
烧写完成后就可以运行了,加载部分的反馈信息如图9所示,登录和运行的信息如图10所示。由于用户控制文件是直接拷贝桌面系统的,所以用户名密码都和桌面系统相同。
图9 加载根文件
图10 登录和运行根文件系统
完成的根文件系统原始文件,即rootfs整个文件夹的大小为14.1 MB,压缩后生成的根文件系统镜像文件,即rootfs.ext2.gz.uboot文件大小为2.3 MB,且已包含大部分常用的系统命令和库文件,能满足一般嵌入式系统的要求,经测试能在MPC8379E-RDB开发板上成功运行。
[1]Nagu D.Transaction - level modeling for architectural and power analysis of PowerPCand CoreConnect-based systems[M].USA:Nagu Dhanwada,2005.
[2]Gene S.Kernel configuration and development[M].UK:Gene Sally,2010.
[3]Vining N C,Done S,Glass I A,et al.EXT2 - positive multiple hereditary osteochondromas with some features suggestive of metachondromatosis[J].Skeletal Radiol,2012,41(5):607-610.
[4]叶梅,赵京伟,初元萍.嵌入式Linux系统在PowerPC上的实现[J].核电子学与探测技术,2006(5):614-618.
[5]史鸿声.基于PowerPC的雷达通用处理机设计[J].雷达科学与技术,2011(2):140-143.
[6]刘刚,赵剑川.Linux系统移植[M].北京:清华大学出版社,2011.
[7]郭学理,韦智,潘松.Linux的 Ext2文件系统[J].计算机应用研究,2001(5):64-66.
[8]顾咏枫,陈章龙.嵌入式Linux裁剪方法[J].小型微型计算机系统,2003,24(9):1697 -1700.
[9]陈海燕,任松岩.嵌入式Linux根文件系统的研究[J].现代电子技术,2010(4):73-75.