红联Linux门户
Linux帮助

制作文件系统

发布时间:2014-12-02 15:20:48来源:linux网站作者:npy_lp

开发平台:Ubuntu11.04

目标板:ARM体系结构

编译器:arm-gcc-4.1.1.tar.bz2

1、把arm-gcc-4.1.1.tar.bz2下载到Ubuntu的$HOME目录下,然后解压。

$ tar jvxf arm-gcc-4.1.1.tar.bz2 

2、使用bash内置命令export把交叉编译工具链可执行文件所在目录的绝对路径添加到环境变量PATH中。

$ export PATH=$HOME/4.1.1/bin:$PATH 

注意,这样的改变只对当前终端(Terminal)有效。

如果不想每次新打开终端时都要设置一次,可以在$HOME目录下的.bashrc(前面的点代表bashrc是一个隐藏文件,执行ls –a可查看到)文件的最后添加如下的一行,这样每次打开终端时,被启动的bash会自动对这个文件执行source命令,使这个文件中设置的所有参数都成为当前shell环境的一部分。

export PATH=$HOME/4.1.1/bin:$PATH 

环境变量PATH被bash用于定位用户在命令行键入的命令。执行arm-linux-gnu-gcc时shell程序bash就是通过环境变量PATH中的路径去查找它的。

交叉编译工具链一般都带有一定的前缀(这里的前缀是arm-linux-gnu-,在制作交叉编译工具链的时候设定),以区别默认安装的基于X86平台的编译器。


开发平台:Ubuntu11.04

目标板:ARM体系结构

编译器:arm-gcc-4.1.1.tar.bz2

源代码:busybox-1.19.2.tar.bz2

BusyBox - The Swiss Army Knife of EmbeddedLinux.

BusyBox 是一个集成了一百多个常用Linux命令和工具的应用程序。它不仅包含了一些简单的命令,如 cat 、echo和ls等,而且还包含了一些更大、更复杂的工具,例如 grep、find、mount 以及 telnet等。简单地说,BusyBox就好像是个大工具箱,集成了许多Linux常用的工具和命令。

BusyBox最初是由Bruce Perens在1996年为DebianGNU/Linux安装盘而编写的。

1、交叉编译BusyBox的默认配置

$ tar jvxf busybox-1.19.2.tar.bz2 
$ cd busybox-1.19.2/ 
$ make defconfig   //通过执行make help获得帮助 

设置交叉编译工具链前缀:

$ make menuconfig 
 Busybox Settings ---> 
Build Options ---> 
() Cross Compiler prefix 

回车,在弹出的界面中输入交叉编译工具链的前缀

使用arm-gcc-4.1.1.tar.bz2编译时会发生缺少头文件ubi-user.h的错误:

miscutils/ubi_tools.c:63:26: error: mtd/ubi-user.h: No such file or directory 
miscutils/ubi_tools.c: In function 'ubi_tools_main': 
miscutils/ubi_tools.c:133: error: 'UBI_DEV_NUM_AUTO' undeclared (first use in this function) 
miscutils/ubi_tools.c:133: error: (Each undeclared identifier is reported only once 
miscutils/ubi_tools.c:133: error: for each function it appears in.) 
miscutils/ubi_tools.c:134: error: 'UBI_VOL_NUM_AUTO' undeclared (first use in this function) 
miscutils/ubi_tools.c:153: error: storage size of 'req' isn't known 
miscutils/ubi_tools.c:161: error: 'UBI_IOCATT' undeclared (first use in this function) 
miscutils/ubi_tools.c:153: warning: unused variable 'req' 
miscutils/ubi_tools.c:167: error: 'UBI_IOCDET' undeclared (first use in this function) 
miscutils/ubi_tools.c:170: error: storage size of 'req' isn't known 
miscutils/ubi_tools.c:177: error: 'UBI_MAX_VOLUME_NAME' undeclared (first use in this function) 
miscutils/ubi_tools.c:184: error: 'UBI_STATIC_VOLUME' undeclared (first use in this function) 
miscutils/ubi_tools.c:186: error: 'UBI_DYNAMIC_VOLUME' undeclared (first use in this function) 
miscutils/ubi_tools.c:195: error: 'UBI_IOCMKVOL' undeclared (first use in this function) 
miscutils/ubi_tools.c:170: warning: unused variable 'req' 
miscutils/ubi_tools.c:201: error: 'UBI_IOCRMVOL' undeclared (first use in this function) 
miscutils/ubi_tools.c:204: error: storage size of 'req' isn't known 
miscutils/ubi_tools.c:214: error: 'UBI_IOCRSVOL' undeclared (first use in this function) 
miscutils/ubi_tools.c:204: warning: unused variable 'req' 
miscutils/ubi_tools.c:222: error: 'UBI_IOCVOLUP' undeclared (first use in this function) 
make[1]: *** [miscutils/ubi_tools.o] Error 1 
make: *** [miscutils] Error 2 

解决这个问题的方法是从linux-2.6.38.8内核源码的include/mtd/目录下拷贝头文件ubi-user.h到4.1.1/arm-linux-gnu/include/mtd/目录:

$ cd $HOME/4.1.1/arm-linux-gnu/include 
$ mkdir mtd 
$ cp linux-2.6.38.8/include/mtd/ubi-user.h mtd/ 

执行make和make install即可编译和安装:

$ make 
$ make install  //默认安装在当前目录的_install目录下。 

2、根据项目需要适当裁减

(1)、跟Linux内核类似,BusyBox也可以通过执行make menuconfig命令启动基于ncurses的配置界面

BusyBox中并没有尖括号(< >)的选项,也不会被编译成模块。

(2)、BusyBox将所有配置进行了分类,可以很方便地根据项目的需要进行裁减。

Busybox Settings --->//BusyBox的通用配置,一般采用默认值即可。  
---Applets 
Archival Utilities --->  //压缩、解压缩相关工具。  
Coreutils --->   //最基本的命令,如cat、cp、ls等。  
Console Utilities --->   //控制台相关命令。  
Debian Utilities --->//Debian操作系统相关命令。  
Editors ---> //编辑工具,如vi、awk、sed等。  
Finding Utilities --->   //查找工具,如find、grep、xargs。  
Init Utilities --->  //BusyBox init相关命令。  
Login/Password Management Utilities --->   //登陆、用户账号/密码等方面的命令。  
Linux Ext2 FS Progs ---> //ext2文件系统的一些工具。  
Linux Module Utilities --->  //加载/卸载模块等相关的命令。  
Linux System Utilities --->  //一些系统命令。  
Miscellaneous Utilities ---> //一些不好分类的命令,如crond、crontab。  
Networking Utilities --->//网络相关的命令和工具。  
Print Utilities ---> //print spool服务及相关工具。  
Mail Utilities --->  //mail相关命令。  
Process Utilities --->   //进程相关命令,如ps、kill等。  
Runit Utilities ---> //runit程序。  
Shells --->  //shell程序。  
System Logging Utilities --->//系统日志相关工具,如syslogd、klogd。 

说明:虽然BusyBox被称为嵌入式Linux中的瑞士军刀,但并不是一定非要使用它不可,如果你觉得它的某些功能不能满足你系统的要求,那么你可以毫不犹豫地把这些功能舍弃掉,换用其他相应的程序包。


源代码:busybox-1.19.2.tar.bz2

Linux内核启动过程的最后一步就是通过do_execve()函数加载执行用户空间的init程序(如BusyBox init、sysvinit等等),它是系统中所有其他进程的父进程(进程ID为1),在系统运行期间以守护进程的形式一直存在,主要用来完成系统的各项配置以及监视其子进程的运行状况。

1、BusyBox init的执行过程

除了基本的命令之外,BusyBox也支持init功能,跟其他init程序一样,BusyBox的init程序也是用来完成系统的各项配置。

(1)、在执行parse_inittab()函数时,如果/etc/inittab文件不存在,BusyBox init会使用以下的默认配置:
 

::sysinit:/etc/init.d/rcS 
::askfirst:/bin/sh 
::ctrlaltdel:/sbin/reboot 
::shutdown:/sbin/swapoff -a 
::shutdown:/bin/umount -a -r 
::restart:/sbin/init 

(2)、在开发板上执行env命令即可查看配置好的环境变量。

/ # env 
USER=root 
HOME=/ 
TERM=vt102 
PATH=/sbin:/usr/sbin:/bin:/usr/bin 
SHELL=/bin/sh 
PWD=/ 

2、inittab文件的语法

BusyBox inittab文件的相关说明以及范例都在busybox-1.19.2源码的examples/inittab文件中。它的每一行的格式如下所示:

<id>:<runlevels>:<action>:<process> 

<id>:用来指定<process>要使用的控制台,如果使用与init进程一样的控制台,则此项可以省略。

<runlevels>:BusyBox init不支持运行级别,完全忽略此项。

<process>:用来指定要执行的程序,包括此程序的命令行选项。

<action>:用来指定控制<process>执行的方式。

在busybox-1.19.2/init/init.c文件中,BusyBox init所支持的动作类型以宏的形式被定义,并且对每种动作类型的含义都做了简要的说明。

/* Each type of actions can appear many times. They will be
* handled in order. RESTART is an exception, only 1st is used.
*/ 
/* Start these actions first and wait for completion */ 
#define SYSINIT 0x01  
/* Start these after SYSINIT and wait for completion */ 
#define WAIT0x02  
/* Start these after WAIT and *dont* wait for completion */ 
#define ONCE0x04  
/*
* NB: while SYSINIT/WAIT/ONCE are being processed,
* SIGHUP ("reread /etc/inittab") will be processed only after
* each group of actions. If new inittab adds, say, a SYSINIT action,
* it will not be run, since init is already "past SYSINIT stage".
*/ 
/* Start these after ONCE are started, restart on exit */ 
#define RESPAWN 0x08  
/* Like RESPAWN, but wait for <Enter> to be pressed on tty */ 
#define ASKFIRST0x10  
/*
* Start these on SIGINT, and wait for completion.
* Then go back to respawning RESPAWN and ASKFIRST actions.
* NB: kernel sends SIGINT to us if Ctrl-Alt-Del was pressed.
*/ 
#define CTRLALTDEL  0x20  
/*
* Start these before killing all processes in preparation for
* running RESTART actions or doing low-level halt/reboot/poweroff
* (initiated by SIGUSR1/SIGTERM/SIGUSR2).
* Wait for completion before proceeding.
*/ 
#define SHUTDOWN0x40  
/*
* exec() on SIGQUIT. SHUTDOWN actions are started and waited for,
* then all processes are killed, then init exec's 1st RESTART action,
* replacing itself by it. If no RESTART action specified,
* SIGQUIT has no effect.
*/ 
#define RESTART 0x80


开发平台:Ubuntu 11.04

在项目开发阶段,为了调试方便,一般不会把内核和文件系统镜像直接烧写到开发板的FLASH中,而是通过网络的方式实现:

内核镜像:通过TFTP服务把存放在开发平台(如Ubuntu)某个目录(如/tftpboot)下的内核镜像(如uImage)烧写到开发板的内存中,然后直接从内存启动。

文件系统:不用制作成镜像,文件系统的所有文件都存放在开发平台(如Ubuntu)的某个目录(如/opt/nfsdir)下,然后通过NFS服务把这个目录当作开发板的根目录。

1、NFS服务的配置

NFS是一种基于远程过程调用(Remote Procedure Call, RPC)协议,采用客户端/服务器端结构而实现的分布式文件系统。

我们一般在开发平台系统(如Ubuntu)中安装NFS服务器端,并指定相应的共享目录(如/opt/nfsdir),然后客户端就可以通过网络像访问本地目录一样透明地访问这个服务器端共享的目录。只要客户端拥有相应的权限,就可以读写、创建和删除其中的任何文件(包括目录)。

目前NFS主要有3个版本(即版本2、3和4),在实践中须要注意客户端和服务器端版本的兼容性,以确保NFS服务的顺利实现。

(1)、Ubuntu中NFS服务器端的配置

配置NFS服务器端通常包括两个步骤,一是安装NFS服务器端软件包,二是在/etc/exports配置文件中指定共享目录并给予客户端一定的访问权限。

首先,在Ubuntu中安装NFS服务器端:

$ sudo apt-get install nfs-kernel-server 

在以上软件的安装过程中,会同时安装nfs-common和portmap等相关的底层支持软件包。

The following NEW packages will be installed: 
libgssglue1 libnfsidmap2 librpcsecgss3 nfs-common nfs-kernel-server portmap 

nfs-common是一个通用的支持软件包,包括rpc.statd、rpc.idmapd及rpc.gssd等实用程序,为NFS服务器和NFS客户系统提供底层支持。

portmap用于提供NFS协议需要的RPC连接服务,管理和维护基于RPC规范的网络连接与数据传输。

然后,创建NFS共享目录,并把这个新创建的共享目录的绝对路径添加到/etc/exports配置文件中:

$ sudo mkdir -p /opt/nfsdir  //如果父目录/opt不存在的话,mkdir命令需要加-p选项 

$ sudo vi /etc/exports 

/opt/nfsdir *(rw,sync,no_root_squash,no_subtree_check) 

其中,/opt/nfsdir是NFS服务共享目录,*代表允许所有的网络段访问,rw指的是客户端的可读写权限,sync表示强制NFS服务器端采用同步方式处理客户端的数据写操作,no_root_squash指的是使NFS客户端的超级用户拥有与服务器端超级用户相同的访问权限,no_subtree_check指的是禁止NFS子目录树的检测。

最后,重新启动服务:

$ sudo /etc/init.d/portmap restart 
$ sudo /etc/init.d/nfs-kernel-server restart 

 (2)、配置开发板内核使其支持NFS服务的客户端

如在linux-2.6.38.8内核中配置NFS服务的过程:

$ make menuconfig 

File systems ---> 
[*] Network File Systems ---> 
<*> NFS client support 
[*]   NFS client support for NFS version 3 //也可以使用版本4  
[*] Root file system on NFS 

2、Ubuntu中TFTP服务的配置

TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。

首先,在Ubuntu中安装TFTP相关软件包:

$ sudo apt-get install tftp-hpa tftpd-hpa 

不需要inetd服务,tftpd也可以独立地运行。

然后,创建TFTP服务的共享目录,并修改配置文件/etc/default/tftpd-hpa以指定这个共享目录:

$ sudo mkdir /tftpboot 

$ vi /etc/default/tftpd-hpa 

# /etc/default/tftpd-hpa  
 
TFTP_USERNAME="tftp" 
TFTP_DIRECTORY="/tftpboot" //指定tftp服务的共享目录  
TFTP_ADDRESS="0.0.0.0:69" 
TFTP_OPTIONS="--secure" 

最后,重新启动TFTP服务:

$ sudo /etc/init.d/tftpd-hpa restart


开发平台:Ubuntu11.04

目标板:ARM体系结构

编译器:arm-gcc-4.1.1.tar.bz2

1、制作文件系统

(1)、在$HOME(本文$HOME的值是/home/richard)目录下创建制作文件系统所用的工作目录,并把busybox-1.19.2中生成的文件全部拷贝到此工作目录下:

$ cd $HOME 
$ mkdir rootfs 
$ cd rootfs/ 
$ cp -a busybox-1.19.2/_install/* . 

另外,还要在此工作目录下为文件系统创建必要的目录:
$ mkdir etc lib sys proc dev 

(2)、从交叉编译工具链中拷贝所需的动态库
$ cd 4.1.1/arm-linux-gnu/lib 
$ cp -a libm-2.5.so libm.so libm.so.6 /home/richard/rootfs/lib 
$ cp -a libc-2.5.so libc.so.6 /home/richard/rootfs/lib/ 
$ cp libgcc_s.so.1 /home/richard/rootfs/lib/ 

可在开发板上通过ldd命令获知BusyBox所依赖的动态库。
/bin # ldd busybox 
libm.so.6 => /lib/libm.so.6 (0x40024000) 
libc.so.6 => /lib/libc.so.6 (0x400d4000) 
/lib/ld-linux.so.2 (0x40000000) 

(3)、配置文件系统的etc目录
$ cd etc/ 

创建inittab文件:
$ vi inittab 

::sysinit:/etc/init.d/rcS 
::askfirst:-/bin/sh 
::ctrlaltdel:/sbin/reboot 
::shutdown:/sbin/swapoff -a 
::shutdown:/bin/umount -a -r 
::restart:/sbin/init 

注意,/bin/sh前须要添加前缀“-”,否则会提示以下的信息:
/bin/sh: can't access tty; job control turned off 

创建fstab文件(由mount –a命令所执行):
$ vi fstab

#device mount point fs-type options dump-freq   pass-num  
none/proc   procdefaults0   0 
none/syssysfs   defaults0   0 
none/dev/ptsdevpts  defaults0   0 
none/dev/shmtmpfs   defaults0   0 

创建rcS文件:
$ mkdir init.d 
$ cd init.d/ 
$ vi rcS 

#!/bin/sh  
mount -t tmpfs mdev /dev  
 
mkdir /dev/pts 
mkdir /dev/shm 
 
mount -a 
 
echo /sbin/mdev > /proc/sys/kernel/hotplug 
mdev -s 

$ chmod +x rcS 

(4)、创建console的设备节点
$ cd dev/ 
$ sudo mknod console c 5 1 

如果不提前创建console设备节点的话,可能会导致系统无法启动。
Warning: unable to open an initial console. 

2、在开发板上测试新建的文件系统

适用于优龙FS2410开发板的u-boot和Linux内核镜像

(1)、拷贝Linux内核镜像到TFTP服务的共享目录中
$ sudo cp uImage /tftpboot/ 

(2)、配置u-boot环境参数
FS2410# setenv bootdelay 3 
FS2410# setenv hostname tanglinux 
FS2410# setenv serverip 192.168.7.205 
FS2410# setenv ipaddr 192.168.7.36 
FS2410# setenv gatewayip 192.168.7.1 
FS2410# setenv bootargs console=ttySAC0,115200 init=/linuxrc root=/dev/nfs nfsroot=192.168.7.205:/home/richard/rootfs ip=192.168.7.36:192.168.7.205:192.168.7.1:255.255.255.0:tanglinux:eth0:off 
FS2410# setenv bootcmd tftp 30800000 uImage\; bootm 
FS2410# save 

关于使用NFS文件系统时Linux内核命令行参数(Kernel command line)如何设置的问题,可参考linux-2.6.38.8内核源码中的Documentation/filesystems/nfs/nfsroot.txt文件。
nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] 
ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf> 

(3)、把工作目录添加到NFS服务的配置文件(/etc/exports)中
$ sudo vi /etc/exports 

/home/richard/rootfs *(rw,sync,no_root_squash,no_subtree_check) 

$ sudo /etc/init.d/nfs-kernel-server restart 

(4)、系统启动完成后,会提示以下信息:

VFS: Mounted root (nfs filesystem). 
Freeing init memory: 200K 
 
Please press Enter to activate this console. 

然后回车,即可通过串口操作开发板了。