TL;DR
- M5Stack UnitV2上で動作するtmuxをビルドした
- 手っ取り早くビルドするために、ARM用UbuntuのDockerイメージを使った
- terminfoやlocaleの追加、パーミッション修正が必要だった
はじめに
先日、M5Stack UnitV2を購入しました。Linux搭載のAIカメラということで、色々と遊べそうです。
M5Stack UnitV2が気になったので購入しました。 pic.twitter.com/av0VIgqqcz
— NALGO Lab. (@NalgoLab) July 13, 2022
PCからSSH接続することも可能で、初期状態でもgit
やscp
、zsh
など、比較的豊富なコマンドが入っているようでした。
しかし、tmux
やscreen
のようなターミナルマルチプレクサは無いようでした。
OSはBuildrootという組み込み用Linuxのようで、パッケージマネージャで手軽に何かを追加する、という訳にもいかなさそうでした。
困りました。多数のシェルを同時に操る現代人にとって、ターミナルマルチプレクサは生活必需品と言えるでしょう。1
仕方ないので自分でtmux
をビルドすることにしました。
環境
今回ビルドに使用したマシンの環境は以下です。
- OS: Ubuntu 18.04 (x86_64)2
- Docker: 20.10.17
ARM用UbuntuのDockerコンテナを起動できるようにする
UnitV2は32bit ARM環境なので、ARM用のtmuxをビルドする必要があります。
わざわざクロスコンパイル環境を用意するのも面倒3なので、ARM環境用のUbuntuコンテナ内でtmuxをビルドします。
この方法であれば、通常通りビルドするだけで自動的にARM用のtmuxバイナリが得られます。
まずはx86_64な環境でARM用コンテナを起動出来るようにします。
以下のコマンドを実行すれば良いです。4
$ docker run --rm --privileged docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64
以下のコマンドの結果を確認し、linux/arm/v7
が表示されていればOKです。5
この状態になると、コンテナ内のARM用バイナリが自動的にQEMU経由で実行されるようになるため、
ARM用コンテナの起動やARM用Dockerイメージのビルドが可能になります。
$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
default * docker
default default running linux/amd64, linux/386, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/arm/v7, linux/arm/v6
それではARM用Ubuntuのコンテナを起動します。
普通に起動するとx86_64用のイメージが選択されるため、ARM用を指定する必要があります。
まずは以下のコマンドで対応アーキテクチャ一覧を確認します。
$ docker buildx imagetools inspect ubuntu:22.04
Name: docker.io/library/ubuntu:22.04
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest: sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
Manifests:
Name: docker.io/library/ubuntu:22.04@sha256:bace9fb0d5923a675c894d5c815da75ffe35e24970166a48a4460a48ae6e0d19
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/amd64
Name: docker.io/library/ubuntu:22.04@sha256:02ef83b72fb2fb709c356d0669a433555bcc5d07e31dc0016d036f1ca201bf13
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm/v7
Name: docker.io/library/ubuntu:22.04@sha256:0f744430d9643a0ec647a4addcac14b1fbb11424be434165c15e2cc7269f70f8
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm64/v8
Name: docker.io/library/ubuntu:22.04@sha256:37897c7c32dfc8f0b7de513548b48dd967186f3aec144a6d031ab7943ef1abde
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/ppc64le
Name: docker.io/library/ubuntu:22.04@sha256:30b98fdf87f8f8fa733c15f1ffb8bb931ae63fed4b203987162910682ad51284
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/riscv64
Name: docker.io/library/ubuntu:22.04@sha256:cd3d86f1fb368c6a53659d467560010ab9e0695528127ea336fe32f68f7ba09f
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/s390x
linux/arm/v7
用のイメージがあるので、DIGESTを指定してコンテナを起動します。
$ docker run -it --rm ubuntu:22.04@sha256:02ef83b72fb2fb709c356d0669a433555bcc5d07e31dc0016d036f1ca201bf13
Unable to find image 'ubuntu:22.04@sha256:02ef83b72fb2fb709c356d0669a433555bcc5d07e31dc0016d036f1ca201bf13' locally
sha256:02ef83b72fb2fb709c356d0669a433555bcc5d07e31dc0016d036f1ca201bf13: Pulling from library/ubuntu
5aeb313108e1: Pull complete
Digest: sha256:02ef83b72fb2fb709c356d0669a433555bcc5d07e31dc0016d036f1ca201bf13
Status: Downloaded newer image for ubuntu@sha256:02ef83b72fb2fb709c356d0669a433555bcc5d07e31dc0016d036f1ca201bf13
root@f0b8a9d045a0:/# uname -m
armv7l
無事起動できました。
tmuxをビルドする
起動したDockerコンテナの中で作業します。
tmux本体のビルド
root@f0b8a9d045a0:/# apt update
root@f0b8a9d045a0:/# apt install git make autoconf automake pkg-config bison gcc libevent-dev libncurses-dev
root@f0b8a9d045a0:/# git clone https://github.com/tmux/tmux.git ~/tmux
root@f0b8a9d045a0:/# cd ~/tmux
root@f0b8a9d045a0:~/tmux# sh autogen.sh
root@f0b8a9d045a0:~/tmux# ./configure --enable-static
root@f0b8a9d045a0:~/tmux# make -j
aptで依存ライブラリを入れて普通にmakeするだけですが、./configure
時に--enable-static
オプションを付けるのがポイントです。
これで依存無しのシングルバイナリが得られます。
root@f0b8a9d045a0:~/tmux# ./tmux -V
tmux next-3.4
root@f0b8a9d045a0:~/tmux# ldd tmux
not a dynamic executable
得られたtmuxバイナリはdocker cp
等でコンテナから取り出し、
UnitV2上のパスが通った場所(/usr/bin/tmux
など)に配置しましょう。
terminfoの追加
UnitV2上でtmuxを起動すると、そのままでは表示が崩れます。6
tmux-256color
のterminfoがあれば良いため、こちらも用意しておきます。
root@f0b8a9d045a0:~/tmux# infocmp -x tmux-256color > tmux-256color.src
root@f0b8a9d045a0:~/tmux# tic -x tmux-256color.src
これでコンテナ内に/etc/terminfo/t/tmux-256color
が生成されます。
こちらを取り出してUnitV2上の/usr/share/terminfo/t/tmux-256color
に配置すれば良いです。
localeの追加
UnitV2上でtmuxを起動すると、そのままでは以下のようなエラーが発生します。
unitv2% tmux
tmux: need UTF-8 locale (LC_CTYPE) but have ANSI_X3.4-1968
こちらはコンテナ内の/usr/lib/locale/C.utf8
を取り出し、UnitV2上の同じ場所に配置すれば良いです。
配置後に一度UnitV2を再起動すると、エラーが発生しなくなります。
パーミッション修正
localeのエラーを解消すると、今度は「rootユーザでしかtmuxを起動出来ない」7という状態になります。
/dev/ptmx
のパーミッションの問題8なので、修正してやれば起動出来るようになります。
unitv2% sudo chmod 666 /dev/ptmx
再起動すると元に戻ってしまうため、シェルスクリプト化して/etc/init.d/
に置いておくと良いでしょう。
起動
ここまで対応すれば、以下のように無事tmuxが正常起動出来るようになります。
この後、普段PCで使用している.tmux.conf
を使ってみたりもしましたが、特に問題もなく動作していました。
おわりに
今回はM5Stack UnitV2上でtmux
コマンドを使用出来るようにしました。
今後はカメラやマイクなどの機能を使用して、何かしてみたいと思います。