通过busybox构建最小根文件系统

通过busybox构建最小根文件系统

背景

busybox是一个经典的工具,用于构建根文件。一直没有空尝试,这次通过qemu仿真可以了。

因此,整理一下有关的流程,方便时候处理。

做法

下载busybox

在https://busybox.net/downloads/上下载源码,我这里使用的是busybox-1.32.0版本。

wget https://busybox.net/downloads/busybox-1.32.0.tar.bz2

解压busybox

tar -xf busybox-1.32.0.tar.bz2

编译busybox

先来到源码的路径中

cd busybox-1.32.0

配置arm-gcc

要求先有一条可以使用的gcc。

如果没有工具链,可以使用下面这一条:

sudo apt-get install -y gcc-arm-linux-gnueabi

$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

编译

MY_ARMGCC=arm-linux-gnueabi-
make ARCH=arm CROSS_COMPILE=${MY_ARMGC} defconfig
make ARCH=arm CROSS_COMPILE=${MY_ARMGC} -j40
make ARCH=arm CROSS_COMPILE=${MY_ARMGC} install

编译以后的结果在:_install目录中。

制作根文件系统

部署目录

拷贝文件
ROOTFS=你自己指定的一个路径
ARM_RUNTIME_LIB=/usr/arm-linux-gnueabi/

## busybox: 可执行程序、对应的库
cp -r _install/ $ROOTFS

## Arm gcc runtime:工具链运行库
cp -r ${ARM_RUNTIME_LIB}/lib $ROOTFS/lib/

找到你自己工具链的运行库,如果找不到,试着执行whereis

例如:

$ whereis arm-linux-gnueabi-gcc
arm-linux-gnueabi-gcc: /usr/bin/arm-linux-gnueabi-gcc /usr/share/man/man1/arm-linux-gnueabi-gcc.1.gz
$ whereis arm-linux-gnueabi-gcc | awk '{print$2}'
/usr/bin/arm-linux-gnueabi-gcc
创建驱动
mkdir $ROOTFS/dev
sudo mknod -m 666 $ROOTFS/dev/tty1 c 4 1
sudo mknod -m 666 $ROOTFS/dev/tty2 c 4 2
sudo mknod -m 666 $ROOTFS/dev/tty3 c 4 3
sudo mknod -m 666 $ROOTFS/dev/tty4 c 4 4
#sudo mknod -m 666 $ROOTFS/dev/tty5 c 4 5
#sudo mknod -m 666 $ROOTFS/dev/tty6 c 4 6
sudo mknod -m 666 $ROOTFS/dev/consloe c 5 1
sudo mknod -m 666 $ROOTFS/dev/null c 1 3

打包为ext3镜像

镜像的格式很多,看自己的busybox支持什么。这里以典型的ext3为例。

## 临时挂载目录
TMP_ROOTPATH=tmp_rootfs
## 输出镜像
OUTPUT_IMAGE=rootfs.ext3

## All image
### create 32 M image with ext3 format
dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
mkfs.ext3 rootfs.ext3
### add file to image
mkdir ${TMP_ROOTPATH}
sudo mount -t ext3 rootfs.ext3 ${TMP_ROOTPATH} -o loop
sudo cp -r ${ROOTFS}/* ${TMP_ROOTPATH}
sudo umount  ${TMP_ROOTPATH}

如果后续需要对这个文件系统进行修改,只需要:

1、挂载

## 临时挂载目录
TMP_ROOTPATH=tmp_rootfs
## 输出镜像
OUTPUT_IMAGE=rootfs.ext3

sudo mount -t ext3 rootfs.ext3 ${TMP_ROOTPATH} -o loop

2、再修改OUTPUT_IMAGE中的文件

3、最后sudo umount ${TMP_ROOTPATH}

## 临时挂载目录
TMP_ROOTPATH=tmp_rootfs
sudo umount  ${TMP_ROOTPATH}

所做的修改就会保存在OUTPUT_IMAGE

附录:傻瓜脚本

结合上述的操作,整合了一个脚本。

#!/bin/sh
# busybox版本
BUSYBOX=busybox-1.32.0
# 交叉编译用的gcc前缀
MY_ARMGCC=arm-linux-gnueabi-
# 对外暴露的根文件目录,用于拷贝
ROOTFS_BARE=rootfs
# 临时挂载目录,用于mount
TMP_ROOTPATH=tmp_rootfs
# 输出镜像
OUTPUT_IMAGE=rootfs.ext3

# 顶层目录,所有的结果都在这个目录下面
top=`pwd`

# 编译busybox
function make_busybox() {
    cd ${top}
    wget https://busybox.net/downloads/${BUSYBOX}.tar.bz2
    tar -xf ${BUSYBOX}.tar.bz2
    cd busybox-*
    make ARCH=arm CROSS_COMPILE=${MY_ARMGC} defconfig
    make ARCH=arm CROSS_COMPILE=${MY_ARMGC} -j40
    make ARCH=arm CROSS_COMPILE=${MY_ARMGC} install
}

# 制作rootfs
function make_rootfs_bare () {
    cd ${top}
    ## Busybox
    local ROOTFS=${top}/${ROOTFS_BARE}
    cp -r _install/ $ROOTFS
    ## Arm gcc runtime
    local ARM_RUNTIME_LIB=`whereis ${MY_ARMGCC}gcc | awk '{print$2}'`/lib
    cp -r ${ARM_RUNTIME_LIB} $ROOTFS/lib/
    ## device drivers
    mkdir $ROOTFS/dev
    sudo mknod -m 666 $ROOTFS/dev/tty1 c 4 1
    sudo mknod -m 666 $ROOTFS/dev/tty2 c 4 2
    sudo mknod -m 666 $ROOTFS/dev/tty3 c 4 3
    sudo mknod -m 666 $ROOTFS/dev/tty4 c 4 4
    #sudo mknod -m 666 $ROOTFS/dev/tty5 c 4 5
    #sudo mknod -m 666 $ROOTFS/dev/tty6 c 4 6
    sudo mknod -m 666 $ROOTFS/dev/consloe c 5 1
    sudo mknod -m 666 $ROOTFS/dev/null c 1 3
}

# 制作镜像
function make_rootfs_image () {
    cd ${top}
    ### create 32 M image with ext3 format
    dd if=/dev/zero of=${OUTPUT_IMAGE} bs=1M count=32
    mkfs.ext3 ${OUTPUT_IMAGE}
    ### add files to image
    mkdir ${TMP_ROOTPATH}
    sudo mount -t ext3 ${OUTPUT_IMAGE} ${TMP_ROOTPATH} -o loop
    sudo cp -r $ROOTFS/* ${TMP_ROOTPATH}
    sudo umount ${TMP_ROOTPATH}
}

function qemu_system_arm_with_rotofs_img ()
{
    ##############################################
    ## 仿真
    #cd $LINUX_PATH
    #qemu-system-arm -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd ../rootfs.ext3
    ## GUI-仿真
    #qemu-system-arm -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -append "root=/dev/mmcblk0 rw console=tty0" -sd ../rootfs.ext3
}

make_busybox
make_rootfs_bare
make_rootfs_image
# qemu_system_arm_with_rotofs_img
上一篇:读书笔记--start_kernel


下一篇:容器实现原理