1.编译
make
make CONFIG_PREFIX=../../../rootfs install
写成脚本后
busyboxcfg:
make -C ${ROOT_DIR}/linux/${BUSYBOX_VER} menuconfig
busybox:
make -C ${ROOT_DIR}/linux/${BUSYBOX_VER} -j4
busyboxclean:
make -C ${ROOT_DIR}/linux/${BUSYBOX_VER} clean
busyinstall:
make -C ${ROOT_DIR}/linux/${BUSYBOX_VER} install
2.裁剪
make ARCH=arm menuconfig 注意ARCH要大写
根据需要进行配置
3.制作根文件系统
第一种:添加etc目录及基本配置文件
借助于busybox的examples。显然,选择第二种会容易的多,我们直接拷贝examples/bootfloopy/etc到install目录下。
#cp –a ../examples/bootfloppy/etc/ .
第二种:手工创建
STEP 1:构建目录结构
创建根文件系统目录,主要包括以下目录
/dev /etc /lib /usr /var /proc /tmp /home /root /mnt /bin /sbin /sys
#mkdir /home/rootfs
#cd /home/rootfs
#mkdir dev etc lib usr var proc tmp home root mnt sys
STEP 2: 使用busybox构建/bin /sbin linuxrc
进入busybox-1.16.1目录,执行
#make defconfig
#make menuconfig
Busybox Setting ----->
Build Options ----->
//1选择将busybox进行静态编译
[*]Build BusyBox as a static binary (no shared libs)
//2.指定交叉编译器为
(/usr/local/arm/4.3.2/bin/arm-linux-)Cross Compiler prefix
Installation Options ----->(选择生成的文件存放目录,也可以直接放在rootfs下就不用拷贝了)
//3.选择上Don’t use /usr
Busybox Library Tuning--->
[*]Username completion
[*]Fancy shell prompts
[*]Query cursor position from terminal
//4.编译出的busybox的shell命令解释器支持显示当前路径及主机信息
保存退出
#make
#make install
在busybox目录下会看见_install目录,里面有/bin /sbin linuxrc三个文件
将这三个目录或文件拷到第一步所建的rootfs文件夹下。
#cp bin/ sbin/ linuxrc /home/rootfs -ra
切记一定要带上-a的参数,因为bin目录里大部分都是链接,如果不带-a的参数,拷过去之后会做相应的复制,不再是链接的形式
STEP 3 构建etc目录:
1)进入根文件系统rootfs的etc目录,执行如下操作:
拷贝Busybox-1.16.1/examples/bootfloopy/etc/*到当前目录下
#cp –r busybox-1.16.1/examples/bootfloopy/etc/* rootfs/etc
修改inittab,
原始文件为:
1 ::sysinit:/etc/init.d/rcS
2 ::respawn:-/bin/sh
3 tty2::askfirst:-/bin/sh
4 ::ctrlaltdel:/bin/umount -a -r
修改后为:
---(1):开机免登陆,直接打开shell(前面数字为行号)
1 ::sysinit:/etc/init.d/rcS
2 #::respawn:-/bin/sh
3 #::respawn:-/bin/login
4 console::askfirst:-/bin/sh
5 #tty2::askfirst:-/bin/sh
6 ::ctrlaltdel:/bin/umount -a -r
---(2):开机需要登陆(前面数字为行号)
1 ::sysinit:/etc/init.d/rcS
2 #::respawn:-/bin/sh
3 ::respawn:-/bin/login
4 #console::askfirst:-/bin/sh
5 #tty2::askfirst:-/bin/sh
6 ::ctrlaltdel:/bin/umount -a -r
2)拷贝虚拟机上的/etc/passwd, /etc/group, /etc/shadow到rootfs/etc下
# cp /etc/passwd rootfs/etc
# cp /etc/group rootfs/etc
# cp /etc/shadow roofs/etc
对以下三个文件修改,只保存与root相关的项,根据具体情况内容会有所不同。
修改passwd为root:x:0:0:root:/root:/bin/sh,即只保存与root相关项,而且最后改成/bin/ash。
修改group为root:x:0:root
修改shadow为root:$1$x9yv1WlB$abJ2v9jOlOc9xW/y0QwPs.:14034:0:99999:7:::
登陆开发板时需输入用户名密码,同虚拟机相同
3)修改profile
PATH=/bin:/sbin:/usr/bin:/usr/sbin //可执行程序环境变量
export LD_LIBRARY_PATH=/lib:/usr/lib //动态链接库环境变量
/bin/hostname osee
USER="`id -un`"
LOGNAME=$USER
HOSTNAME='/bin/hostname'
PS1='[\u@\h \W]# ' //显示主机名、当前路径等信息:
4)修改etc/init.d/rc.S文件
/bin/mount -n -t ramfs ramfs /var
/bin/mount -n -t ramfs ramfs /tmp
/bin/mount -n -t sysfs none /sys
/bin/mount -n -t ramfs none /dev
/bin/mkdir /var/tmp
/bin/mkdir /var/modules
/bin/mkdir /var/run
/bin/mkdir /var/log
/bin/mkdir -p /dev/pts //telnet服务需要
/bin/mkdir -p /dev/shm //telnet服务需要
#echo /sbin/mdev > /proc/sys/kernel/hotplug//USB自动挂载需要
/sbin/mdev -s //启动mdev在/dev下自动创建设备文件节点
/bin/mount -a
#######配置网络################################
/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0
/sbin/ifconfig eth0 192.168.1.70
/sbin/ifconfig eth0 netmask 255.255.255.0
/sbin/route add default gw 192.168.1.1 eth0
/sbin/ifconfig eth1 192.168.1.71 netmask 255.255.255.0
/sbin/route add default gw 192.168.1.1 eth1
5)修改etc/fstab文件,增加以下文件
none /dev/pts devpts mode=0622 0 0
tmpfs /dev/shm tmpfs defaults 0 0
STEP 4 构建lib目录:
(~/at91/x-tools/arm-zch-linux-gnueabi/arm-zch-linux-gnueabi/sysroot/lib我的只是把这个目录下的SO文件复制就可以了)
1)#cd /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib 将以下动态库拷贝到rootfs/lib下
#cp *so* roofs/lib -a (必须加-a否则拷贝到的是链接)
2)#cd /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib
将以下动态库拷贝到rootfs/lib下
#cp ./libstdc++.so.* rootfs/lib -a
STEP 5 动态编译库文件:
进入Build Options时,不要选择Build Busybox as a static binary,其他所有操作步骤跟静态编译一样,你会发现这样建立的文件系统无法启动,终端上打印出如下消息:
Kernel panic-not synving:No init found. Try passing init=option to kernel.
为什么会出现这种问题呢?这就得回到两种编译方式的特点上来。静态编译时是将所用到的库文件一起编译了进去,而动态编译时是在需要时才调用相应的库。我们选择动态编译后,没有添加任何库文件就运行,显然是会出错的。那么如何查看busybox可执行文件里使用的库呢。Readelf这个工具提供 了解决办法。使用如下命令,参数d表示将文件中所有的动态部分予以显示。
# arm-uclibc-linux-readelf -d busybox
Dynamic section at offset 0xca014 contains 18 entries:
标记 类型 名称/值
0×00000001 (NEEDED) 共享库: [libm.so.0]
0×00000001 (NEEDED) 共享库: [libc.so.0]
0×0000000c (INIT) 0xbe24
0×0000000d (FINI) 0xb2054
0×00000004 (HASH) 0×80e8
0×00000005 (STRTAB) 0xa500
0×00000006 (SYMTAB) 0×8b70
0×0000000a (STRSZ) 3259 (bytes)
0×0000000b (SYMENT) 16 (bytes)
0×00000015 (DEBUG) 0×0
0×00000003 (PLTGOT) 0xda0cc
0×00000002 (PLTRELSZ) 3040 (bytes)
0×00000014 (PLTREL) REL
0×00000017 (JMPREL) 0xb244
0×00000011 (REL) 0xb1bc
0×00000012 (RELSZ) 136 (bytes)
0×00000013 (RELENT) 8 (bytes)
0×00000000 (NULL) 0×0
从上面的结果中,我们可以看到,busybox这个程序使用到了libm.so.0和libc.so.0两个库文件,实际上这是2个符号链接, 分别指向libc-0.9.28.so和libuClibc-0.9.28.so。将以上四个文件分别拷贝到lib目录下。按理说,这样应该就可以了,但 是仍然无法正常运行。显示的错误信息和刚刚没加库之前一样。可能的原因有2种:一是库文件没有添加全,二是库文件没有正确被加载。根据readelf显示 的结果应该不是第一种原因。那么到底为什么没被正确加载呢?原来库文件的加载,还需要一个共享库加载器。找到对应的文件ld-uClibc- 0.9.28.so和ld-uClibc.so.0添加到lib目录下后。运行正常。
参考文档:
http://blog.chinaunix.net/uid-26285146-id-3512798.html
http://blog.csdn.net/yzlworld/article/details/5717801
http://www.cnblogs.com/Charles-Zhang-Blog/p/3419301.html
https://www.ibm.com/developerworks/cn/linux/l-busybox/
http://blog.csdn.net/u014213012/article/details/51582826
http://blog.csdn.net/goalietech/article/details/17733817