QEMU for arm64

This page gives details of building and useing Qemu for Arm64. It is likely to become obsolete in Q1 or Q2 2014 once the debian package includes this functionality. But right now it's the fastest arm64 environment available to most people, so is useful.

Background

In October 2013 the arm64 (aarch64) qemu port became publicaly available. It is only a user-space emulation, so not applicable to all development tasks, but is fine for building software and is _much_ faster and easier to use than ARM's proprietary (free beer) Foundation Model.

This code is expected to be incorporated into QEMU v1.8 in Q1/Q2 2014. In the meantime you need to build from the development branch. This work was done by people at ?SuSe, so kudos to them.

Overview

Normally 'apt-get install qemu' takes care of all the details of this for you, but as this is too new to be in upstream qemu, never mind the Debian package, you currently (Oct 2013) get to deal with the details yourself. But it's not actually hard.

Essentially you build a static version of qemu for arm64, copy that into an arm64 chroot (tarball, filesystem, whatever), then configure binfmts in your main system (i.e so that the running kernel knows about it) to know which file to run to handle arm64 binaries.

Pre-built chroots

"Here's one I made earlier", to save you doing most of this if you just want to run stuff. You will still need to do the update-binfmts thing as that's not part of the chroot.

Building the code

Build from this branch:

git clone https://github.com/susematz/qemu/tree/aarch64-1.6 qemu-arm64
cd qemu-arm64
apt-get build-dep qemu
./configure --target-list=arm64-linux-user  --static --disable-werror

There is a bug in the makefiles, so this will fail unless you edit config-host.mak to add -lgpg-error (after configuring):

--- config-host.mak~    2013-10-30 16:09:57.440144183 +0000
+++ config-host.mak     2013-10-30 16:36:42.656104017 +0000
@@ -120,7 +120,7 @@
 LDFLAGS=-Wl,--warn-common -m64 -static -g 
 LIBTOOLFLAGS= -Wc,-fstack-protector-all
 LIBS+=-lrt -pthread -lgthread-2.0 -lglib-2.0 -lrt -lpcre    -liscsi
-LIBS_TOOLS+=-Wl,-z,relro -lssh2 -lgcrypt   -lvdeplug -luuid  -laio
+LIBS_TOOLS+=-Wl,-z,relro -lssh2 -lgcrypt   -lvdeplug -luuid  -laio -lgpg-error
 EXESUF=
 LIBS_QGA+=-lrt -pthread -lgthread-2.0 -lglib-2.0 -lrt -lpcre   
 POD2MAN=pod2man --utf8

(or fix the actual bug, or disable the tools part of the build, but I didn't see a rune for that)

That will produce:
qemu-arm64 (and qemu-arm64-binfmt) in arm64-linux-user

You can ignore qemu-arm64-binfmt which is a wrapper for falling back to host-arch binaries.
Copy qemu-arm64 into /usr/bin/qemu-arm64-static in the arm64 chroot you want to use.

Configuring binfmts-misc

If you have a chroot from above, or have built qemu and copied it into your own chroot, then you need this step to make it work.

Install binfmt-support and qemu

sudo apt-get install binfmt-support qemu

To use the arm64 static emulator you need to tell binfmts about which thing to run for this type of ELF binary. To do that put this file in /usr/share/binfmts/qemu-arm64 in your normal system (not the chroot)

package qemu-user-static
interpreter /usr/bin/qemu-arm64-static
flags: OC
offset 0
magic \x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7
mask \xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff

then run

sudo update-binfmts --import qemu-arm64

to register the arm64 qemu static binary (into /var/lib/binfmts).

Then configure the chroot as an schroot directory or tarball chroot and use it in the normal way. Assuming your chroot was created in /srv/chroots/chroot-arm64 saving this file as /etc/schroot/chroot.d/chroot-arm64, will do the trick:
Replace 'user' with your username

[chroot-arm64]
description=arm64 chroot
directory=/srv/chroots/chroot-arm64
type=directory
users=user
groups=user,sbuild
root-groups=user,sbuild

or for a tarball chroot:

[chroot-arm64]
description=arm64 chroot
file=/srv/chroots/chroot-arm64.tar.gz
type=file
users=user
groups=user,sbuild
root-groups=user,sbuild