And*_*kel 8 c linux arm cross-compiling
我正在使用Docker容器(thewtex/cross-compiler-linux-armv7)在系统上交叉编译一个简单的"Hello World"Linux用户空间C程序x86_64.目标系统是ARMv7嵌入式系统(特别是具有库存固件的Kobo Aura HD电子阅读器).
程序(hello_world.c)的源代码如下
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello World!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
出乎意料的是,我可以在主机系统上执行生成的可执行文件:
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!
Run Code Online (Sandbox Code Playgroud)
以及目标设备上
[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!
Run Code Online (Sandbox Code Playgroud)
这有什么解释吗?
作为参考,我使用以下命令集调用编译器
docker run thewtex/cross-compiler-linux-armv7 > ./dockcross.sh
chmod +x dockcross.sh
Run Code Online (Sandbox Code Playgroud)
由于某种原因,生成的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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
And*_*kel 17
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
Run Code Online (Sandbox Code Playgroud)
这允许在Linux上透明地执行静态链接的ARM可执行文件.感谢Mark Plotnick指出这个机制.