Enabling AArch32 QEMU on AArch64 hardware
This post is an indirect continuation of my earlier entry on using chroot
and QEMU, and a rather bizarre issue that came up when trying to run a described steps on an Arm64 Linux machine (or more precisely a Linux VM running on M2 MacBook Pro). So, the developed automation worked simply fine when running on x86 GitHub runner, however I could not get QEMU to emulate 32-bits Arm binaries on the 64-bit Arm machine. Every time I tried to run QEMU I was getting an exec format
error, which is odd considering I am running 32-bit Arm binary under a QEMU compiled for a host architecture. This led me to the discovery of a Linux mechanism called binfmt
or more specifically binfmt_misc
.
In simple terms binfmt_misc
allows the OS to detect the type of the binary and invoke it with a correct interpreter (emulator). We can easily inspect registered formats with:
cat /proc/sys/fs/binfmt_misc
However, when I run this command on my Arm64 Linux VM, I can see a list of many different QEMU architectures, including RISC-V, but 32-bit Arm is nowhere to be seen. Weird! However, there is a simple explanation. In principle the Arm64 machine should be able to run 32-bit binaries, and that is what Linux and QEMU assume. However, not every hardware manufacturer decides to implement such support, with Apple being one of them. As a result, Linux VM tries to run AArch32 binaries natively causing it to crash. There is more discussion on this topic here.
Luckily, the fix is quite simple. We need to manually register Arm32 support with binfmt_misc
. This can be done by executing the following command as a root
(note: using sudo
do not work here, but there are ways to achieve that with sudo
- see here):
echo ':qemu-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:/usr/bin/qemu-arm-static:OCF' > /proc/sys/fs/binfmt_misc/register
That is all. Now 32-bit Arm binaries can be run on 64-bit machines, that do not support AArch32, using QEMU. And, one last thing, the magic numbers used to set up the format can be found here.