chroot 在交叉編譯環境中使用 qemu 是如何工作的?
為了能夠進行交叉編譯,有一個技巧,您可以將靜態 qemu 二進製文件複製到您的
<different-arch-root-to-be>/usr/bin
文件中,並且當您 chroot 到該文件系統中時,該文件系統具有非本機二進製文件,神奇的是二進製文件可以由主機 cpu 執行,uname -a
並且類似的聲明您在目標架構上。最終結果是您可以獲得簡單的交叉編譯。我可以想像一種可行的方式,但需要
chroot
注意qemu
。是這樣嗎?我似乎找不到任何關於它如何工作的文件。
Linux 有一種機制允許註冊外掛,以便核心在被指示執行文件時呼叫解釋器程序:binfmt_misc。稍微簡化一下,當一個執行檔被執行時,核心會讀取前幾個字節,然後是這樣的:
- 它是否以四個字節
\x7fELF
開頭,後跟一個看起來有效的 ELF 標頭?如果是這樣,請使用核心內部的ELF載入程序來載入程序並執行它。- 它是否以兩個字節
#!
(shebang)開頭?如果是這樣,請閱讀第一行,解析之後的內容#!
並執行,將路徑作為參數傳遞給執行檔。- 它是否以通過 binfmt_misc 機制註冊的魔法值之一開始?如果是,則執行註冊的解釋器。
要通過 Qemu 執行外部架構二進製文件,對應於每個受支持架構的 ELF 標頭的魔法值通過 binfmt_misc 機制註冊。您可以通過列出目錄來查看支持的內容
/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 是執行檔找到載入器所必需的。