转载地址:http://blog.chinaunix.net/uid-26310563-id-3168454.html
主机:Windows XP,VMware 8,Ubuntu
编译环境:arm-linux-gcc 4.4.3
Linux版本:linux-2.6.32.2
busybox版本:busybox-1.19.4
busybox源码下载地址:http://www.busybox.net/downloads/
参考资料:《嵌入式Linux应用开发完全手册》 韦东山
所谓创建根文件系统,就是创建各种目录,并且在里面创建各种文件。比如在/bin、/sbin目录下存放各种可执行程序,在/etc目录下存放配置文件,在/lib目录下存放库文件。Busybox主要用来创建/bin、/sbin等目录下的可执行文件,如命令行下经常使用的命令ls、mv、cp等。
编译busybox
Busybox的编译较为简单,一般使用默认配置即可,如果熟悉配置选项的话也可以执行make menuconfig进行手动裁剪。具体配置说明可参考《嵌入式Linux应用开发完全手册》。
修改busybox顶层目录的Makefile文件,修改如下两行:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux
然后执行make,编译busybox。编译完成后执行:
make CONFIG_PREFIX=/home/nfs/rootfs install
将busybox安装到目录/home/nfs/rootfs下。/home/nfs/rootfs是目标板文件系统的根目录。执行命令查看安装busybox后生成的文件:
# ls -l /home/nfs/rootfs/
drwxr-xr-x 2 root root 4096 2012-04-05 15:24 bin
lrwxrwxrwx 1 root root 11 2012-03-31 08:17 linuxrc -> bin/busybox
drwxr-xr-x 2 root root 4096 2012-03-31 08:17 sbin
drwxr-xr-x 5 root root 4096 2012-04-03 07:25 usr
linuxrc是内核启动的init进程,那内核又如何知道要启动的init进程是哪个呢?它是由uboot传递给linux内核参数中"init=xxx"决定的。在我的目标板的uboot中传递给内核的参数为"init=/linuxrc"。内核如何启动init进程可以查看内核代码init/main.c中的init_post函数。
构建lib库
虽然通过编译busybox生成了我们需要的可执行文件,但现在在目标板上仍然无法运行,需要添加lib库来支持可执行文件运行。可以使用uclibc和glibc来构建lib库。由于编译lib库相对复杂,而我们又有现成的lib库可以使用,这里我们就实行拿来主义。现成的lib库就在我们的交叉编译工具arm-linux-gcc的目录下,在本人主机上的绝对路径为/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib,
把该lib目录下的所有文件复制到目标板文件系统lib下,执行命令:
#cp -r /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib /home/nfs/rootfs/lib
PS:注意要加-r选项,把软链接文件原样复制过来,不加-r会复制软链接的链接文件,造成存储空间的浪费。
构建etc目录
创建etc/inittab,参照busybox的examples/inittab文件,内容如下:
点击(此处)折叠或打开
PS:这里的console是在构建/dev目录时创建的设备节点,对应的设备是启动Linux内核前传入的命令行参数“console=xxx”指定的控制台,我传递的参数为“console=ttySAC0,115200”,表示使用串口0,波特率为115200。
创建etc/init.d/rcS文件。rcS是系统启动后执行的第一个脚本文件,如果想把自己编写的应用程序设置为开机启动,在本文件中中加入运行该程序的命令即可。内容如下:
点击(此处)折叠或打开
修改添加文件可执行权限:#chmod +x etc/init.d/rcS。
创建etc/fstab文件,内容如下:
点击(此处)折叠或打开
构建dev目录
这里使用busybox的mdev创建设备文件,mdev是udev的简化版本,它也是通过读取内核信息来创建设备文件。
要使用mdev,需要内核支持sysfs文件系统,为了减少对Flash的读写,还要支持tmpfs文件系统。先确保内核已经设置了CONFIG_SYSFS、CONFIG_TMPFS配置项。
使用mdev的命令如下,请参考它们的注释以了解其作用:
#mount -t tmpfs mdev /dev (使用内存文件系统,减少对Flash的读写)
#mkdir /dev/pts (dev/pts用来支持外部网络连接(telnet)的虚拟终端)
#mount -t devpts devpts /dev/pts
#mount -t sysfs sysfs /sys (mdev通过sysfs文件系统获得设备信息)
#echo /bin/mdev > /proc/sys/kernel/hotplug (设置内核,当有设备插拔时调用/bin/mdev程序)
#mdev -s (在/dev目录下生成内核支持的所有设备的节点)
要在内核启动后,自动运行mdev。需要修改etc目录下的两个文件:修改etc/fstab来自动挂载文件系统、修改etc/init.d/rcS加入要自动运行的命令。修改后的文件如下:
etc/fstab
点击(此处)折叠或打开
etc/init.d/rcS
点击(此处)折叠或打开
添加mdev配置文件etc/mdev.conf,mdev.conf可以用来控制设备节点的所有者和权限,格式如下:
<device regex> <uid>:<gid> <octal permissions>
mdev.conf还可以设置mdev在dev目录下生成的设备节点的名字,Linux内核串口驱动原本对S3C2410、S3C2440注册的设备名是s3c2410_serial0、s3c2410_serial1、s3c2410_serial2,我们可以修改mdev.conf文件,使mdev在/dev目录下对应生成ttySAC0, ttySAC1和ttySAC2,以符合应用程序对于串口设备操作的习惯。配置文件mdev.conf的内容如下:
mdev.conf
点击(此处)折叠或打开
重要的一点忘写了,希望没有误导之前看这篇文章的网友。现补充如下:
由于mdev是通过init进程来启动的,在使用mdev构造/dev目录之前,init进程至少要用到两个设备文件/dev/console、/dev/null,所以要建立这两个设备文件。
# mkdir -r /home/nfs/rootfs/dev
# cd /home/nfs/rootfs/dev
# mknod console c 5 1
# mknod null c 1 3
构建其他目录
# mkdir proc mnt tmp sys root
到此,我们的根文件系统构建完毕,/home/nfs/rootfs目录下就是我们的根文件系统。目标板可以把它通过作为网络根文件系统,通过nfs直接启动。也可以把它制作为映像文件烧写到目标板的Flash启动。