Busybox for ARM on QEMU

本文介绍如何在QEMU上为ARM平台构建并测试BusyBox根文件系统。BusyBox通过将多个系统工具链接到单一二进制文件中实现精简的文件系统,非常适合嵌入式Linux设计。文中详细描述了配置、编译BusyBox的过程,并演示了如何使用QEMU进行测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Busybox for ARM on QEMU

Busybox is a solution for embedded Linux designs that need a compact filesystem: the trick is compiling and linking many system utilities into a single binary that behaves differently based on the name it was used to execute it. A working Linux root filesystem then consists in a small directory tree (/bin/sbin/usr/bin, …), a single executable binary in /bin/busybox, and many symbolic links to the Busybox binary (/bin/ls/bin/sh/sbin/ifconfig, …), and using a typical configuration it can be as small as 2MB (1MB if compressed).

Last time I compiled a Linux kernel and a minimal root filesystem containing just a “Hello World” program. Now we can build a reasonably working root filesystem and test it using QEMU. Note that, in order to follow this example, you need:

  • The CodeSourcery Linux toolchain
  • A Linux kernel image compiled for the Versatile platform, with EABI support (here is how I created mine)
  • QEMU ARM emulator (the package to install is qemu on Debian or qemu-kvm-extras on Ubuntu)
  • Developer’s libraries for ncurses (the package to install is libncurses5-dev) to compile the menu configuration

I downloaded version 1.16.0 of the Busybox source and extracted it. Inside the extracted directory I ran:

1
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- defconfig

A default configuration file is created. To change it to our needs:

1
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig

I checked the option to compile Busybox as a static executable, so that we don’t have to copy the dynamic libraries inside the root filesystem. The setting can be found in “Busybox Settings --> Build Options“. Then, the following command builds Busybox and creates a directory called_install containing the root filesystem tree:

1
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- install

We can now create a root filesystem image using the cpio tool, and in order to compact the filesystem even more, we can run gzip on it to create a compressed image:

1
2
3
4
$ cd _install
$ find . | cpio -o --format=newc > ../rootfs.img
$ cd ..
$ gzip -c rootfs.img > rootfs.img.gz

In my case, the compressed image size is about 1MB. To test Busybox, we can emulate an ARM platform with QEMU using the following command, assuming we copy the Linux kernel zImage in the current directory:

1
$ qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=/bin/sh"

The Linux kernel will boot, and the shell /bin/sh will be executed as specified by the boot parameter rdinit, showing the common “#” prompt. The shell can be used normally, for example you can run ls to find the same directory structure of the Busybox _install directory, but using commands like ps and mount we can see that not everything is in place: both programs complain abount the /proc directory. We can create and populate the /proc directory running these commands inside the QEMU emulated system prompt:

1
2
# mkdir /proc
# mount -t proc none /proc

After that, the ps and mount programs work fine. We can also note that the /dev directory is almost empty (the only exception being the console device). To populate it we need to mount also the/sys directory, so that we can use the mdev tool; run inside QEMU:

1
2
3
# mkdir /sys
# mount -t sysfs none /sys
# mdev -s

The /sys and /dev directory are now populated. To execute these steps every time, we can use/sbin/init functionality: this program is usually the first run by the Linux kernel, and its default behavior is to execute the initialization file with path /etc/init.d/rcS. In the host computer this time, in the folder where we compiled Busybox, we create the missing directories:

1
2
3
$ cd _install
$ mkdir proc sys dev etc etc/init.d
$ cd ..

Now we create a new _install/etc/init.d/rcS with the following content:

1
2
3
4
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s

Then set it as an executable file:

1
$ chmod +x _install/etc/init.d/rcS

We can then recreate an updated root filesystem compressed image as before, and run:

1
$ qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=/sbin/init"

The Linux kernel will boot again, but this time it is asking to press Enter, and when we do the usual console prompt will appear. The system directories are fully populated, meaning that the scriptrcS has been executed; other than that, /sbin/init also spawns shell terminals using getty.

In our example the Busybox filesystem is accessed using a ram disk, but it can also be read from a physical disk storage or loaded from the network using NFS protocol. Maybe another time I will describe in details how to run Busybox with NFS inside QEMU.


 h

### QEMU on Linux Installation, Configuration, and Usage Examples #### Installing Required Packages To set up QEMU along with necessary tools for managing virtual machines under the Linux environment such as Linux Mint, one should ensure that packages like `qemu-kvm`, `qemu-utils`, `seabios`, `ovmf`, `hugepages`, `cpu-checker`, and `bridge-utils` are installed[^1]. These utilities provide comprehensive support not only for running VMs but also configuring advanced features. For instance, installing these components can be achieved through package managers available within distributions: ```bash sudo apt update && sudo apt install qemu-kvm qemu-utils seabios ovmf hugepages cpu-checker bridge-utils -y ``` This command ensures all dependencies required by QEMU to function optimally in a Linux setting are present. #### Configuring Network Bridging Network bridging allows guests to connect directly to external networks via the host machine's network interface. Setting this up involves creating bridges using `bridge-utils`. A typical setup might involve editing `/etc/network/interfaces` or utilizing GUI-based management provided by distribution-specific software centers. An example of adding a bridge could look something like this when modifying interfaces file: ```plaintext auto br0 iface br0 inet dhcp bridge_ports eth0 bridge_stp off bridge_fd 0 bridge_maxwait 0 ``` After saving changes, restarting networking services applies new configurations effectively allowing guest systems access beyond just local environments. #### Running ARM-Based Guests Using Custom Built Images Creating custom-built images specifically tailored towards certain architectures demonstrates flexibility offered by platforms supporting emulation capabilities including QEMU. For building an ARM64 system from scratch combining BusyBox with minimalistic kernels showcases practical applications where lightweight yet functional setups become essential[^4]. Steps involved include compiling both kernel sources alongside statically linking binaries ensuring portability across different hosts without dependency issues arising due to dynamic libraries being absent during runtime operations. #### Example: Downloading Pre-Built QEMU Binaries When targeting specific hardware emulations outside mainstream offerings, obtaining precompiled versions may save time compared against compiling everything locally. An illustrative case would be downloading ESPRESSIF’s officially released builds designed explicitly around Xtensa architecture used primarily inside IoT devices manufactured by them[^3]: Downloading link: [E:\Espressif\dist\qemu-xtensa-softmmu-esp_develop_9.0.0_20240606-x86_64-w64-mingw32.tar.xz](https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-xtensa-softmmu-esp_develop_9.0.0_20240606-x86_64-w64-mingw32.tar.xz) Extract archive into desired directory before invoking emulator commands specifying paths accordingly. --related questions-- 1. How does one verify CPU compatibility prior to attempting KVM installations? 2. What modifications must occur within GRUB settings enabling nested virtualization support? 3. Can you elaborate further upon integrating SPICE protocol enhancing graphical performance while operating remote desktop sessions hosted over QEMU/KVM instances? 4. In what scenarios do users benefit most significantly deploying specialized firmware files SEABIOS versus OVMF during creation phases associated with UEFI-compliant guests?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值