Cross-Bootstrap Fedora
I recently had to assemble linux distribution images to be run in containers and
virtual machines. While most package managers provide tools to bootstrap an
entire distribution into a target directory (e.g., debootstrap
, dnf
--installroot
, zypper
, pacstrap
, …), I needed to do that for foreign
architectures. Fortunately, Fedora got me covered!
If you use dnf --installroot=/path
, dnf will perform the given operations in
a separate directory tree, rather than your file-system root. It is easy to use
this with dnf install
to install an entire Fedora distribution into some
custom directory. Unfortunately, RPM allows scripts to be run as part of the
installation process of packages. Those scripts might invoke binaries of the
target architecture as part of the installation. Hence, before we can cross
bootstrap Fedora, we need one more tool: qemu-user-static
The qemu project provides two kinds of emulators:
-
System Emulators: These are the commonly known emulators used to emulate an entire machine of a given architecture. They can be used to run virtual machines of any kind. The binaries are usually called
qemu-system-<arch>
. -
User Emulators: These emulators are much less known. They emulate the linux user-space of your target architecture of choice. That is, they execute binaries of foreign architectures on your machine, translating on the syscall boundary. Hence, you can run
MIPS
binaries on yourx86_64
machine running a normalx86_64
kernel, as long as you use the qemu-user-mips emulator. The binaries are usually calledqemu-<arch>
.
Fedora provides a package called qemu-user-static
, which provides statically
linked qemu user-space emulators and hooks them up with the kernel-binfmt
configuration. Hence, with the package installed, you can directly execute
binaries of foreign architectures, and the kernel will use the qemu emulators
to run the binaries. Since the qemu emulators are statically linked, they will
work just fine in chroots as well.
With this in mind, you can simply add --forcearch=<arch>
to dnf to bootstrap
Fedora in a foreign architecture. For instance, this bootstraps just bash
and
all its dependencies as 32bit ARM targets:
dnf \
-y \
--repo=fedora \
--repo=updates \
--releasever=27 \
--forcearch=armv7hl \
--installroot=/some/path \
install \
bash
For more information, have a look at Nathaniel McCallum’s
introduction
of the --forcearch
argument to dnf.