A Quick'n'Dirty Set-up of an Aarch64 Ubuntu 14.04 VM with QEMU

Lately, I came up with the idea to do some development on Aarch64. However, I couldn't get my hands on real hardware easily so I started to look for alternatives (i.e., emulators). The ARMv8 Foundation Model seemed to be the trivial solution but I've heard that QEMU is somewhat faster so I gave it a try. My goal was to set up the VM as quick as possible: reuse whatever is already "out there" and rebuild only what's utterly necessary. In the end it turned out that it's quite easy to get such a VM working ... once you know what you need. To figure that out, well, that required some googling and emailing around. Below are my notes (I cleaned them up a bit and tried to make them somewhat coherent), so that others won't need to compile all these information again. I hope that someone will find it useful.

(Note: My host machine, where everything described below was done/tested on, is an x86_64 desktop box running a (more or less) fresh Ubuntu 14.04.1.)

Build your own QEMU/Aarch64

Okay, my goal was not to rebuild, and I failed at the very first step. For Aarch64, it's best to build QEMU from source. Fortunately, building QEMU is really simple:

sudo apt-get build-dep qemu # install the dependencies
git clone git://git.qemu.org/qemu.git # get the source (at the time of writing, HEAD was at revision 69f87f713069f1f70f86cb65883f7d43e3aa21de)
cd qemu
./configure --target-list=aarch64-softmmu --enable-virtfs # configure for aarch64 (virtfs only needed if you'd like to mount up a dir of the host in the guest OS)
make # build qemu (make install is not necessary)

That's it, QEMU is ready to run. The questions are "what" (images) and "how" (command line options)?

Create a clean Aarch64 Ubuntu Core 14.04.1 image

First, I wanted a well-prepared and well-maintained root filesystem. And the good news is that Ubuntu has 14.04 out for Aarch64 as well. So, it only takes a download from the official website, and either some manual work or the help of a useful script to turn the downloaded tarball into a QEMU-compatible image. The script I ended up using is attached to this blogpost.

wget http://cdimage.ubuntu.com/ubuntu-core/releases/14.04/release/ubuntu-core...
./arm64-prepare-image-qemu.sh ubuntu-core-14.04.1-core-arm64.tar.gz # the script will sudo!

(Note: The script creates a 32 GB file! See at the end of the post how to change that.)

Get your hands on suitable kernel & initrd (for those who are lazy to build their own)

Beside the root filesystem, I also needed the images of an already built kernel and an initrd. Again, Ubuntu has those, even if a bit hidden away: they can be taken from inside a QCOW2-format Ubuntu 14.04 cloud image. This needs a bit more steps than creating the rootfs image before but it's still not rocket science (and needs to be done only once).

Preparation steps:

sudo apt-get install qemu-utils # install tools required to deal with the QCOW2 format
wget http://cloud-images.ubuntu.com/releases/14.04/release/ubuntu-14.04-serve... # download the cloud image

Mount the cloud image:

sudo modprobe nbd max_part=63
sudo qemu-nbd -c /dev/nbd0 ubuntu-14.04-server-cloudimg-arm64-disk1.img
mkdir mnt
sudo mount /dev/nbd0p1 mnt

Copy out the kernel & initrd files from the cloud image to the file system of the host:

sudo cp mnt/boot/vmlinuz-3.13.0-32-generic .
sudo cp mnt/boot/initrd.img-3.13.0-32-generic .

(Note: Some chown-ing is needed here here, since the files are owned by root.)

Finally, clean up (unmount the image):

sudo umount mnt
sudo qemu-nbd -d /dev/nbd0
rmdir mnt

Run your brand new Aarch64 Ubuntu 14.04.1 system

QEMU and the images are all ready for use by now, so the only issue that remains is to get all the command line options right. Here is what worked for me the best:

./aarch64-softmmu/qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic -smp 1 -m 4096 \
	-global virtio-blk-device.scsi=off -device virtio-scsi-device,id=scsi \
	-drive file=../qemu-images/ubuntu-core-14.04.1-core-arm64.img,id=coreimg,cache=unsafe,if=none -device scsi-hd,drive=coreimg \
	-kernel ../qemu-images/vmlinuz-3.13.0-32-generic \
	-initrd ../qemu-images/initrd.img-3.13.0-32-generic \
	-netdev user,id=unet -device virtio-net-device,netdev=unet \
	--append "console=ttyAMA0 root=/dev/sda"

This will start up the system, so ... Enjoy!

Some notes/advices:

  • The first login prompt will already be lost somewhere amidst the startup log messages by the time they stop rolling. Just press enter to get a new one.
  • The initial password for root is root. (Don't forget to change it after the first login!)
  • The current command line sets up user mode networking for the VM. It has its limitations (e.g., no ping) but it should be fine for simple web access for the start.
  • Do apt-get update && apt-get upgrade at least at the first startup.
  • Don't forget to properly shut down your VM if you're done with it (shutdown -h now). Just killing the qemu process is as rude as plugging out the power cord from your PC! Once you see "reboot: System halted" on the console, you can switch to the QEMU monitor by pressing CTRL+A C and then type quit.


So, all the above is OK, so-so, but not exactly what you want. Then, you may want to:

  • change the size of the disk image holding the root fs: change the count=32768 argument of dd in the arm64-prepare-image-qemu script (specify size in MB).
  • change the memory allocated for the VM: change the -m 4096 command line parameter of qemu-system-aarch64 (specify size in MB).
  • replace the default user networking (slirp) with a more powerful networking setup: experiment with the -netdev command line options.
  • build your own kernel & initrd: good luck with that :)

Acknowledgements / Sources of information

I received a lot of help from Alex Bennée, for which I'm really thankful, and collected info/inspiration from the sources below:

rename to arm64-prepare-image-qemu.sh after download1.82 KB

anyuh (not verified) - 08/24/2014 - 05:12

i just wonder why dont you use cloud image (ubuntu-14.04-server-cloudimg-arm64-disk1.img) to install? why you have to create image from *.tar.gz

akos.kiss - 08/28/2014 - 08:44

Now, that you're asking, I wonder too. :) I must have been tempted by the fact that the core image was 14.04.1 already, so a little bit newer than the cloud image, and the very same version I'm using on my desktop box. (Not that upgrading the cloud image should be a big issue...)

So, the cloud image could also work. Are you up to give it a try and share the results here?

Anonymous (not verified) - 04/28/2015 - 08:12

how to set a network bridge. I am using "-net bridge,vlan=0,br=br0 " but geeting this issue :

failed to parse default acl file `/usr/local/etc/qemu/bridge.conf'
failed to launch bridge helper
qemu-system-aarch64: -net bridge,vlan=0,br=br0: Device 'bridge' could not be initialized

haji (not verified) - 04/28/2015 - 17:45

I really like your information and i want to like to join you.

kennedy (not verified) - 06/09/2015 - 09:41

hi, when I was run:

sudo qemu-nbd -c /dev/nbd0 ubuntu-14.04-server-cloudimg-arm64-disk1.img
nbd.c:nbd_init():L723: Failed to set NBD socket
nbd.c:nbd_receive_request():L857: read failed

best wishes!

kennedy (not verified) - 06/10/2015 - 08:29

I kill the qemu-nbd process, and rerun this command, it been sovled

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • No HTML tags allowed
  • Lines and paragraphs break automatically.

More information about formatting options

This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Fill in the blank