Gentoo Logo

[ << ] [ < ] [ Home ] [ > ] [ >> ]

5. Compiling with qemu user chroot

5.a. Usage

In order to take advantage of QEMU user mode we need to do a few things. First we need to merge the QEMU package with the right settings. That means building it with USE=static-user and setting QEMU_USER_TARGETS to include the targets we want to utilize.

Code Listing 1.1: Building QEMU

See the portage(5) man page for other ways of doing this.
# echo app-emulation/qemu static-user >> /etc/portage/package.use

Tweak the list here to include the target(s) you care about.
See the `emerge -pv qemu` output for the full list.
See the portage(5) man page for other ways of doing this than make.conf.
# echo 'QEMU_SOFTMMU_TARGETS="alpha arm i386 mips mips64 mips64el mipsel ppc ppc64 s390x sh4 sh4eb sparc sparc64 x86_64"' >> /etc/portage/make.conf
# echo 'QEMU_USER_TARGETS="alpha arm armeb i386 mips mipsel ppc ppc64 ppc64abi32 s390x sh4 sh4eb sparc sparc32plus sparc64"' >> /etc/portage/make.conf

Then install the package!
# emerge -1 app-emulation/qemu

Next we need to build the kernel module binfmt_misc. Add this to your kernel .config: CONFIG_BINFMT_MISC=m or CONFIG_BINFMT_MISC=y. If this module is not built already, then the devel host will require a reboot after the kernel update and modules_install.

Mount the binfmt_misc handler if it's not already, then we need to register our format with the kernel via the procfs.

Code Listing 1.2: binfmt_misc

# [ -d /proc/sys/fs/binfmt_misc ] || modprobe binfmt_misc
# [ -f /proc/sys/fs/binfmt_misc/register ] || mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
(Do not register a handler that matches the host machine)
# echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register
# 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:/qemu-wrapper:' > /proc/sys/fs/binfmt_misc/register
# echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
# echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
# echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
# echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
# echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
# echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/bin/qemu-sh4:' >/proc/sys/fs/binfmt_misc/register
# echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb:' >/proc/sys/fs/binfmt_misc/register
# echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register

Code Listing 1.3: Enter/Exit the chroot

(Download your desired stage tarball)
# wget http://arch-stageball
(Unpack the tarball)
# tar -xzvf arch-stageball
# cd arch-stageball
(Install the static qemu into the chroot)
# ROOT=$PWD/ emerge -K qemu
# mkdir -p usr/portage
(Mount the required directories)
# mount --bind /usr/portage usr/portage
# mount --bind /proc proc
# mount --bind /sys sys
# mount --bind /dev dev
# mount --bind /dev/pts dev/pts
(Chroot into the environment)
# chroot . /bin/busybox mdev -s
# chroot . /bin/bash --login
(Unmount stuff when not in use)
# umount usr/portage sys proc dev/pts dev

Sometimes we'll need to pass additional args to QEMU (cpu model), so we'll create a wrapper script that'll call QEMU with it.

Code Listing 1.4: qemu-wrapper

#include <string.h>
#include <unistd.h>

int main(int argc, char **argv, char **envp) {
	char *newargv[argc + 3];

	newargv[0] = argv[0];
	newargv[1] = "-cpu";
	newargv[2] = "cortex-a8";

	memcpy(&newargv[3], &argv[1], sizeof(*argv) * (argc - 1));
	newargv[argc + 2] = NULL;
	return execve("/usr/bin/qemu-arm", newargv, envp);

Compile the wrapper with gcc -static qemu-wrapper.c -O3 -s -o qemu-wrapper and copy into the chroot. Notice the first example arm entry in the binfmt_misc section uses this method.

[ << ] [ < ] [ Home ] [ > ] [ >> ]


View all

Page updated April 28, 2013

Summary: How To compile with QEMU user.

Mike Frysinger

Ned Ludd

Robin H. Johnson

Alex Tarkovsky

Alexey Shvetsov

Raúl Porcel

Joshua Saddler

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.