Embedded Handbook/General/Compiling with qemu user chroot

Cross compiling software with a QEMU user chroot. Cross compiling software with a QEMU user chroot.

Kernel
The host system kernel will need support for miscellaneous binary formats. This is achived via the binfmt_misc module. Add the  or   symbols to the host's kernel  file. If this module is not built already, then the development host will require a reboot after the kernel update and modules_install.

Package configuration
In order to take advantage of QEMU user mode a few steps are necessary. First the package must be emerged with the right settings. Specifically this means building with  and setting QEMU_USER_TARGETS to include the targets that will be utilized.

See for other ways of doing this:

Tweak the list here to include the necessary target(s). See the output of for the full list:

To build all targets:

Then install the package:

At this point it is wise to create a binary package for QEMU:

Register binary format handlers
Mount the binfmt_misc handler if it is not already mounted, then register the format with the kernel via the procfs:

Do not register a handler that matches the host machine (in this example, registers for x86 and AMD64 has been excluded since the host machine).

32-bit registers:

Add 64-bit registers:

Services
After this, make sure the binfmt service is (re-)started:

OpenRC
It may be wise for the services to be started by default on boot:

systemd
For the service, add files containing the desired handler registration strings under. For example, for and  systems:

With the files created in, systemd will now find them automatically at system boot time. See for more information.

Since the files were likely created just a few moments ago, it will be necessary to restart the service once to register the binary formats:

To confirm the service is running properly after restarting:

Setup chroot
Download the desired stage tarball:

Unpack the tarball:

Install the static qemu into the chroot:

Mount the required directories:

Chroot into the environment:

Keep QEMU from being altered within the chroot (if deleted or reinstalled within the chroot, breakage will occur):

Unmount the various file systems when they are no longer in use:

Sometimes we'll need to pass additional args to QEMU (CPU model), so we'll create a wrapper script (in C) that'll call QEMU with it:

Compile the wrapper with:

Then copy into the chroot. Notice the first example ARM entry in the binfmt_misc section uses this method.

Caveat
Currently qemu does not support pid-sandbox and network-sandbox.

This issue can be worked around by setting the FEATURES environment variable before each call to and other Portage tools in the chroot:

Alternatively, modify Portage's FEATURES variable within the chroot.