它整合了许多Linux上常用的工具和命令(utilities), 如rm, ls, gzip, tftp等。对于这些工具和命令,busybox中的实现可能不是最全的,但却是最常用的,因此它的特点就是短小精悍,特别适合对尺寸很敏感的嵌入式系统。

 

官网:https://busybox.net/

参考: 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

基于busybox构建rootfs

默认配置即可

 

 

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

基于busybox构建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

基于busybox构建rootfs

注:~/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

基于busybox构建rootfs

 

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最终目录

基于busybox构建rootfs

 

 

7. 打包

可以将rootfs打包压缩成各种格式,我打包成rootfs.cpio.gz

1) cd rootfs

2) 打包压缩成rootfs.cpio.gz

  • find ./* | cpio -H newc -o > rootfs.cpio

  • gzip rootfs.cpio

基于busybox构建rootfs

 

 

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

基于busybox构建rootfs

解决:完成上述步骤6

 

8.3 成功时的界面:

基于busybox构建rootfs

 

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

基于busybox构建rootfs

 

 

注:

1) 解压rootfs.cpio.gz

gunzip rootfs.cpio.gz

cpio -idmv <rootfs.cpio

 

 

分类:

技术点:

相关文章: