Busybox编译、制作initramfs,并在QEMU中运行
一、下载链接
BusyBox
二、编译配置
1、make menuconfig
Settings --->[*] Build static binary (no shared libs)
2、make -j$(nproc))
... ...
drwxr-xr-x 2 root root 4096 8月 9 13:28 rootfs
-rw-r--r-- 1 root root 536870912 8月 9 13:29 rootfs.img
编译成功后会生成下面一些重要文件
3、make install
root@zh-vm:/home/WorkSpace/busybox-1.36.0# make install./_install//bin/arch -> busybox./_install//bin/ash -> busybox... ..../_install//usr/sbin/ubirsvol -> ../../bin/busybox./_install//usr/sbin/ubiupdatevol -> ../../bin/busybox./_install//usr/sbin/udhcpd -> ../../bin/busybox
--------------------------------------------------
You will probably need to make your busybox binary
setuid root to ensure all configured applets will
work properly.
--------------------------------------------------
编译成功后,会生成在 _install/ 文件夹中一些文件
root@zh-vm:/home/WorkSpace/busybox-1.36.0# cd _install/
root@zh-vm:/home/WorkSpace/busybox-1.36.0/_install# ls
bin linuxrc sbin usr
root@zh-vm:/home/WorkSpace/busybox-1.36.0/_install# cd bin/
root@zh-vm:/home/WorkSpace/busybox-1.36.0/_install/bin# ls
arch chmod df fatattr hostname linux32 mkdir mv ps run-parts stat uname
ash chown dmesg fdflush hush linux64 mknod netstat pwd scriptreplay stty usleep
base32 conspy dnsdomainname fgrep ionice ln mktemp nice reformime sed su vi
base64 cp dumpkmap fsync iostat login more pidof resume setarch sync watch
busybox cpio echo getopt ipcalc ls mount ping rev setpriv tar zcat
cat cttyhack ed grep kbd_mode lsattr mountpoint ping6 rm setserial touch
chattr date egrep gunzip kill lzop mpstat pipe_progress rmdir sh true
chgrp dd false gzip link makemime mt printenv rpm sleep umount
root@zh-vm:/home/WorkSpace/busybox-1.36.0/_install/bin# file busybox
busybox: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux),
statically linked, BuildID[sha1]=a413dec73919412ec918146dc6243d4abf14e703,
for GNU/Linux 3.2.0, stripped
三、制作initramfs
Initramfs(初始 RAM 文件系统):在 Linux 启动时,内核会先加载 initramfs,运行它的 init脚本(可能是这个脚本),然后再挂载真正的根文件系统。
root@zh-vm:/home/WorkSpace/busybox-1.36.0/_install# mkdir -p /home/WorkSpace/initramfs
root@zh-vm:/home/WorkSpace/busybox-1.36.0/_install# cp bin/busybox /home/WorkSpace/initramfs/
root@zh-vm:/home/WorkSpace/busybox-1.36.0/_install# cd /home/WorkSpace/initramfs/
root@zh-vm:/home/WorkSpace/initramfs# mkdir bin
root@zh-vm:/home/WorkSpace/initramfs# mv busybox bin/
root@zh-vm:/home/WorkSpace/initramfs# vim init
root@zh-vm:/home/WorkSpace/initramfs# cat init
#! /bin/busybox sh/bin/busybox mkdir -p /proc && /bin/busybox mount -t proc none /proc
/bin/busybox echo "Hello Linux!!!"export PS1='Zenus> '
/bin/busybox sh
-
mkdir -p /proc:创建 /proc 目录(-p 确保父目录存在,不会报错)。
-
mount -t proc none /proc:挂载 proc 虚拟文件系统到 /proc。
- -t proc:指定文件系统类型为 proc(内核提供的进程信息接口)。
- none:表示没有实际的存储设备(proc 是内核虚拟的)。
- /proc:挂载点。
mkdir -p /proc:创建 /proc 目录(-p 确保父目录存在,不会报错)。
mount -t proc none /proc:挂载 proc 虚拟文件系统到 /proc
&&:只有前一条命令成功(返回 0)才执行后面的命令。
作用:/proc 是 Linux 内核提供的虚拟文件系统,包含系统运行时的进程和内核信息(如 cpuinfo、meminfo)。许多工具(如 ps、top)依赖它,因此早期挂载是必要的。
- export PS1='Zenus> ';PS1 是 Shell 的提示符变量,控制命令行前的显示内容,这里设置为 Zenus>
Zenus>
作用:定制化 Shell 界面,方便识别当前环境。
root@zh-vm:/home/WorkSpace/initramfs# chmod +x init
root@zh-vm:/home/WorkSpace/initramfs# ll
drwxr-xr-x 2 root root 4096 8月 9 21:54 bin/
-rwxr-xr-x 1 root root 67 8月 9 21:58 init*root@zh-vm:/home/WorkSpace/initramfs# tree
.
├── bin
│ └── busybox
└── init1 directory, 2 files
root@zh-vm:/home/WorkSpace/initramfs# find . -print0 | cpio -ov --null --format=newc | gzip -9 > /home/WorkSpace/build/initramfs.img
.
./init
./initramfs.img
./bin
./bin/busybox
5078 块
这个命令是一个经典的 Linux initramfs 镜像构建命令,用于将当前目录下的所有文件打包成一个 gzip 压缩的 cpio 归档文件(通常用作 initramfs):
- find . -print0 → 递归获取当前目录所有文件(以 \0 分隔)
- cpio -ov --null --format=newc → 打包成 cpio 归档(newc 格式)
- gzip -9 → 用最高压缩级别进行 gzip 压缩
- /home/WorkSpace/build/initramfs.img → 输出到目标文件
root@zh-vm:/home/WorkSpace/initramfs# file initramfs.img
initramfs.img: gzip compressed data, max compression, from Unix, original size modulo 2^32 2599936
四、整体执行文件
整体脚本:
initramfs:cd /home/WorkSpace/initramfs && find . -print0 | cpio -ov --null --format=newc | gzip -9 > /home/WorkSpace/build/initramfs.imgcpimage:cp /home/WorkSpace/linux-5.14/arch/x86_64/boot/bzImage ./bzImagerun:qemu-system-x86_64 \-kernel bzImage \-initrd initramfs.img \-m 512 \-nographic \-append "earlyprintk=serial,ttyS0 console=ttyS0 nokaslr" \
执行:
root@zh-vm:/home/WorkSpace/build# make initramfs
cd /home/WorkSpace/initramfs && find . -print0 | cpio -ov --null --format=newc | gzip -9 > /home/WorkSpace/build/initramfs.img
.
./init
./initramfs.img
./bin
./bin/busybox
7617 块
root@zh-vm:/home/WorkSpace/build# make cpimage
cp /home/WorkSpace/linux-5.14/arch/x86_64/boot/bzImage ./bzImage
root@zh-vm:/home/WorkSpace/build# tree
.
├── bzImage
├── initramfs.img
└── Makefile0 directories, 3 files
root@zh-vm:/home/WorkSpace/build# make runDecompressing Linux... Parsing ELF... done.
Booting the kernel.
[ 0.000000] Linux version 5.14.0 (root@zh-vm) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #2 SMP 5
[ 0.000000] Command line: earlyprintk=serial,ttyS0 console=ttyS0 nokaslr
[ 0.000000] x86/fpu: x87 FPU will use FXSAVE
[ 0.000000] signal: max sigframe size: 1440
[ 0.000000] BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
... ...
[ 1.350199] Run /init as init process
[ 1.382946] busybox (68) used greatest stack depth: 14800 bytes left
Hello Linux!!!
sh: can't access tty; job control turned off
Zenus> [ 1.791674] tsc: Refined TSC clocksource calibration: 3792.816 MHz
[ 1.792176] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x6d57a9bbd17, max_idle_ns: 881590484949 ns
[ 1.792659] clocksource: Switched to clocksource tsc
[ 1.888941] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/input3Zenus>
Zenus>
ctrl+A,随后松开按X退出QEMU
Zenus> QEMU: Terminated
root@zh-vm:/home/WorkSpace/build#