原文地址:使用busybox构建linux根文件系统 作者:charles413
主机:Windows
编译环境:arm-linux-gcc
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
修改busybox顶层目录的Makefile文件,修改如下两行:
ARCH
CROSS_COMPILE ?=
然后执行make,编译busybox。编译完成后执行:
make
将busybox安装到目录/home/nfs/rootfs下。/home/nfs/rootfs是目标板文件系统的根目录。执行命令查看安装busybox后生成的文件:
#
drwxr-xr-x
lrwxrwxrwx
drwxr-xr-x
drwxr-xr-x
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
PS:注意要加-r选项,把软链接文件原样复制过来,不加-r会复制软链接的链接文件,造成存储空间的浪费。
构建etc目录
创建etc/inittab,参照busybox的examples/inittab文件,内容如下:
点击(此处)折叠或打开
- # /etc/inittab
- # Boot-time system configuration/initialization script.
- # This is run first except when booting in single-user mode.
- #
- ::sysinit:/etc/init.d/rcS
- # /bin/sh invocations on selected ttys
- #
- # Note below that we prefix the shell commands with a "-" to indicate to the
- # shell that it is supposed to be a login shell. Normally this is handled by
- # login, but since we are bypassing login in this case, BusyBox lets you do
- # this yourself...
- #
- # Start an "askfirst" shell on the console (whatever that may be)
- console::askfirst:-/bin/sh
- #tty1::askfirst:-/bin/sh
- # Stuff to do before rebooting
- ::ctrlaltdel:/sbin/reboot
- ::shutdown:/bin/umount -a -r
PS:这里的console是在构建/dev目录时创建的设备节点,对应的设备是启动Linux内核前传入的命令行参数“console=xxx”指定的控制台,我传递的参数为“console=ttySAC0,115200”,表示使用串口0,波特率为115200。
创建etc/init.d/rcS文件。rcS是系统启动后执行的第一个脚本文件,如果想把自己编写的应用程序设置为开机启动,在本文件中中加入运行该程序的命令即可。内容如下:
点击(此处)折叠或打开
- #!/bin/sh
- ifconfig eth0 192.168.1.158
- mount -a
修改添加文件可执行权限:#chmod
创建etc/fstab文件,内容如下:
点击(此处)折叠或打开
- #device mount-poin type options dump fsck order
- proc /proc proc defaults 0 0
- tmpfs /tmp tmpfs defaults 0 0
构建dev目录
这里使用busybox的mdev创建设备文件,mdev是udev的简化版本,它也是通过读取内核信息来创建设备文件。
要使用mdev,需要内核支持sysfs文件系统,为了减少对Flash的读写,还要支持tmpfs文件系统。先确保内核已经设置了CONFIG_SYSFS、CONFIG_TMPFS配置项。
使用mdev的命令如下,请参考它们的注释以了解其作用:
#mount
#mkdir
#mount
#mount
#echo
#mdev
要在内核启动后,自动运行mdev。需要修改etc目录下的两个文件:修改etc/fstab来自动挂载文件系统、修改etc/init.d/rcS加入要自动运行的命令。修改后的文件如下:
etc/fstab
点击(此处)折叠或打开
- #device mount-poin type options dump fsck order
- proc /proc proc defaults 0 0
- tmpfs /tmp tmpfs defaults 0 0
- sysfs /sys sysfs defaults 0 0
- tmpfs /dev tmpfs defaults 0 0
etc/init.d/rcS
点击(此处)折叠或打开
- #!/bin/sh
- ifconfig eth0 192.168.1.158
- mount -a
- mkdir /dev/pts
- mount -t devpts devpts /dev/pts
- echo /sbin/mdev > /proc/sys/kernel/hotplug
- mdev -s
添加mdev配置文件etc/mdev.conf,mdev.conf可以用来控制设备节点的所有者和权限,格式如下:
<device
mdev.conf还可以设置mdev在dev目录下生成的设备节点的名字,Linux内核串口驱动原本对S3C2410、S3C2440注册的设备名是s3c2410_serial0、s3c2410_serial1、s3c2410_serial2,我们可以修改mdev.conf文件,使mdev在/dev目录下对应生成ttySAC0,
点击(此处)折叠或打开
- # system all-writable devices
- full 0:0 0666
- null 0:0 0666
- ptmx 0:0 0666
- random 0:0 0666
- tty 0:0 0666
- zero 0:0 0666
- # console devices
- tty[0-9]* 0:5 0660
- vc/[0-9]* 0:5 0660
- # serial port devices
- s3c2410_serial0 0:5 0666 =ttySAC0
- s3c2410_serial1 0:5 0666 =ttySAC1
- s3c2410_serial2 0:5 0666 =ttySAC2
- s3c2410_serial3 0:5 0666 =ttySAC3
- # loop devices
- loop[0-9]* 0:0 0660 =loop/
- # i2c devices
- i2c-0 0:0 0666 =i2c/0
- i2c-1 0:0 0666 =i2c/1
- # frame buffer devices
- fb[0-9] 0:0 0666
- # input devices
- mice 0:0 0660 =input/
- mouse.* 0:0 0660 =input/
- event.* 0:0 0660 =input/
- ts.* 0:0 0660 =input/
- # rtc devices
- rtc0 0:0 0644 >rtc
- rtc[1-9] 0:0 0644
- # misc devices
- mmcblk0p1 0:0 0600 =sdcard */etc/rc.d/init.d/sd
- sda1 0:0 0600 =udisk * /etc/rc.d/init.d/udisk
重要的一点忘写了,希望没有误导之前看这篇文章的网友。现补充如下:
由于mdev是通过init进程来启动的,在使用mdev构造/dev目录之前,init进程至少要用到两个设备文件/dev/console、/dev/null,所以要建立这两个设备文件。
#
#
#
#
构建其他目录
#
到此,我们的根文件系统构建完毕,/home/nfs/rootfs目录下就是我们的根文件系统。目标板可以把它通过作为网络根文件系统,通过nfs直接启动。也可以把它制作为映像文件烧写到目标板的Flash启动。