如何制作跨架构 chroot

来自 Alpine Linux

如果您有一台 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 协议。

参考