Arch Linux / QEMU BPi emulation

Today I’m going to tell you, how to emulate the ARMv7 architecture on your x86 or x64 machine. This is an alternative to cross compiling as you are not limited to your linking libraries in your toolchain. In other words: You get an almost “native” Banana Pi environment on your host machine. Of course there is a downside of doing this: It is slow. Don’t expect performance miracles. If you want to compile much faster, you definitely should set up a cross compiling toolchain.

But still, let’s experiment with it!

The idea of the following method is called “architectural chroot” (also known as “chroot voodoo”). I found an interesting article, on which this blog post is based on.

We’re going to use QEMU as our emulator. At the moment the required package qemu-user-static seems to be outdated in AUR. If you want, you can use my modified PKGBUILD to build qemu-user-static or fix the PKGBUILD for yourself.

yaourt -S qemu-user-static

Image preparations for rootfs

We need an image of our Banana Pi and another folder to mount and chroot the rootfs of that image later. You can obtain the default image from the manufacturers site or extract it from your existing BPi installation by dd (disk dump) your SD card (replace /dev/mmcblk0 with your SD card reading device):

cd $HOME
mkdir chroot
sudo dd if=/dev/mmcblk0 of=dump_bpi.img

Keep in mind, that with your dd extraction you get two partitions (the boot partition and the rootfs partition). We want to mount the rootfs, therefore we have to figure out the binary offset within that image, where the rootfs begins:

fdisk -l dump_bpi.img
Disk dump_bpi.img: 29.7 GiB, 31914983424 bytes, 62333952 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x544cef89

Device        Boot  Start      End  Sectors  Size Id Type
dump_bpi.img1        2048   104447   102400   50M 83 Linux
dump_bpi.img2      104448 62332927 62228480 29.7G 83 Linux

Note that the sector size is 512 bytes and the second partition begins on sector 104448 in my example. So the mounting offset is calculated by 512 * 104448 = 53477376. From now on, we need to have higher privileges, so first get a root shell and then mount the image:

sudo -s
mount -o loop,offset=$((512 * 104448)) dump_bpi.img chroot/

Enter the chroot environment

To be able to interpret the ARM instructions we copy the qemu-user-static binary to our mounted rootfs. Also we copy the hosts resolv.conf for DNS resolving:

cd $HOME
cp /usr/bin/qemu-arm-static chroot/usr/bin
cp /etc/resolv.conf chroot/etc/resolv.conf

Register the qemu-user-static binary as an ARM interpreter in the kernel:

echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register

Bind the required devices and then chroot:

cd $HOME/chroot
mount -t proc /proc proc
mount -o bind /dev dev
mount -o bind /dev/pts dev/pts
mount -o bind /sys sys
chroot . /bin/bash

We check, if everything is working correctly:

uname -a
Linux machine 3.16.1-1-ARCH #1 SMP PREEMPT Thu Aug 14 07:40:19 CEST 2014 armv7l GNU/Linux

Great, we have a running chroot environment! Now we can do our work as if we were on the BPi directly. If you don’t want to work as root, you can use either su or sudo:

sudo -s -u USER
su - USER

Leave the chroot environment

To finish working, we do the following:

cd $HOME
umount chroot/{sys,proc,dev/pts,dev}
umount chroot

That’s it, you’re able to emulate your BPi setup on your main machine.
For simple benchmark purposes, I compiled a few packages on both, the Banana Pi and the Core i7-4700HQ host machine. Here are the results (format mm:ss, measured using time make):

Application Banana Pi Host machine
RetroArch 07:13 05:18
libretro-quicknes 01:10 01:09
pcsx_rearmed (platform: libretro) 08:31 06:56
libvdpau-sunxi 00:23 00:18
PocketSNES (standalone) 12:20 10:36

As you see, there is no big difference. If setting up an emulated environment justifies the effort, certainly depends on your needs. There are a lot of factors that may have an impact on the performance. It might be worth a try to build bigger projects within an architectural chroot.


Leave a Reply

Your email address will not be published. Required fields are marked *