基於busybox構建rootfs

它整合了許多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

默認配置即可

 

 

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 "$@"

然後執行: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="[$USER@$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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章