如何在 64 位 Debian/Ubuntu 上运行 32 位程序?

如何在 64 位 Debian/Ubuntu 上运行 32 位程序?

我安装了 64 位(amd64 又名 x86_64)Debian 或 Ubuntu。我偶尔需要运行32位(i386/i686)程序,或者为32位系统编译程序。我怎样才能以最少的麻烦做到这一点?

额外奖励:如果我想使用旧版本或新版本的发行版来运行或测试怎么办?

答案1

对于当前版本

当前的 Debian 和 Ubuntu 具有多架构支持:您可以以简单的方式在同一系统上混合 x86_32 (i386) 和 x86_64 (amd64) 软件包。这称为多架构支持 - 请参阅乌班图或者德班维基更多信息。

沃克的回答以获得简单、最新的答案。


对于旧版本

在旧版本中,Debian 和 Ubuntu 在 amd64 上附带了许多 32 位库。安装ia32-libs 安装 ia32-libs软件包具有一组基本的 32 位库,以及可能依赖于该库的其他软件包。如果您拥有所有必需的库,您的 32 位可执行文件应该可以运行。对于开发,安装gcc-multilib 安装 gcc-multilib,以及可能依赖它的其他软件包,例如g++-multilib.你可能会发现binutils-multiarch 安装 binutils-multiarch也有用,并且ia32-libs-dev在 Debian 上。将选项传递-m32给 gcc 以针对 ix86 进行编译。

请注意,无论您安装了哪些 32 位用户模式组件,uname -m仍然会显示x64_64您是否运行 64 位内核。下面描述的 Schroot 会处理这个问题。

施鲁特

本节是在另一个 Linux 发行版“内部”安装类似 Debian 的发行版的指南。它的措辞是在 64 位 Ubuntu 中安装 32 位 Ubuntu,但应该稍作修改即可适用于其他情况,例如在 Debian stable 中安装 Debian不稳定版,反之亦然。

介绍

这个想法是在子树中安装备用发行版并从中运行。您可以通过这种方式在 64 位系统上安装 32 位系统,或者安装不同版本的发行版,或者安装不同软件包集的测试环境。

chroot命令和系统调用启动一个进程,该进程具有仅限于目录树子树的文件系统视图。 Debian 和 Ubuntu 发布施鲁特,一个围绕此功能创建更可用的子环境的实用程序。

安装schroot包裹 安装根目录德班)和debootstrap包裹 安装debootstrap德班)。 Debootstrap 仅在安装备用发行版时需要,之后可以删除。

设置施根

此示例介绍如何设置 32 位 Ubuntu 10.04LTS (lucid lynx) 备用环境。类似的设置应该适用于 Debian 和 Ubuntu 的其他版本。创建一个/etc/schroot/chroot.d/lucid32包含以下内容的文件:

[lucid32]
description=Ubuntu 10.04LTS 32-bit
directory=/32
type=directory
personality=linux32
users=yourusername
groups=users,admin

该行directory=/32告诉 schroot 我们将把 32 位安装的文件放在哪里。该行username=yourusername表示用户yourusername将被允许使用 schroot。该行groups=users,admin表示任一组中的用户都将被允许使用 schroot;你也可以放置一个users=…指令。

安装新发行版

创建目录并开始使用 debootstrap 填充它。 Debootstrap 为指定的发行版和体系结构下载并安装一组核心软件包。

mkdir /32
debootstrap --arch i386 lucid /32 http://archive.ubuntu.com/ubuntu

你几乎已经有了一个可以运行的系统了;接下来是一些小的改进。当您运行Schroot 时,它会自动覆盖几个文件/32/etc,特别是 DNS 配置/etc/resolv.conf和用户数据库/etc/passwd以及其他文件(这可以被覆盖,请参阅文档)。您可能还需要一劳永逸地手动复制一些文件:

cp -p /etc/apt/apt.conf /32/etc/apt/      # for proxy settings
cp -p /etc/apt/sources.list /32/etc/apt/  # for universe, security, etc
cp -p /etc/environment /32/etc/           # for proxy and locale settings
cp -p /etc/sudoers /32/etc/               # for custom sudo settings

chroot 中不会有文件/etc/mtab/etc/fstab我不建议mount在 chroot 中手动使用该命令,而是从外部执行。但一定要创建一个足够好的/etc/mtab命令来使命令df合理地工作。

ln -s /proc/mounts /32/etc/mtab

使用directory类型,schroot 将执行绑定安装多个目录,即这些目录将与父安装共享:/proc, /dev, /home, /tmp

chroot 中的服务

如此处所述,schroot 不适合运行守护程序。当您退出 schroot 时,schroot 中的程序将被终止。如果您希望它更持久,请使用“普通”schroot 而不是“目录”schroot,并在/etc/fstab父安装中设置永久绑定安装。

在 Debian 和 Ubuntu 上,服务在安装时自动启动。为了避免这种情况(这可能会破坏 chroot 之外运行的服务,特别是因为网络端口是共享的),请建立一个政策不在 chroot 中运行服务。将以下脚本设置为/32/usr/sbin/policy-rc.d并使其可执行(chmod a+rx /32/usr/sbin/policy-rc.d)。

#!/bin/sh
## Don't start any service if running in a chroot.
## See /usr/share/doc/sysv-rc/README.policy-rc.d.gz
if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
  exit 101
fi

填充新系统

现在我们可以开始使用 chroot。此时您需要安装更多软件包。

schroot -c lucid32
sudo apt-get update
apt-get install lsb-core nano
...

您可能需要生成一些语言环境,例如

locale-gen en_US en_US.utf8

如果 schroot 适用于较旧版本的 Ubuntu,例如 8.04 (hardy),请注意软件包 ubuntu-standard 会引入 MTA。选择nullmailer而不是默认值postfix(您可能希望您的 chroot 发送邮件,但您绝对不希望它接收任何邮件)。

更进一步

欲了解更多信息,请参阅schroot手动的, 这施鲁特常见问题解答schroot.conf手动的。施鲁特是Debian 自动构建器 (buildd) 项目。可能还有其他有用的提示关于 debootstrap 的 Ubuntu 社区页面

虚拟机

如果您需要完全隔离备用环境,请使用虚拟机,例如键盘虚拟机qemu-kvm 安装 qemu-kvm) 或者虚拟盒子

答案2

自从乌班图11.04(自然)和德班7.0(喘息)推出多架构支持,32位和64位库可以在一个系统上共存。要安装 32 位库 libXX,首先将必要的 32 位架构添加到您的系统中:

sudo dpkg --add-architecture i386
sudo apt-get update

然后安装32位库:

sudo apt-get install libXX:i386

ia32-libs 包。从 Ubuntu 12.04 开始,它不再包含任何库,它只引入libXX:i386包作为依赖项。

编译部分对于C和C++程序来说相当容易,添加-m32CFLAGor CXXFLAG,这将使生成的程序32位,例如

export CFLAGS="-m32"
gcc main.c -o main

这也适用于基于 makefile 的项目。

答案3

如果您只有 32 位二进制文​​件,并且想在现代 64 位 Debian/Ubuntu 系统上运行,请执行以下操作:

dpkg --add-architecture i386
apt update
apt install libc6-i386

这已经在 Debian 9 上进行了测试。

答案4

我将其作为 Docker 解决方案撰写 -https://bbosmith.medium.com/running-32-bit-i386-applications-on-64-bit-arm-using-docker-de7a198914a2。 Docker 在任何运行此解决方案的地方都可以工作 - 只需更改设置以适应。

我有一个在任何具有可用 Docker 映像的平台上运行 32 位应用程序的答案。抱歉,这个答案不包括编译。但它对于运行其他平台的二进制文件来说是如此简单和强大,因此它确实值得发布。

假设您想date从 64 位实例上的 32 位 Debian 实例运行。显然这是人为的 - 插入您选择的二进制文件。

首先证明有一个支持 32 位 Linux 的平台可用:

host $ docker buildx imagetools inspect debian
Name:      docker.io/library/debian:latest
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest:    sha256:e97ee92bf1e11a2de654e9f3da827d8dce32b54e0490ac83bfc65c8706568116

Manifests:
  Name:      docker.io/library/debian:latest@sha256:c2cedd7f80a4dd0f9f80d3699bd433ccf3de33ab63bfa2d4c4ba870c998222d6
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64

  Name:      docker.io/library/debian:latest@sha256:e2e12679dbb45a942e627756196cc8a87182c5de53000b021a051733422e1d45
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm/v5

  Name:      docker.io/library/debian:latest@sha256:2acb8966cd93f0928d5ed57116849afae60eb8603797ca9b34801620d35236d9
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm/v7

  Name:      docker.io/library/debian:latest@sha256:6496a3400e12fbff53da7318b304405a5cb2f185a74bdb4458dcc4b645839380
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64/v8

  Name:      docker.io/library/debian:latest@sha256:0877f432f15595d9754cdd7c01e8afd53767db4b515b9a47d3e67e1e2f40f520
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/386

  Name:      docker.io/library/debian:latest@sha256:f464ff1c8422dce7ce2f9c179b7e39a680748b4d0e3e074ad705cf84d4372a0c
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/mips64le

  Name:      docker.io/library/debian:latest@sha256:5105fb4c3f037b0a6278c3ae1f0320ff1e169a3d7cfb0ca7a7b51f8657039c21
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/ppc64le

  Name:      docker.io/library/debian:latest@sha256:c5bfba100bac4c910c69710efe8a07b4b39d547f3c75722944eb741845742936
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/s390x

是的! Platform: linux/386

如果没有,您需要尝试其他映像而不是 Debian(在本例中使用)或进行一些鸭鸭搜索。

接下来编写一个Dockerfile:

FROM debian

ENTRYPOINT ["date"]

ENTRYPOINT 的形式exec允许传递参数,例如"+DATE: %D%nTIME: %T"

https://docs.docker.com/reference/dockerfile/#shell-and-exec-form

构建它:

host $ docker buildx build --platform <target for build> -t <dockeruser>/<dockerImageToBuild>:latest \
     --push .

例如。

host $ docker buildx build --platform linux/386 -t bbos/dateegforso:latest --push .

标签名称 ( bbos/dateegforso) 必须全部小写。

这会将构建映像推送到 Bob 的 docker.io 存储库。推送不是必需的,但会在全局范围内保留图像。

您需要先登录才能启用此推送。

docker login

使用以下命令运行:

docker run --init --platform <platform to run if multiple> <dockeruser>/<dockerImageToBuild>:latest <args>

例如。

docker run --init --platform linux/386 bbos/dateegforso:latest "+DATE: %D%nTIME: %T"

(该图像当前存在,并且该命令应该按原样工作)。

--init不是必需的,但是如果您有一个长时间运行的任务(显然不是date)并且您需要终止它,那么您将需要它。否则ctrl-c将其发送到啦啦之地。

你可以在任何 docker 运行的地方运行这个。 x64 Linux、AMD、AARM64、..

相关内容