Кросс платформенный chroot в x86_64 Linux системе

Тем кто часто сталкивается с обслуживанием и конфигурированием систем на базе различных архитектур, приходится решать вопрос среды запуска операционной системы и приложений.
Часто данный вопрос решается с помощью виртуальных машин или отладка ведётся прямо на “железе”, в некоторых, специфических, случаях, конечно не обойтись без отладки на “железе” (к примеру на плате имеется специфический GPIO контроллер) но таковые случаи до воли редки.
Большинство операций по начальной конфигурации, тестам или просто компиляции приложений, можно выполнить на хост системе - с помощью chroot и qemu-static и тем самым работая с локальной, файловой системой, с всеми вытекающими плюсами.

Сегодня я хочу рассмотреть вариант chroot в rootfs ArchLinux arm64. Хоть эта тема и не нова, но почему-то часто про эту возможность забываю (но их можно простить, большинство мануалов от пользователей Raspberry Pi и Windows на хосте :) ).

Для этого нам понадобится архив с rootfs ArchLinux aarch64 и бинарник qemu-aarch64-static (или другой, в соотвтетсвии с вашей embedded платформой)

Все действия выполняются из под пользователя root - не sudo.
[+] sudo su ...
[–] sudo tar ...


Подготавливаем rootfs

sudo su
password: ****
mkdir arch-rootfs
wget http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz
tar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C arch-rootfs


Установка qemu-aarch64-static

Ядро на вашей хост системе, должно быть сконфигурировано с параметром BINFMT_MISC=y.
Конфигурация текущего ядра находится в файле /proc/config.gz, проверить необходимый параметр можно командой zgrep BINFMT_MISC /proc/config.gz.

qemu-aarch64-static должен присутствовать как в хост системе так и chroot окружении, после окончания работ, его необходимо удалить из rootfs или оставить на будущее.

Загружаем бинарник qemu-aarch64-static и устанавливаем в системе, в ранее подготовленный rootfs

wget https://github.com/multiarch/qemu-user-static/releases/download/v4.1.0-1/qemu-aarch64-static
install -m755 qemu-aarch64-static /usr/bin/
install -m755 qemu-aarch64-static arch-rootfs/usr/bin/

Регистрируем обработчик qemu-static для архитектуры aarch64

echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-aarch64-static:' > /proc/sys/fs/binfmt_misc/register


CHROOT

После регистрации qemu-static в системе у нас уже должен работать chroot.
В зависимости от предполагаемых действий, вам может понадобится так-же смонтировать в chroot окружение /proc, /dev, /dev/pts, /sys, этого можно не делать если не предполагается настройка сети, фаервола, systemd, etc.

mount -t proc /proc arch-rootfs/proc
mount -o bind /dev arch-rootfs/dev
mount -o bind /dev/pts arch-rootfs/dev/pts
mount -o bind /sys arch-rootfs/sys

chroot arch-rootfs /bin/bash
uname -a
Linux notebook.sysalex.com 5.3.8-arch1-1 #1 SMP PREEMPT @1572357769 aarch64 GNU/Linux

Если при выполнении chroot arch-rootfs /bin/bash получаете ошибку chroot: failed to run command ‘/bin/bash’: Exec format error - не зарегистрирован qemu-static в binfmt_misc.
При ошибке chroot: failed to run command ‘/bin/bash’: No such file or directory - забыли скопировать qemu-aarch64-static в /usr/bin/ chroot окружения.


Регистрация qemu-static для других архитектур

Что-бы не делать регистрацию руками, можно воспользоваться скриптом binmft_manger

# REGISTER
# aarch64
echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-aarch64-static:' > /proc/sys/fs/binfmt_misc/register

# arm
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-static:' > /proc/sys/fs/binfmt_misc/register

# rmeb
echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-static:' > /proc/sys/fs/binfmt_misc/register

# alpha
echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha-static:' > /proc/sys/fs/binfmt_misc/register

# mips
echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-static:' > /proc/sys/fs/binfmt_misc/register

# mipsel
echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-static:' > /proc/sys/fs/binfmt_misc/register

# ppc
echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-static:' > /proc/sys/fs/binfmt_misc/register

# sh4
echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/bin/qemu-sh4-static:' > /proc/sys/fs/binfmt_misc/register

# sh4eb
echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-static:' > /proc/sys/fs/binfmt_misc/register

# sparc
echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc-static:' > /proc/sys/fs/binfmt_misc/register

# UNREGISTER
echo -1 > /proc/sys/fs/binfmt_misc/ARCH [arm,aarch64...etc]