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

15

我正在使用Docker容器(thewtex/cross-compiler-linux-armv7)在x86_64系统上进行ARMv7内嵌式系统(具体来说是带有原始固件的Kobo Aura HD电子阅读器)的简单"Hello World" Linux用户空间C程序交叉编译。

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

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Hello World!\n");
    return 0;
}

出乎意料的是,我可以在主机系统上执行生成的可执行文件:

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!

这个有解释吗?


为参考,我使用以下一组命令来调用编译器

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

由于某种原因生成的shell脚本有缺陷,我需要手动替换 /cross-compiler-base/cross-compiler-linux-armv7//:build/:build:z/dockcross.sh 中。现在我运行

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

file 命令返回关于生成的 hello 可执行文件的以下信息

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

7
可能有人为您配置了binfmt_misc,并设置了arm可执行文件以运行qemu。 - Mark Plotnick
谢谢,binfmt_misc确实是允许这种魔法的机制。我会在这个问题下发布一个答案。 - Andreas Stöckel
1个回答

31

Linux内核中有一种称为binfmt_misc的机制,可以将任意解释器与可执行文件关联起来。这种关联可以基于可执行文件开头的魔数序列,也可以基于其文件扩展名(例如,wine会自动为*.exe文件注册)。解释器通过写入/proc/sys/fs/binfmt_misc/ sysfs在内核中进行注册。

在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指出了这种机制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接