How to build QEMU emulator for ARMv8 architecture

Quick Emulator, best known as QEMU, is an open-source emulator suite that supports full system and user space emulation. The system emulator version of it — especially for the ARMv8 architecture — is a must have tool for tinkering with embedded software because it makes things a lot more accessible and practical.

Here I’m interested in building qemu-system-aarch64 for running on Linux since that is the most usual development environment for embedded systems. Although I’m building QEMU for ARMv8, the procedure to compile it for other architectures is the same — to build qemu-system-x86_64 you would need to change just a command line option parameter.

#TL;DR

$ sudo apt install git build-essential libglib2.0-dev libfdt-dev \
    libpixman-1-dev zlib1g-dev ninja-build
$ git clone 'https://gitlab.com/qemu-project/qemu.git'
$ cd qemu
$ git checkout tags/v7.0.0 -b any-branch-name
$ mkdir build_artifacts
$ cd build_artifacts
$ export QEMU_INSTALL_PATH=~/bin/qemu-upstream
$ ../configure \
    --target-list=aarch64-softmmu \
    --prefix="$QEMU_INSTALL_PATH"
$ make -j $(nproc)
$ mkdir -p "$QEMU_INSTALL_PATH"
$ make install

#Goals

  1. Build the latest qemu-system-aarch64 emulator for running on a Linux x86-64 host. (Also, the build should generate the other accompanying programs, configuration files and stuff that a vanilla QEMU needs to run properly.)

  2. Put QEMU in the user’s ~/bin folder, or something like that, because I might want to have different versions of it installed at the same time and, importantly, I don’t want it to interfere with my distro’s QEMU package installed from apt.

#Prerequisites

  1. A Linux box, since we’re building qemu-system-aarch64 in and for running on a Linux host.

  2. Having a compiler and a basic C build environment installed. On a Debian based distro like Ubuntu, that means having the build-essential package installed:

    $ sudo apt install build-essential
    

#Build steps

#1. Getting build dependencies

As a minimum, a QEMU build requires the following dependencies:

$ sudo apt install libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build

However, QEMU is large and can emulate lots of hardware devices. Depending on what you want to use it for, you may need to have additional build dependencies installed.

For example, if you wanted to actually reproduce audio playback by some guest OS running inside QEMU, in addition to specifying the appropriate parameter in the build command line (see further below), you would need to install alsa-lib:

$ sudo apt install libasound2-dev

If you tried to build without it, you would get an error like this:

../meson.build:1405:6: ERROR: Problem encountered: Audio driver "alsa" not available.

A full log can be found at /home/cesar/qemu/build_artifacts/meson-logs/meson-log.txt

ERROR: meson setup failed

Likewise, say you would like to have QEMU support displaying video output onto a window on your host OS — in this case, you’d need to install the libsdl2-dev apt package.

Nevertheless, the minimum requirements are the ones at the beginning of this subsection and they are sufficient for the things I’m currently interested in doing — which basically require just storage and network access.

#2. Downloading the source code

$ git clone 'https://gitlab.com/qemu-project/qemu.git'
$ cd qemu
$ git checkout tags/v7.0.0 -b any-branch-name

There’s an aspect worth noting here, an advice one might say: if any strange build problem happens, take a look at the actual version you’re trying to build. Sometimes you might be trying a build configuration that will actually break on upstream. That’s why I’m using a git tag and not the master branch. Nothing prevents you from building on the bleeding edge though and it might just work as well.

Also, you could get the source code by just downloading a tarball/zip and not using git:

$ wget 'https://download.qemu.org/qemu-7.0.0.tar.xz'
$ tar xf qemu-7.0.0.tar.xz
# Then cd into qemu-7.0.0/ directory

#3. The actual build

$ mkdir build_artifacts
$ cd build_artifacts
$ export QEMU_INSTALL_PATH=~/bin/qemu-upstream
$ ../configure \
    --target-list=aarch64-softmmu \
    --prefix="$QEMU_INSTALL_PATH"
$ make -j $(nproc)

The build_artifacts directory is just to not pollute the source tree with compilation artifacts — it’s not required.

The noteworthy thing here is the --target-list option from the configure script. This is the parameter that specifies what QEMU to build. As commented before, QEMU is a suite of emulators, and it’s organized in such a way that there’s one executable for each target CPU architecture it emulates. In this case I’m interested in emulating ARMv8 machines but, if it was the case, I could build QEMU for running 64 bits x86 machines by using the x86_64-softmmu target. If I wanted to build both, the configure script invocation would look like this:

$ ../configure \
    --target-list=aarch64-softmmu,x86_64-softmmu \
    --prefix="$QEMU_INSTALL_PATH"

To see a list of available target architectures run ../configure --help and look at the available --target-list options. You’ll see that aarch64-softmmu and x86_64-softmmu are included there.

Then, the make -j $(nproc) is the actual command that does the building. Here, I’m using that trick to run it using the maximum parallelism possible on the host machine.

#4. The installation

QEMU requires more than just the qemu-system-aarch64 executable to run — i.e., it’s not a single-binary-executable. To move it together with its required runtime dependencies one must do it properly.

Since QEMU uses the GNU build system, it has support for installing (Yeah, that make install…) Here, I’m installing it to ~/bin/qemu-upstream, so I set the target location right in the beginning of the build process (see bash’s QEMU_INSTALL_PATH environment variable in the previous subsection). After building, the installation process is just a matter of make install (without sudo).


That’s it — qemu-system-aarch64 will be in ~/bin/qemu-upstream/bin and you might just add the latter to your $PATH environment variable.

#References

https://wiki.qemu.org/Hosts/Linux

https://www.linuxfromscratch.org/blfs/view/svn/postlfs/qemu.html

https://qemu.readthedocs.io/en/latest/devel/build-system.html