chroot 如何使用 qemu 进行交叉编译环境?

chroot 如何使用 qemu 进行交叉编译环境?

为了能够进行交叉编译,有一个技巧,您可以将静态 qemu 二进制文件复制到您的文件系统中<different-arch-root-to-be>/usr/bin,当您 chroot 到该文件系统时,该文件系统具有非本机二进制文件,神奇的是,这些二进制文件可以由主机 cpu 执行,并且uname -a类似的声明您位于目标架构上。最终结果是你可以得到非常简单的交叉编译。

我可以想象一种可行的方法,但需要chroot注意qemu

是这样吗?我似乎找不到任何有关其工作原理的文档。

答案1

Linux 有一种允许注册插件的机制,以便内核在被指示执行文件时调用解释器程序:binfmt_misc。简单一点,当执行一个可执行文件时,内核会读取前几个字节,如下所示:

  • 是否以四个字节开头\x7fELF,后跟一个看起来有效的 ELF 标头?如果是这样,请使用极低频内核中的 loader 来加载程序并执行它。
  • 是否以两个字节开头#!舍邦)?如果是这样,请读取第一行,解析后面的内容#!并执行该行,并将路径作为参数传递给可执行文件。
  • 它是否以通过 binfmt_misc 机制注册的魔术值之一开始?如果是,则执行注册的解释器。

要通过 Qemu 运行外部架构二进制文件,需要通过 binfmt_misc 机制注册与每个受支持架构的 ELF 标头相对应的魔法值。您可以通过列出目录/proc/sys/fs/binfmt_misc/(这是一个特殊的文件系统,代表内核中当前注册的 binfmt_misc 解释器集)来查看支持的内容。例如:

cat /proc/sys/fs/binfmt_misc/qemu-arm
enabled
interpreter /usr/bin/qemu-arm-static
flags: 
offset 0
magic 7f454c4601010100000000000000000002002800
mask ffffffffffffff00fffffffffffffffffeffffff

因此,如果可执行文件/somewhere/foo以指定的魔术字节开头,如果您运行/somewhere/foo arg1 arg2,内核将调用/usr/bin/qemu-arm-static /somewhere/foo arg1 arg2

此机制无需使用 chroot 即可工作,可执行文件可以位于任何位置。为了使动态可执行文件工作,chroot 很方便:动态可执行文件包含其加载程序的绝对路径,因此,如果您运行例如 ARM 可执行文件,它将期望加载程序位于/lib.如果加载程序实际上位于/different-arch-root-to-be,则可执行文件需要对该目录进行 chroot 才能找到加载程序。

相关内容