Linux on QEMU (Arm-based)
This guide provides a step-by-step approach to running a Linux distribution on QEMU for Arm-based architectures. QEMU is a powerful open-source emulator that allows you to run operating systems for different architectures on your host machine.
We will use QEMU source code to build and configure a virtual machine that runs an Arm-based Linux distribution. We will only need three things to get started:
- QEMU source code
- Linux kernel source code
- A root filesystem (rootfs) for Arm
Linux Kernel Source Code
You can download the Linux kernel source code from the official repository:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
After that, navigate to the Linux source directory and build the kernel for the Arm architecture:
make ARCH=arm64 LLVM=1 defconfig
make ARCH=arm64 LLVM=1 -j$(nproc)
We don't use cross-compilation here to avoid complexity, so ensure you have clang, lld, and llvm installed on your system.
After building, the kernel image will be located at arch/arm64/boot/Image.
QEMU Source Code
Next, clone the QEMU source code from its official repository:
git clone https://git.qemu.org/git/qemu.git
Navigate to the QEMU source directory and configure it for Arm architecture:
cd qemu
./configure enable-debug
make -j$(nproc)
This will build QEMU with support for Arm-based virtual machines. You can find the QEMU binary at build/qemu-system-aarch64.
Root Filesystem (rootfs)
You can create a simple root filesystem using BusyBox. But, we use Alpine Linux for this guide. Download the Alpine Linux rootfs for Arm64:
# Download Alpine Linux minirootfs for ARM64
wget https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/aarch64/alpine-minirootfs-3.19.0-aarch64.tar.gz
# Extract it
mkdir alpine-rootfs
cd alpine-rootfs
tar xzf ../alpine-minirootfs-3.19.0-aarch64.tar.gz
# Create init script
cat > init << 'EOF'
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
echo "========================================"
echo "Booted Alpine Linux ARM64 successfully!"
echo "========================================"
exec /bin/sh
EOF
chmod +x init
# Package it
find . | cpio -o -H newc | gzip > ../alpine-arm64.cpio.gz
Running QEMU with the Linux Kernel and rootfs
Now that we have the kernel and root filesystem ready, we can run QEMU with the following command:
./build/qemu-system-aarch64 \
-machine virt \ # Use the 'virt' machine type
-cpu cortex-a57 \ # Specify the CPU type
-m 1024 \ # Allocate 1GB of RAM
-kernel ../linux/arch/arm64/boot/Image \ # Path to the kernel image
-initrd ../alpine-arm64.cpio.gz \ # Path to the root filesystem
-nographic \ # Disable graphical output
-append "console=ttyAMA0 root=/dev/ram rw" # Kernel command line arguments
If you need networking support, you can add the following options to the QEMU command:
-netdev user,id=net0 \
-device virtio-net-pci,netdev=net0
This will set up user-mode networking for the virtual machine.
Conclusion
You should now see the Alpine Linux booting up in the QEMU terminal. You can interact with the shell and explore the Arm-based Linux environment. This setup provides a great way to experiment with Linux on Arm architecture without needing physical hardware. Enjoy your virtualized Linux experience!