为什么 Ubuntu 18.04 无法 chroot 进入 qemu 环境?

为什么 Ubuntu 18.04 无法 chroot 进入 qemu 环境?

我真的很难理解 chroot / qemu 在 Ubuntu 18.04 上无法工作的原因。更高版本可以工作(肯定是 19.10),但在 18.04 下我得到:

cannot run command '/bin/sh' No such file or directory.

我无法弄清楚到底是哪里出了问题。我可以调用 armhf 二进制文件而无需尝试 chroot,一切正常。我可以下载相同环境的 x86_64 等效版本并 chroot 到其中。但我无法 chroot 到 armhf 环境。

我的第一个猜测是这是 qemu 改变的东西。 Ubuntu 18.04 有 qemu 2.11然而Ubuntu 19.10 有 qemu 4.0。但我没有看到关于 chroot 的提及qemu 更改日志

我真的希望能够修复这个问题,而无需将设备完全升级到非 LTS 版本。如果我可以修补一个问题(即使“只是”内核),那么我很乐意这样做;但如果不知道到底出了什么问题,我只是在黑暗中摸索。


重现错误:

  • 安装qemu-user-static在 x86_64 Ubuntu 18.04 机器上。
    sudo apt-get install qemu-user-static
    
  • 下载 arm chroot 环境(例如:alpine mini 根文件系统 armhf
    wget http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/armhf/alpine-minirootfs-3.11.3-armhf.tar.gz
    
  • 提取并 chroot 到环境中
    mkdir my_env
    cd my_env
    tar -xf ../alpine-minirootfs-3.11.3-armhf.tar.gz
    chroot . /bin/sh
    

答案1

您错过了一步 - 您需要将qemu-arm-static可执行文件复制到 ARMhf 文件系统。

因此以下步骤应该可行:

wget http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/armhf/alpine-minirootfs-3.11.3-armhf.tar.gz
mkdir my_env
cd my_env
tar -xf ../alpine-minirootfs-3.11.3-armhf.tar.gz
sudo cp /usr/bin/qemu-arm-static ./usr/bin/ # this is essential step!
sudo chroot . /bin/sh

您将能够在这个 chroot 内运行命令,例如:

# arch
armv7l

笔记:

  1. 我已经在我的 Ubuntu 16.04 LTS 和 18.04 LTS 上测试过此方法。它基于我的其他回答
  2. 刚刚测试了即将推出的 20.04 LTS 的 chroot - 不需要复制qemu-arm-static

答案2

这种差异是由于内核中添加了一个新功能造成的:

http://manpages.ubuntu.com/manpages/eoan/man8/update-binfmts.8.html

--fix-binary yes, --fix-binary no
           Whether to open the interpreter binary immediately and always use the opened image.
           This allows the interpreter from the host to be used regardless of usage in chroots or
           different mount namespaces.  The default behaviour is no, meaning that the kernel
           should open the interpreter binary lazily when needed.  This option requires Linux 4.8
           or newer.  It cannot be used together with --detector, or with multiple binary formats
           that share the same magic number, since the kernel will only open a single interpreter
           binary which will then not be able to detect and execute the real interpreter from
           inside a chroot or from a different mount namespace.

由于此选项对于 chroot 正常工作是必需的,并且仅在内核 4.8 中引入(Ubuntu 18.04 只有 4.15),因此要使其按照我的问题所述工作,需要升级内核。

当然有另一个答案中提到的解决方法将 qemu-arm-statick 复制到 chroot 环境中。要使其正常工作,它在 chroot 环境中的位置必须与主机上的位置相同。例如:

qemu=$(which qemu-arm-static)
cp ${qemu} ${target}/${qemu}
chroot ${target} /bin/sh

我还没有测试过但是...

看起来您可以通过安装来修补此问题linux-image-generic-hwe-18.04。有关 LTS Enablement 内核的详细信息,请参见此处:

https://wiki.ubuntu.com/Kernel/LTSEnablementStack

相关内容