QEMU上运行BusyBox详解

BusyBox

前文“在QEMU环境中使用GDB调试Linux内核”和"Initramfs 原理和实践" 分别描述了怎么用qemu来运行一个编译好的内核,以及怎么指定initramfs,但都是简单的演示。其实轮子已经有人造出来了,BusyBox项目就是这样一个工具集,提供了非常多的常用Linux命令,并且支持多平台。BusyBox项目的官网介绍如下:

BusyBox: The Swiss Army Knife of Embedded Linux

BusyBox combines tiny versions of many common UNIX utilities into a single small executable. It provides replacements for most of the utilities you usually find in GNU fileutils, shellutils, etc. The utilities in BusyBox generally have fewer options than their full-featured GNU cousins; however, the options that are included provide the expected functionality and behave very much like their GNU counterparts. BusyBox provides a fairly complete environment for any small or embedded system.

我们可以把BusyBox作为一个用户空间运行在qemu启动的内核中,思路是把BusyBox打包成一个小型文件系统结构,并且归档到cpio文件中,作为系统启动的initramfs运行起来,这样我们就可以拥有一个类似Linux的操作界面和工具集。

编译内核,运行 qemu, 制作initramfs等过程可以参考前文,这里只着重介绍怎么把BusyBox打包成initramfs让Linux内核把它跑起来。

准备

统一下目录,之后的操作都会在$HOME/kernel/这个目录下进行,把环境变量TOP设置为这个目录

# TOP=$HOME/kernel/
# cd $TOP
# pwd
/root/kernel

下载和解压BusyBox

# wget https://busybox.net/downloads/busybox-1.27.2.tar.bz2
# tar -xf busybox-1.27.2.tar.bz2

Config BusyBox

# mkdir -pv ../obj/busybox-x86
mkdir: created directory ‘../obj’
mkdir: created directory ‘../obj/busybox-x86’
# make 0=../obj/busybox-x86 defconfig

0= 表示把build输出放在这个位置,这样就可以利用同一套源代码来build多个不同的configuration。

配置menuconfig

# make 0=../obj/busybox-x86 menuconfig

menuconfig需要完成如下2个配置

  • 开启静态编译, 避免链接shared libraries
  • 编译成x86 32位

1) 开启静态编译,在menuconfig界面,敲/, 搜索"static",可以看到在如下位置可以进行选项配置:

Busybox Settings --->
    Build Options --->
        [*] Build BusyBox as a static binary(no shared libs)

在"Build BusyBox as a static binary(no shared libs"选项上选Y。

2) 编译成x86 32位

在如下两个选项中输入对应的值:

(-m32 -march=i386) Additional CFLAGS
(-m32) Additional LDFLAGS

Build BusyBox

# cd ../obj/busybox-x86
# make -j2
# make install

制作initramfs文件

至此静态链接的BusyBox编译完成,可以将安装在_install目录下的文件和目录拎出来打包,按照initramfs要求的格式打包起来,打包的目标目录为新建的$TOP/initramfs/x86-busybox。

# mkdir -pv $TOP/initramfs/x86-busybox
mkdir: created directory ‘/initramfs’
mkdir: created directory ‘/initramfs/x86-busybox’
# cd $TOP/initramfs/x86-busybox
root@iZ8vb12um7qt3iuasi08caZ:/initramfs/x86-busybox# mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin}}
mkdir: created directory ‘bin’
mkdir: created directory ‘sbin’
mkdir: created directory ‘etc’
mkdir: created directory ‘proc’
mkdir: created directory ‘sys’
mkdir: created directory ‘usr’
mkdir: created directory ‘usr/bin’
mkdir: created directory ‘usr/sbin’
# cp -av $TOP/obj/busybox-x86/_install/* .

initramfs需要一个init程序,可以写一个简单的shell脚本作为init:

# cat init
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"
exec /bin/sh

加上执行权限

# chmod u+x init

将x86-busybox下面的内容打包归档成cpio文件,以供Linux内核做initramfs启动执行。

# find . -print0 | cpio --null -ov --format=newc | gzip -9 > $TOP/obj/initramfs-busybox-x86.cpio.gz

启动Linux

将 BusyBox cpio压缩文件作为initramfs启动Linux内核。

# cd $TOP
# qemu -kernel ./linux-3.18.6/arch/x86/boot/bzImage -initrd obj/initramfs-busybox-x86.cpio.gz -nographic -append "console=ttyS0"

启动后console打印启动信息,随后进入init程序指定的shell中。

完整的启动日志如下,里面能看到Linux内核在启动加载各个模块和驱动的过程:

Boot took 1.34 seconds

/bin/sh: can't access tty; job control turned off
/ # [ 1.678389] tsc: Refined TSC clocksource calibration: 2499.937 MHz
[ 1.760577] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/input3
[ 2.679684] Switched to clocksource tsc

参考

How to Build A Custom Linux Kernel For Qemu

猜你喜欢

转载自www.linuxidc.com/Linux/2019-03/157825.htm
今日推荐