技术知识库

使用 BusyBox 制作 ARM64 initramfs

使用 BusyBox 制作 ARM64 initramfs

摘要

本手册从 BusyBox 1.37.0 源码交叉编译静态 ARM64 用户空间,制作带控制终端的 /init,打包为 external rootfs-v2.cpio.gz,并与 Linux 5.0 Image 组合启动。

前置条件

  • 已完成 编译 Linux 5.0 ARM64 内核。
  • CONFIG_BLK_DEV_INITRD=y、CONFIG_RD_GZIP=y。
  • 已安装 wget、bzip2、cpio、gzip 和 ARM64 交叉工具链。

1. 下载并解压 BusyBox

cd /home/martin-zou/workspace

wget https://busybox.net/downloads/busybox-1.37.0.tar.bz2
ls -lh busybox-1.37.0.tar.bz2
file busybox-1.37.0.tar.bz2

tar -xjf busybox-1.37.0.tar.bz2
cd /home/martin-zou/workspace/busybox-1.37.0

2. 生成并修改配置

make ARCH=arm64 \
  CROSS_COMPILE=aarch64-linux-gnu- \
  defconfig

make ARCH=arm64 \
  CROSS_COMPILE=aarch64-linux-gnu- \
  menuconfig

在 Settings 中设置:

[*] Build static binary (no shared libs)
(aarch64-linux-gnu-) Cross compiler prefix

如果 menuconfig 在 GCC 15 下误报缺少 ncurses,先按 BusyBox 1.37 menuconfig 在 GCC 15 下误报缺少 ncurses 修复探针,再重新打开。

为兼容 ARM64 和主机新版 Linux UAPI,再次进入配置并关闭:

CONFIG_SHA1_HWACCEL
CONFIG_SHA256_HWACCEL
CONFIG_TC

也可以用 Vim 搜索并修改生成的配置:

vim .config

保存后让 Kconfig 补齐依赖:

make ARCH=arm64 \
  CROSS_COMPILE=aarch64-linux-gnu- \
  oldconfig

grep -E 'CONFIG_(STATIC|CROSS_COMPILER_PREFIX|SHA1_HWACCEL|SHA256_HWACCEL|TC)' \
  .config

预期关键结果:

CONFIG_STATIC=y
CONFIG_CROSS_COMPILER_PREFIX="aarch64-linux-gnu-"
# CONFIG_SHA1_HWACCEL is not set
# CONFIG_SHA256_HWACCEL is not set
# CONFIG_TC is not set

兼容性原因见 BusyBox 1.37 ARM64 编译遇到 SHA-NI 与 TC 兼容性错误。

3. 编译并安装目录树

make ARCH=arm64 \
  CROSS_COMPILE=aarch64-linux-gnu- \
  -j"$(nproc)"

echo "make_status=$?"
file busybox

make ARCH=arm64 \
  CROSS_COMPILE=aarch64-linux-gnu- \
  install

验证:

ls -lh _install/bin/busybox
file _install/bin/busybox
ls -l _install/bin/sh _install/linuxrc
du -sh _install

4. 创建最小根文件系统与 PID 1

mkdir -p _install/dev _install/proc _install/sys _install/tmp
chmod 1777 _install/tmp
vim _install/init

写入:

#!/bin/sh

export PATH=/sbin:/bin:/usr/sbin:/usr/bin

mount -t devtmpfs devtmpfs /dev
mount -t proc proc /proc
mount -t sysfs sysfs /sys

echo
echo "========================================"
echo " Linux 5.0 ARM64 + BusyBox 1.37 started"
echo "========================================"
echo

exec setsid cttyhack sh
chmod +x _install/init
ls -ld _install/{dev,proc,sys,tmp}
ls -l _install/init

setsid cttyhack 让 PID 1 shell 获得 /dev/ttyAMA0 控制终端,避免 can't access tty; job control turned off。

5. 打包并检查 external initramfs

cd /home/martin-zou/workspace/busybox-1.37.0/_install

find . -print0 |
  cpio --null -ov --format=newc --owner=0:0 |
  gzip -9 > ../rootfs-v2.cpio.gz

cd ..
ls -lh rootfs-v2.cpio.gz
gzip -t rootfs-v2.cpio.gz
echo "gzip_test=$?"

gzip -dc rootfs-v2.cpio.gz |
  cpio -it |
  grep -E '^(\.|init|bin/busybox|bin/sh|linuxrc)$'

6. QEMU 启动

qemu-system-aarch64 \
  -machine virt \
  -cpu cortex-a57 \
  -smp 2 \
  -m 1024 \
  -kernel /home/martin-zou/workspace/runninglinuxkernel_5.0/build/arm64/arch/arm64/boot/Image \
  -initrd /home/martin-zou/workspace/busybox-1.37.0/rootfs-v2.cpio.gz \
  -append "console=ttyAMA0 rdinit=/init loglevel=8" \
  -nographic

7. 虚拟机内验证

uname -a
cat /proc/cmdline
tty
echo $$
ps | head
mount
nproc
free -m

完成标准:架构为 aarch64,tty=/dev/ttyAMA0,shell PID 为 1,devtmpfs、proc、sysfs 均已挂载。

退出 QEMU:按 Ctrl-a,松开后按 x。

关联