GrabDuck

用busybox制作根文件系统 - noted2011的专栏 - CSDN博客

:

内核版本:
Linux-2.6.34.10
交叉编译器版本:
arm-linux-gcc  4.4.3
操作系统平台:
Linux    Fedora 12
开发板平台:
飞凌  OKIII2440
使用的工具:
Busybox-1.19.2.tar.bz2
使用busybox定制一个很小的文件系统。

一、    准备制作
建立根目录,该目录就要我们要移植到目标板上的目录,对于嵌入式的文件系统,根目录下必要的目录包括bin,dev,etc,usr,lib,sbin。
cd /home/noted2011/rootfs
cd rootfs
用shell脚本创建根文件系统的目录结构
首先 touch build_fs.sh
然后进行编辑,用vim,键入以下内容:
#!/bin/sh
echo "------Create rootfs directons......"
mkdir rootfs
cd rootfs
echo "--------Create root,dev......"
mkdir root dev etc bin sbin mnt sys proc lib home tmp var usr
mkdir usr/sbin usr/bin usr/lib usr/modules
mkdir mnt/usb mnt/nfs mnt/etc mnt/etc/init.d
mkdir lib/modules
chmod 1777 tmp
cd ..
echo "-------make direction done---------"
二、    编译busybox
把Busybox-1.19.2.tar.bz2拷贝到home/rock/
下载
BusyBox下载地址:http://www.busybox.net/
解压
tar xjvf busy-1.19.2.tar.bz2
cd busybox-1.19.2
vi Makefile
首先修改 Makefile ,将以下两项改为
CROSS_COMPILE = arm-linux-
ARCH      = arm
配置busybox,修改以下选项(其他选项默认就可以了,或者根据需要再裁减一下):
make menuconfig
Busybox Settings  --->
Build Options  --->
[*] Build BusyBox as a static binary (no shared libs)

make
make CONFIG_PREFIX=/home/noted2011/rootfs/rtfs install

说明:编译BusyBox时,可能会出现以下错误。这些错误的原因是因为你使用的交叉编译器工具是基于比较老的linux内核制作的,有一些东西是在后面的 linux内核版本才有的。用交叉编译器工具arm-linux-gcc 4.4.3(在《搭建arm-linux-gcc交叉编译环境》里有介绍),编译BusyBox时基本上就没有问题了,包括下面的这些错误也都没有出现。
1.    inotifyd出错
交叉编译busybox-1.19.2时,出现以下错误:
CC      miscutils/inotifyd.o
miscutils/inotifyd.c:31:27: linux/inotify.h: No such file or directory
miscutils/inotifyd.c: In function `inotifyd_main':
miscutils/inotifyd.c:61: error: `IN_ALL_EVENTS' undeclared (first use in this function)
miscutils/inotifyd.c:61: error: (Each undeclared identifier is reported only once
miscutils/inotifyd.c:61: error: for each function it appears in.)
miscutils/inotifyd.c:129: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:139: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:140: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:140: error: dereferencing pointer to incomplete type
miscutils/inotifyd.c:143: error: invalid application of `sizeof' to incomplete type `inotify_event'
miscutils/inotifyd.c:143: error: dereferencing pointer to incomplete type
make[1]: *** [miscutils/inotifyd.o] Error 1
make: *** [miscutils] Error 2
网上说这是busybox的一个bug,解决方法:去掉对inotifyed的支持,具体步骤如下:
# make menuconfig
Miscellaneous Utilities  --->
[ ]inotifyd
还有另一个bug是taskset,也要将它去掉,不然编译时又会出错。
Miscellaneous Utilities  --->
[ ]taskset    
2.    未定义ARPHRD_INFINIBAND
错误信息如下:
networking/interface.c:818: error: 'ARPHRD_INFINIBAND' undeclared here (not in a function)
make[1]: *** [networking/interface.o] Error 1
make: *** [networking] Error 2
通过查看内核源代码目录中的“include/linux/ifarp.h”文件可知“ARPHRD_INFINIBAND”的值为“32”。然后修改“networking/interface.c”文件,在其中添加:
#define ARPHRD_INFINIBAND 32  /* InfiniBand */
make ARCH=arm CROSS_COMPIL=arm-linux- CONFIG_PREFIX=/home/rock/rootfs all install

三、    制作文件系统
在dev目录下,创建两个设备节点:
#mknod  console  c  5  1
#mknod  null  c  1  3
进入etc  目录,添加文件:
1.    拷贝Busybox-1.19.2/examples/bootfloopy/etc/*  到当前目录下。
# cp  -r  ../../busybox-1.19.2/examples/bootfloopy/etc/*  ./
包括的文件:fstab、init.d、inittab、profile
2.    拷贝/etc/passwd、/etc/group、/etc/shadow到当前目录下。
# cp  /etc/passwd  ./
# cp  /etc/group  ./
# cp  /etc/shadow  ./
把passwd文件中的第一行:root:x:0:0:root:/root:/bin/bash中的/bin/bash,改成/bin/ash,因为文件
系统的bin目录下没有bash这个命令,而是用ash代替bash,所以在用用户名密码登录的时候(如
telnet),会出现“cannot run /bin/bash: No such fileor directory”的错误。
3.    修改inittab文件:
内容如下:
console::sysinit:/etc/init.d/rcS
ttyS0::respawn:-/bin/sh
s3c2410_serial0::askfirst:-/bin/sh
::once:/usr/sbin/telnetd  -l  /bin/login
::ctrlaltdel:/bin/umount  -a  -r
4.    修改fstab文件,内容如下:
proc    /proc    proc    defaults    0    0
tmpfs   /tmp     tmpfs   defaults    0    0
sysfs    /sys     sysfs    defaults    0    0
tmpfs    /dev    tmpfs    defaults    0    0
var      /dev    tmpfs    defaults    0    0
5.    修改init.d/rcS文件,内容如下:
#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
runlevel=S
prevlevel=N
umask  022
export  PATH  runlevel  prevlevel
mount  -a
mkdir  /dev/pts
mount  -t  devpts  devpts  /dev/pts
#echo  /sbin/mdev  >  /proc/sys/kernel/hotplug
mdev  -s
mkdir  -p  /var/lock
/bin/hostname  -F  /etc/sysconfig/HOSTNAME
ifconfig eth0 192.168.0.15 up
/sbin/telnetd

说明:这里的ip地址根据自己的需求进行配置。
6.    修改profile文件,内容如下:
# Ash  profile
# vim:  syntax=sh
# No  core  files  by  default
#ulimit  -S  -c  0  >  /dev/null  2>&1
USER="`id  -un`"
LOGNAME=$USER
PS1='[\u@\h  \W]# '
PATH=$PATH
HOSTNAME=`/bin/hostname`
echo  " Processing  /etc/profile... "
echo  "Done"
export  USER  LOGNAME  PS1  PATH
7.    新建sysconfig文件夹,在里面新建HOSTNAME文件,内容为:OK2440

说明:以上操作都是在etc目录下进行的。

8.    拷贝库文件:
进入lib目录,拷贝交叉编译器的库文件到lib目录下
写一个cp.sh脚本
#!/bin/sh
cd /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib/
for file in libc libcrypt libdl libm libpthread libresolv libutil
do
cp $file-*.so /home/noted2011/rootfs/rtfs/lib/
cp -d $file.so.[*0-9] /home/noted2011/rootfs/rtfs/lib/
done
cp -d ld*.so* /home/noted2011/rootfs/rtfs/lib/由于交叉编译器的库文件比较多,体积较大,所以需要裁剪一下库文件,只保留常用的库文
件。
arm-linux-strip -s /home/noted2011/rootfs/rtfs/lib*
四、    制作调试工具strace
使用strace可以跟踪程序执行时系统调用的相关信息,因此它是一个功能非常强大的调试和分析诊断工具。由于Linux系统中并没有包含程序,所以需要自己移植,整个移植过程非常简单。
1. 从SourceForge上下载strace的代码,http://sourceforge.net/projects/strace/
2. 解压 tar xvjf strace-4.5.20.tar.bz2
3. 配置 ./configure --host=arm-linux CC=arm-linux-gcc LD=arm-linux-ld
4. 编译,直接敲make即可,不用选择“-static”链接选项
5. strip,arm-linux-strip ./strace
6.最后使用 file ./strace查看编译结果,编译好的strace程序只有200多K。
最后将strace拷贝到/home/noted2011/rootfs/rtfs /usr/sbin目录下,即可使用。
五、    制作文件系统镜像
找一个mkyaffs2image工具
cd  /home/noted2011/rootfs
./mkyaffs2image rootfs/ rootfs.yaffs
六、    可能出现的问题
1.    问题1
Freeing init memory: 148K

ramdisk_execute_command=/linuxrc
linuxrc used greatest stack depth: 6072 bytes left
Kernel panic - not syncing: Attempted to kill init!
Backtrace:
[<c003169c>] (dump_backtrace+0x0/0x114) from [<c02c0a84>] (dump_stack+0x18/0x1c)
r6:c03ae324 r5:c03c8ca4 r4:c03c8ca4
[<c02c0a6c>] (dump_stack+0x0/0x1c) from [<c02c0aec>] (panic+0x64/0x180)
[<c02c0a88>] (panic+0x0/0x180) from [<c0049f2c>] (do_exit+0x7c/0x6d4)
r3:cf82ba80 r2:cf82bc94 r1:cf82bc60 r0:c0360377
[<c0049eb0>] (do_exit+0x0/0x6d4) from [<c004a608>] (do_group_exit+0x84/0xb8)
[<c004a584>] (do_group_exit+0x0/0xb8) from [<c0058c04>] (get_signal_to_deliver+0x348/0x384)
r4:0830009f
[<c00588bc>] (get_signal_to_deliver+0x0/0x384) from [<c0030338>] (do_signal+0x70/0x600)
[<c00302c8>] (do_signal+0x0/0x600) from [<c00308e8>] (do_notify_resume+0x20/0x64)
[<c00308c8>] (do_notify_resume+0x0/0x64) from [<c002daf8>] (work_pending+0x24/0x28)
r4:beea9bf0
OK

搜索了网上的资料后,使用arm-linux-gcc 4.0.0以上的编译器编译内核时需要加上这个配置:

Kernel Features  --->
[*] Use the ARM EABI to compile the kernel                  
[*]   Allow old ABI binaries to run with this kernel (EXPERIMENTA)

重新编译内核后,加载到单板上执行,初始化成功。