To be able to do cross compiling there's a trick where you copy a static qemu binary into your <different-arch-root-to-be>/usr/bin and when you chroot into that filesystem, which has non-native binaries, magically the binaries are executable by the host cpu, and uname -a and similar claim that you are on the target architecture. The net result is that you can get dead simple cross compiling.

I can imagine a way this might work, but it would require chroot to be qemu aware.

Is this the case? I can't seem to find any documentation as to how this works.


Linux has a mechanism that allows plug-ins to be registered so that the kernel calls an interpreter program when instructed to execute a file: binfmt_misc. Simplifying a bit, when an executable file is executed, the kernel reads the first few bytes and goes like this:

  • Does it start with the four bytes \x7fELF followed by a valid-looking ELF header? If so, use the ELF loader inside the kernel to load the program and execute it.
  • Does it start with the two bytes #! (shebang)? If so, read the first line, parse what's after the #! and execute that, passing the path to the executable as an argument.
  • Does it start with one of the magic values registered through the binfmt_misc mechanism? If so, execute the registered interpreter.

To run foreign-architecture binaries via Qemu, magic values corresponding to an ELF header with each supported architecture are registered through the binfmt_misc mechanism. You can see what is supported by listing the directory /proc/sys/fs/binfmt_misc/ (which is a special filesystem representing the current set of registered binfmt_misc interpreters in the kernel). For example:

cat /proc/sys/fs/binfmt_misc/qemu-arm
interpreter /usr/bin/qemu-arm-static
offset 0
magic 7f454c4601010100000000000000000002002800
mask ffffffffffffff00fffffffffffffffffeffffff

So if an executable /somewhere/foo starts with the specified magic bytes, if you run /somewhere/foo arg1 arg2, the kernel will call /usr/bin/qemu-arm-static /somewhere/foo arg1 arg2.

It is not necessary to use a chroot for this mechanism to work, the executable could be anywhere. A chroot is convenient in order for dynamic executables to work: dynamic executables contain an absolute path to their loader, so if you run e.g. an ARM excutable, it will expect a loader located in /lib. If the loader is in fact located in /different-arch-root-to-be, a chroot to that directory is necessary for the executable to find the loader.

| improve this answer | |
  • I'm really glad I asked! That's really useful information apart from this specific case. – Catskul Aug 20 '14 at 0:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.