如何制作跨架构 chroot
如果您有一台 ARM 计算机,您会发现某些软件仅适用于 x86_64。一种可能的解决方案是拥有一个完整的 x86_64 虚拟机,但这会因为必须模拟整个系统而产生相当大的开销。幸运的是,有 QEMU 用户空间模拟,它仍然使用主机内核,因此开销较小。本指南将向您展示如何制作 chroot 并使用 qemu 和 binfmt_misc 启用透明的 x86_64 二进制文件执行。
先决条件
您应该熟悉 Linux 命令行。
本指南编写时假设您已将 Alpine 作为主安装,并将 Alpine 放入 chroot 中。
此外,显示的命令假定您具有 root 权限。根据需要使用 sudo/doas
(或先使用 su
)。
安装必要的软件
启用 Community 仓库 并安装您想要使用的架构的 qemu 用户模式二进制文件,在本例中为 x86_64 和 i386
# apk add qemu-x86_64 qemu-i386 qemu-openrc openrc
请注意,有 qemu-system-*
软件包,您不需要这些,因为它们用于完整的虚拟机模拟。
启用 qemu-binfmt
服务并启动它
qemu-binfmt 脚本是一个 OpenRC init 脚本,它在服务启动时注册 binfmt_misc 处理程序,并在服务停止时取消注册它们。将该服务添加到默认运行级别并立即启动它
# rc-update add qemu-binfmt default # rc-service qemu-binfmt start
创建 chroot 文件夹
为了简单起见,我们将只使用主机系统上指定的 apk 仓库。本指南假设 $CHROOT
环境变量保存您想要创建 chroot 的目录。创建 chroot 目录和 etc/apk
子目录(我们将 apk 仓库文件复制到其中)
# mkdir -p $CHROOT/etc/apk/
现在将主机的 apk 仓库复制到 chroot 文件夹中
# cp /etc/apk/repositories $CHROOT/etc/apk/
您还需要将 resolv.conf
文件复制到 chroot 中,以便它可以访问互联网
# cp /etc/resolv.conf $CHROOT/etc/
将 alpine-base
安装到 chroot 文件夹中
alpine-base 元软件包是拥有一个完全工作的 alpine 系统所需的全部。此处使用的 apk 调用比您可能习惯的调用有更多选项
# apk add -p $CHROOT --initdb -U --arch x86_64 --allow-untrusted alpine-base
以下是所有选项的作用
-p $CHROOT
:将安装的根目录设置为$CHROOT
而不是/
--initdb
:初始化一个新的软件包数据库。-U
:--cache-max-age 1
的别名。基本上意味着不要从缓存安装。--arch x86_64
:安装 x86_64 软件包而不是本机软件包。将其替换为您要模拟的任何架构(例如--arch x86
)。--allow-untrusted
:安装具有不受信任签名或没有签名的软件包。(这是必需的,因为不同架构的密钥与主机上的密钥不同。如果您有正确的密钥,您可以将它们复制到$CHROOT/etc/apk/keys/
目录并删除此标志)。
将虚拟文件系统挂载到 chroot 中
# mount -t proc proc $CHROOT/proc/ # mount -t sysfs sys $CHROOT/sys/ # mount -o bind /dev/ $CHROOT/dev/ # mount -o bind /dev/pts/ $CHROOT/dev/pts/ # mount -o bind /run $CHROOT/run/
激动人心的部分:进入 chroot
如果您已按照所有步骤操作,则此部分应该很顺利。chroot
调用使用 sh -l
的特殊命令作为登录 shell 运行并 source /etc/profile
# chroot $CHROOT/ sh -l
故障排除
如果您在尝试添加 alpine-base 时收到 ERROR: ${package_name}.post-install: script exited with error 127
,这通常意味着 qemu binfmt_misc 尚未正确设置。检查是否已安装 qemu-$arch
软件包,并查看 binfmt_misc 服务是否正在运行。记住在添加新架构后重启服务。
# rc-service qemu-binfmt restart
您还可以查看 /proc/sys/fs/binfmt_misc/
中是否有一个 qemu-$arch
条目。
使用 Netlink 的程序(例如 ip addr
)似乎无法正常工作,因为 qemu 没有正确模拟 Netlink 协议。
参考
- 使用 QEMU 和 binfmt_misc 在 Linux 中透明地运行来自任何架构的二进制文件(请参阅标题为
Emulating full ARM rootfs
的部分)