ARM Linux可执行文件神秘地在x86_64上运行

我正在使用Docker容器( thewtex/cross-compiler-linux-armv7 )在Fedora 23 x86_64系统上交叉编译一个简单的“Hello World”Linux用户空间C程序。 目标系统是ARMv7embedded式系统(特别是带库存固件的Kobo Aura HD电子阅读器)。

程序的源代码( hello_world.c )如下

 #include <stdio.h> int main(int argc, char *argv[]) { printf("Hello World!\n"); return 0; } 

我使用以下一组命令调用编译器

 docker run thewtex/cross-compiler-linux-armv7 > ./dockcross.sh chmod +x dockcross.sh 

出于某种原因,生成的shell脚本是错误的,我手动必须replace/cross-compiler-base/cross-compiler-linux-armv7//:build/:build:z/ 。 现在我跑了

 ./dockcross.sh arm-linux-gnueabihf-cc hello_world.c -static -o hello 

file返回有关生成的hello可执行file的以下信息

 hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=317a9ea164931f614b24e98dec743050e2d7f900, not stripped 

意外的是,我可以在主机系统上执行产生的可执行文件:

 andreas@andreas-pc:~/tmp/test$ uname -a && ./hello Linux andreas-pc 4.5.5-201.fc23.x86_64 #1 SMP Sat May 21 15:29:49 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux Hello World! 

以及在目标设备上

 [root@(none) onboard]# uname -a && ./hello Linux (none) 2.6.35.3-850-gbc67621+ #1038 PREEMPT Thu Apr 25 15:48:22 CST 2013 armv7l GNU/Linux Hello World! 

这有什么解释吗?

在Linux内核中有一个名为binfmt_misc的机制,它允许使用魔术字节序列或特定文件扩展名将任意解释器关联到可执行文件。 解释器使用/proc/sys/fs/binfmt_misc/文件系统接口进行注册。

在Fedora上, systemd-binfmt服务负责解释器注册。 它从/usr/lib/binfmt.d目录中读取一组配置文件,并对sysfs执行必要的写操作。 在上述问题的背景下,安装qemu模拟器套件将把相应的注册文件放在这个目录下。 在ARM体系结构的情况下,该文件被称为qemu-arm并具有以下内容:

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

这允许在Linux上透明地执行静态链接的ARM可执行文件。 感谢Mark Plotnick指出这个机制。