它整合了许多Linux上常用的工具和命令(utilities), 如rm, ls, gzip, tftp等。对于这些工具和命令,busybox中的实现可能不是最全的,但却是最常用的,因此它的特点就是短小精悍,特别适合对尺寸很敏感的嵌入式系统。
参考: http://www.tldp.org/HOWTO/Bootdisk-HOWTO/buildroot.html
busybox有两个作用:
-
基于busybox构建rootfs
-
编译生成Linux上常用的工具和命令
toolchain:gcc-linaro-5.4.1-2017.01-x86_64_aarch64-linux-gnu
1. 下载busybox
进官网,选择 BusyBox 1.31.1下载
解压:tar -vxjf busybox-1.31.1.tar.bz2
2. 配置
2.1 使用默认配置
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
-
defconfig,缺省配置,也就是默认配置选项。
-
allyesconfig,全选配置,也就是选中 busybox 的所有功能。
-
allnoconfig,最小配置。
2.2 定制
执行:make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
默认配置即可
3. build
3.1 创建一个文件夹用来存放roofs
cd ~/tools
mkdir rootfs
3.2 make
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- install CONFIG_PREFIX=/home/wangbaoli/tools/rootfs
CONFIG_PREFIX=/home/wangbaoli/tools/rootfs用来指定安装文件夹
编译完成后,工具和命令被安装到~/tools/rootfs
4. 添加lib库
4.1 lib
lib文件夹中包含*.so *.a库,理论上我们应该copy gcc-toolchain下的lib库,并且根据需要做一定的删减,否者的话rootfs体积会太大。
gcc-toolchain下的lib库:/usr/local/gcc-linaro-5.4.1-2017.01-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/
但是,这里为了节省做裁剪的时间,我直接复制已有rootfs的lib库。
1)mkdir lib
2)cp ~/repo/rootfs/buildroot-2019.02.5/output/target/lib/* ./lib
注:~/repo/rootfs/buildroot-2019.02.5/output/target 是buildroot默认的rootfs存放路径
3)创建lib64到lib的软连接
ln -s lib lib64
4.2 usr/lib
usr/lib文件夹中包含*.so *.a库,理论上我们应该copy gcc-toolchain下的usr/lib库,并且根据需要做一定的删减,否者的话rootfs体积会太大。
gcc-toolchain下的usr/lib库:/usr/local/gcc-linaro-5.4.1-2017.01-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/usr/lib
但是,这里为了节省做裁剪的时间,我直接复制已有rootfs的usr/lib库。
1)cd usr && mkdir lib
2)cp ~/repo/rootfs/buildroot-2019.02.5/output/target/usr/lib/* ./lib
3)ln -s lib lib64
5. 添加init和其他文件夹
5.1 执行:mkdir dev proc mnt sys tmp root
5.2 添加init
如果通过bootloader传入命令行参数init=xxx(通常是init=linuxrc),那么系统挂载文件系统后运行linuxrc。
如果存在文件/init,那么系统挂载文件系统后运行/init,即内核启动时会将/init作为第一个用户进程启动。
在rootfs下,新建init,添加:
#!/bin/sh
# devtmpfs does not get automounted for initramfs
/bin/mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
exec /sbin/init "[email protected]"
然后执行:chmod +x init
6. 完善
首先:mkdir etc && mkdir etc/init.d
在kernel挂载根文件系统后,运行的第一个程序是根目录下的linuxrc或init( 如果bootargs 设置 init=/linuxrc则运行linuxrc),实际是一个指向/bin/busybox的链接, 也就是说系统起来后运行的第一个程序是busybox本身。
linux先执行 /etc/inittab, 然后调用/etc/init.d/rcS, 最后是执行/etc/profile。
6.1 创建 /etc/init.d/rcS
开机启动脚本
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH runlevel
/bin/hostname megvii
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
然后:chmod +x etc/init.d/rcS
6.2 创建 /etc/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
fstab 在 Linux 开机以后自动配置哪些需要自动挂载的分区。
6.3 创建 /etc/inittab
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
6.4 创建/etc/profile
USER="`id -un`"
LOGNAME=$USER
HOSTNAME=`/bin/hostname`
HOME=/root
PS1="[[email protected]$HOSTNAME \W]\# "
PATH=$PATH
export USER LOGNAME HOSTNAME HOME PS1 PATH PATH LD_LIBRARY_PATH
此文件涉及系统的环境,即环境变量相关。这里修改会对所有用户起作用。
用户登录或切换(即Login shell 启动)时都有一个专用的运行环境,但首先执行 /etc/profile 。
在 /etc/profile 文件中设置的变量是全局变量。而 .bashrc文件(在用户的家目录下)则只对当前用户有用。
6.5最终目录
7. 打包
可以将rootfs打包压缩成各种格式,我打包成rootfs.cpio.gz
1) cd rootfs
2) 打包压缩成rootfs.cpio.gz
-
find ./* | cpio -H newc -o > rootfs.cpio
-
gzip rootfs.cpio
8. 测试
测试该rootfs.cpio.gz
boot kernel,出现如下错误,我们逐个来解决:
8.1 VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
[ 2.086084] VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
[ 2.086155] Please append a correct "root=" boot option; here are the available partitions:
[ 2.086250] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
完成上述步骤5.2,添加init
8.2 can't run '/etc/init.d/rcS': No such file or directory
解决:完成上述步骤6
8.3 成功时的界面:
8.4 优化
1)去掉:Please press Enter to activate this console.
在/etc/inittab,将::askfirst:-/bin/sh改为::respawn:-/bin/sh
2)设置hostname
在/etc/init.d/rcS加入/bin/hostname yourname
3)设置user
在/etc/profile 设置USER=root
注:
1) 解压rootfs.cpio.gz
gunzip rootfs.cpio.gz
cpio -idmv <rootfs.cpio