1

Bit of a strange situation there. I compiled a static executable of BusyBox 1.32.1 for the ARM platform (32-bit) and strangely it runs without problems on both platforms. Look by yourself:

root@smallbuntu /m/n/b/i/n/rootfs# readelf -h bin/busybox-initrd
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x1f419
  Start of program headers:          52 (bytes into file)
  Start of section headers:          1482800 (bytes into file)
  Flags:                             0x5000002, Version5 EABI, <unknown>
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         6
  Size of section headers:           40 (bytes)
  Number of section headers:         27
  Section header string table index: 26
root@smallbuntu /m/n/b/i/n/rootfs# 

then:

root@smallbuntu /m/n/b/i/n/rootfs# bin/busybox-initrd ls
bin         home        media       proc        srv         var
boot        kobo        mnt         root        sys
dev         lib         modules     run         tmp
etc         lost+found  opt         sbin        usr
root@smallbuntu /m/n/b/i/n/rootfs# bin/busybox-initrd uname -a
Linux smallbuntu 5.8.0-50-generic #56-Ubuntu SMP Mon Apr 12 17:18:36 UTC 2021 armv7l GNU/Linux
root@smallbuntu /m/n/b/i/n/rootfs# 

uname -a seems to return armv7l by the busybox binary. Here's the normal output:

Linux smallbuntu 5.8.0-50-generic #56-Ubuntu SMP Mon Apr 12 17:18:36 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Any idea of what's going on?
Thanks!

3
  • 3
    The suggested duplicate is about Mono, but the answer addresses this scenario too (binfmt_misc and QEMU). Commented May 7, 2021 at 15:48
  • Interesting question, but this is more related to the architecture it's running on. Commented May 7, 2021 at 15:50
  • @NicolasMailloux, same thing though, that foreign arch file is being interpreted by something like /usr/libexec/qemu-binfmt/arm-binfmt-P as something has registered it for this kind of file (check in /proc/sys/fs/binfmt_misc) Commented May 7, 2021 at 15:53

1 Answer 1

6

If you look inside /proc/sys/fs/binfmt_misc, you’ll probably see a file named qemu-arm or something similar, with contents along the lines of

enabled
interpreter /usr/bin/qemu-arm-static
flags: OCF
offset 0
magic 7f454c4601010100000000000000000002002800
mask ffffffffffffff00fffffffffffffffffeffffff

This instructs the kernel to “interpret” binaries matching the given magic value using /usr/bin/qemu-arm-static. This allows it to use QEMU to emulate ARM CPUs (and fix up system calls to match the ARM ABI) and run ARM binaries transparently on any system where QEMU can emulate ARM CPUs, including your 64-bit x86 PC.

In your case, since the ARM binary is statically linked, no additional setup is required. Dynamically-linked binaries need their native libraries to be available too.

On Debian-based systems, including Ubuntu-based systems, this is set up by the qemu-user-static and binfmt-support packages: the qemu-user-static package registers the binfmt_misc configurations that QEMU can handle using update-binfmts, and the binfmt-support package ensures that the registered configurations are loaded into the kernel (binfmt_misc is a kernel module).

See also What types of executable files exist on Linux?, What kinds of executable formats do the files under /proc/sys/fs/binfmt_misc/ allow?, and How is Mono magical?

4
  • Well, you're right! That was a nice mistery solved! Thanks! Commented May 7, 2021 at 15:56
  • @Stéphane just a minor detail, qemu-user-static doesn’t need the qemu-arm file, it registers everything from its postint (and the configuration then ends up in /var/lib/binfmts). Commented May 7, 2021 at 16:14
  • 1
    @StephenKitt, but that's the /usr/share/binfmts/qemu-arm file that the postinst script imports Commented May 7, 2021 at 17:39
  • @Stéphane not in Debian 10, but I see that’s changed for Debian 11. In Debian 10 qemu-user-static’s postinst calls update-binfmt with the specs as command-line parameters, not in files. Commented May 7, 2021 at 21:02

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.