QEMU is an open source emulator that can emulate operating systems from all architectures, including ARM, the architecture of the Raspberry Pi. You can even emulate it on an x86 PC, but it will be slower than on a Raspberry Pi itself since the code is being converted from ARM code to x86 code through QEMU in order to run on the PC. However, it is still nice for trying some Raspberry Pi software and the OS out and even better, you can get a feel of Raspbian and other Raspberry Pi OSes before buying the device itself.
DISCLAIMER: This only works with ARMv6 Pi OSes and only Linux ones. So this won’t work on ARMv7 Linux distros such as Ubuntu MATE and Server, or non-Linux OSes such as RiscOS. While there is a raspi2 machine for QEMU that can run ARMv7 OSes, this machine is still in early development and things such as mouse, keyboard, and internet do not yet work on it, so I will be using an ARMv6 generic machine instead.
First of all, open up a terminal and create a folder for the virtual machine:
mkdir rpi-vm && cd rpi-vm
Next, let’s download the QEMU kernel adapted for Raspberry Pi images
git clone https://github.com/dhruvvyas90/qemu-rpi-kernel.git
Now we need to extract our desired image to the folder. In my case it will be Raspbian Buster Lite, downloadable from here. You can run any Linux ARMv6 OS on it though, provided you use the right kernel in the folder which you can experiment with.
By default, the OS images are very small and only really contain space for the operating system itself. So, let’s add 4GB of space to the image with the following command:
dd if=/dev/zero bs=1M count=4096 >> 2020-08-20-raspios-buster-armhf-lite.img
2020-08-20-raspios-buster-armhf-lite.img with whatever your image is called.
We may have added space to the image, but the partitions of the image itself remain the same. So, mount the image as a loopback device with the following command:
sudo losetup -f -P --show 2020-08-20-raspios-buster-armhf-lite.img
gparted /dev/loopX or install the
gparted package first if you do not have it installed. Right click on the ext4 partition and expand it to all of the remaining space. Click apply and then close.
Because this kernel is adapted for a virtual machine board, and not a Pi, we must change the fstab so the OS runs well with the kernel. Let’s mount the ext4 root partition with the following command:
sudo mount -o rw /dev/loopXp2 /mnt
Now, let’s edit the fstab file
sudo nano /mnt/etc/fstab
Replace all mentions of
sda and save. For the image to be compatible with the QEMU VM and kernel, we must also edit another file. Run:
sudo nano /etc/ld.so.preload
Comment out the line and save the file. Then unmount with the following commands:
sudo umount /mnt
sudo losetup -d /dev/loopX
Now, run the VM with the following command:
qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -kernel qemu-rpi-kernel/kernel-qemu-4.19.50-buster -hda 2020-08-20-raspios-buster-armhf-lite.img -append "dwc_otg.lpm_enable=0 root=/dev/sda2 console=tty1 rootfstype=ext4 elevator=deadline rootwait" -dtb qemu-rpi-kernel/versatile-pb-buster.dtb -no-reboot -serial stdio
Of course, if you are running an OS other than Raspbian Buster Lite, you will have to change the image. If you are running an older OS, you may also have to use an older kernel which you can find in the qemu-rpi-kernel folder.
The output should look a little like this:
In my case, I chose to install the LXDE desktop. You can also install a desktop environment if you like, see this for instructions on how to do this with Raspbian Lite.
Here is my setup:
Of course, if running this on an x86 host, it will be slow since QEMU has to translate ARM code to x86 and also because the hardware being emulated itself is slow too. If running on an ARM host with KVM enabled in kernel, it may be faster, but multitasking in the virtual OS and memory intense programs will either way will be a struggle. It’s a nice thing to play around with though, and you can try it with any ARMv6 Pi Linux OS you want. Enjoy!