2022/05/21

Raspberry Pi OSをdocker内で動かす

Intel CPUの64bit環境下で、Dockerを利用してRaspberry Piの32bit OS環境を動かしてみます。

Dockerの準備


Debian11環境で作業します。

Dockerがインストールされていなければ、例えば https://docs.docker.com/engine/install/debian/ を参考にDockerをインストールします。

イメージの準備


最初に、https://downloads.raspberrypi.org/から必要なRaspberry Pi OSのroot.tar.xzをダウンロードします。

Raspberry Pi OS Lite (32-bit)のバージョンbullseyeであれば、 https://downloads.raspberrypi.org/raspios_lite_armhf/archive/2022-04-07-11:57/ にあります。

Dockerのイメージへの変換


次に、ダウンロードしたroot.tar.xzをDockerのイメージへと変換します。例えば、
$ docker image import ./root.tar.xz pi11-32bit:2022-04-07
とします。インポートできたかは、
$ docker images
REPOSITORY    TAG          IMAGE ID       CREATED          SIZE
pi11-32bit    2022-04-07   d2b599f3a584   23 seconds ago   1.16GB
のようにして確認できます。

この時点では、まだ実行できません。

$ docker run -it pi11-32bit:2022-04-07 bash
exec /usr/bin/bash: exec format error

(以下、方法2を実施し、その後、リブートした後に方法1を実行しましたが、もしかすると方法2の影響が残っている可能性があります)

方法1


パッケージqemu-user-staticをホストPCにインストールするだけです。 インストールすると、
$ docker run -it --rm pi11-32bit:2022-04-07 uname -m
armv7l
のようにエラーが起きずに実行できるようになります。

方法2


$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
を実行します。イメージがダウンロードされて、その後、実行されます。

実行が完了すると、ホストPC側に/proc/sys/fs/binfmt_misc/qemu-*が作成され、

$ docker run -it pi11-32bit:2022-04-07 bash -c ls
bin  boot  dev	etc  home  lib	lost+found  media  mnt	opt  proc  root  run  sbin  srv  sys  tmp  usr	var
のように動くようになります。

なお、ホストPCをリブートすると、ホストPCで

$ ls /proc/sys/fs/binfmt_misc/
python3.9  register  status
となり、qemu-で始まるファイルがなくなります。また、
$ docker run -it pi11-32bit:2022-04-07 bash
exec /usr/bin/bash: exec format error
となり、実行できない状態になります。

方法2の仕組み


multiarch/qemu-user-staticコンテナ内で、ホストのbinfmt_miscとqemu-user-staticを設定することで動作させているようです。

まず、 https://github.com/multiarch/qemu-user-static/blob/master/containers/latest/register.sh を見ると

mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
と書かれており、カーネルモジュール binfmt_misc をマウントしています(lsmodを実行するとbinfmt_miscが存在することが確認できます)。

少なくともここでホストのルート権限が必要になり、--previlegedをつけることになります。

また、register.shの最後に呼び出されているファイルはおそらく https://github.com/qemu/qemu/blob/master/scripts/qemu-binfmt-conf.sh で、この中のqemu_register_interpreter()にて

qemu_generate_register > /proc/sys/fs/binfmt_misc/register
という記述があることから、最終的にbinfmt_miscに対して自動的にqemuを動作させるよう登録をしています。

参考


https://www.koatech.info/blog/raspbian-on-docker/
https://qiita.com/autch/items/c8c9cdc7b8e5821e81a4
https://github.com/multiarch/qemu-user-static
https://github.com/qemu/qemu/blob/master/scripts/qemu-binfmt-conf.sh
https://wiki.bit-hive.com/north/pg/binfmt_misc
https://qiita.com/yuyakato/items/5dd06fb179922206044d

0 件のコメント :