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 ] [ > ] [ >> ]


Print

View all

Page updated April 28, 2013

Summary: How To compile with QEMU user.

Mike Frysinger
Author

Ned Ludd
Author

Robin H. Johnson
Author

Alex Tarkovsky
Author

Alexey Shvetsov
Author

Raúl Porcel
Author

Joshua Saddler
Editor

Donate to support our development efforts.

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