chroot into arm

This is part of a series of posts on the design and technical steps of creating Himblick, a digital signage box based on the Raspberry Pi 4.

Now that we have taken care of updating the SD image partitioning we are free to customize the system.

Normally one would mount the system partition, chroot into it, and run scripts, install packages, run ansible playbooks. But this is an arm system, and the development systems are amd64, which won't run arm binaries. Or won't they?

It turns out that in 2019, they do:

# apt install qemu binfmt-support qemu-user-static
# chroot /media/root/rootfs
/# /usr/bin/file /usr/bin/file
/usr/bin/file: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, …
/# echo foo > /dev/null
bash: /dev/null: Permission denied

Chroot doesn't mount /dev, /sys, /proc, and the rest of the filesystems needed to run many commands. Now that we live in the future, there's a straightforward way to get that done, too:

# apt install systemd-container
# systemd-nspawn -D /media/root/rootfs
Spawning container rootfs on /media/enrico/rootfs.
Press ^] three times within 1s to kill container.
~# /usr/bin/file /usr/bin/file
/usr/bin/file: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, …
~# echo foo > /dev/null
~# cat /dev/null
~#

So, to recap:

  1. apt install qemu binfmt-support qemu-user-static systemd-container
  2. use systemd-nspawn -D instead of chroot

and you can chroot in a mostly set up filesystem for any architecture supported by QEMU.

Joy!

Update: