個人的に Qbilinux ってディストリビューションを作成しています。その環境の上で色々な作業をしてますが,ARM の開発環境をもっと効率の良い物にでないかなぁっと昔から思っていました.
過去,クロスコンパイラを作ってみたり,qemu 上で動作させてみたり.
で,今回,Qbilinux 上で docker が動作するようになったので,docker 上に ARM 開発環境を構築できないかなと思い立ち.
少し検索してみたところ,下記のページを発見.すばらしい.
qiita.com
元ネタはここらしい.
blog.guiraudet.com
ふむふむ.
とりあえず,最初はドキュメント通り試してみようかなということで raspbian を使って上記説明のとおりに作業してみました.日本語のページでは docker 上の debian で作業していますが,手元に linux 環境があるので,static な qemu バイナリだけを拾ってきて,普通に linux 上でゴニョゴニョと作業.static な qemu イメージの有る場所は http://blog.guiraudet.com/raspberrypi/2016/03/03/raspbian-image-for-docker.html の方に記述されているものを拾ってきました.
作成したイメージを docker に登録してドキドキしながら実行.....うまく動作しない.^^;
$ docker run --privileged -it raspbian-x86_64:20200213 /bin/bash
standard_init_linux.go:211: exec user process caused "exec format error"
と出てダメ.
うーむ.何でだろう?
いろいろと調べてみたところ,https://github.com/multiarch/qemu-user-static があって,ここにあるドキュメントによると
$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
で直るらしい.ってことで実行.
無事実行できるようになりました.ふう.
$ docker run --privileged -it raspbian-x86_64:20200213 /bin/bash
root@9f9ad0a61de9:/# uname -a
Linux 9f9ad0a61de9 5.4.50-x64 #1 SMP Sun Jul 5 09:45:28 JST 2020 armv7l GNU/Linux
root@9f9ad0a61de9:/# arch
armv7l
root@9f9ad0a61de9:/#
multiarch/qemu-user-static って何なんだろう?って思ったら https://github.com/multiarch/qemu-user-static のページの下の方に説明がありました.
とりあえず,raspbian が動作したので,今度は本命の自分で作ってる Qbilinux 環境を動かせないか試してみました.
Qbilinux verion 0.3 の aarch64 用の SD カードイメージを https://qbilinux.org/pub/isos/qbilinux-0.3_aarch64_sd.img.xz に公開しているので,それを unxz して圧縮展開.ld.so.preload は使っていないので修正は必要ないかな.で,raspbian の時と同様に qemu を同梱.
それを tar でかためて docker にイメージを登録.
ドキドキしながら実行.
$ docker run -it --privileged qbilinux-aarch64:0.3 /bin/bash
root@4ab972979376:/# uname -a
Linux 4ab972979376 5.4.50-x64 #1 SMP Sun Jul 5 09:45:28 JST 2020 aarch64 GNU/Linux
root@4ab972979376:/# cat /etc/qbilinux-release
qbilinux release 0.2
root@4ab972979376:/# arch
aarch64
root@4ab972979376:/#
あっさり動作しました.:-)
CPU やメモリはこんな感じで見えます.
root@4ab972979376:/# cat /proc/cpuinfo
processor : 0
vendor_id : AuthenticAMD
cpu family : 23
model : 17
model name : AMD Ryzen 5 2400G with Radeon Vega Graphics
stepping : 0
microcode : 0x810100b
cpu MHz : 3428.868
cache size : 512 KB
physical id : 0
siblings : 8
core id : 0
cpu cores : 4
apicid : 0
initial apicid : 0
fpu : yes
cache_alignment : 64
address sizes : 43 bits physical, 48 bits virtual
power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
- snip -
processor : 7
vendor_id : AuthenticAMD
cpu family : 23
model : 17
model name : AMD Ryzen 5 2400G with Radeon Vega Graphics
stepping : 0
microcode : 0x810100b
cpu MHz : 1355.281
cache size : 512 KB
physical id : 0
siblings : 8
core id : 3
cpu cores : 4
apicid : 7
initial apicid : 7
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid
extd_apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb hw_pstate sme ssbd sev ibpb vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero irperf xsaveerptr arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif overflow_recov succor smca
bugs : sysret_ss_attrs null_seg spectre_v1 spectre_v2 spec_store_bypass
bogomips : 7186.50
TLB size : 2560 4K pages
clflush size : 64
cache_alignment : 64
address sizes : 43 bits physical, 48 bits virtual
power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
root@4ab972979376:/# cat /proc/meminfo
MemTotal: 16346912 kB
MemFree: 776184 kB
MemAvailable: 13863160 kB
Buffers: 693456 kB
Cached: 11844408 kB
SwapCached: 0 kB
Active: 6330576 kB
Inactive: 8169764 kB
Active(anon): 1689744 kB
Inactive(anon): 427304 kB
Active(file): 4640832 kB
Inactive(file): 7742460 kB
Unevictable: 9340 kB
Mlocked: 9340 kB
SwapTotal: 33554428 kB
SwapFree: 33554164 kB
Dirty: 588 kB
Writeback: 0 kB
AnonPages: 1971972 kB
Mapped: 606052 kB
Shmem: 178796 kB
KReclaimable: 883404 kB
Slab: 971948 kB
SReclaimable: 883404 kB
SUnreclaim: 88544 kB
KernelStack: 12864 kB
PageTables: 19380 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 41727884 kB
Committed_AS: 5859872 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 27420 kB
VmallocChunk: 0 kB
Percpu: 2176 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
DirectMap4k: 240100 kB
DirectMap2M: 10192896 kB
DirectMap1G: 7340032 kB
root@4ab972979376:/# top
top - 19:49:51 up 11:46, 0 users, load average: 0.11, 0.36, 0.30
Tasks: 2 total, 0 running, 2 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.7/0.0 1[| ]
%Cpu1 : 0.0/0.0 0[ ]
%Cpu2 : 0.0/0.0 0[ ]
%Cpu3 : 0.0/0.7 1[| ]
%Cpu4 : 0.0/0.0 0[ ]
%Cpu5 : 0.0/0.0 0[ ]
%Cpu6 : 0.7/0.0 1[| ]
%Cpu7 : 0.0/0.0 0[ ]
GiB Mem : 15.3/15.6 [ ]
GiB Swap: 0.0/32.0 [ ]
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
9938 root 0 0 217.4m 9.1m 0.0 0.1 0:00.00 0 /bin/top
1 root 20 0 218.6m 13.3m 0.0 0.1 0:00.30 S /usr/bin/qemu-aarch64-static /bin/bash
CPU は 8個見えてます.使っている PC の CPU スペックが docker からそのまま見えています.Ryzen 5 2400G ですけど.:-)
メモリも 16G 見えていますが,これも使っている PC のメモリがそのまま表示されますね.
次,ソフト類のコンパイルが問題なくできるかチェック.とりあえず docker 中から普段使っている /home をマウントして作業.
root@4ab972979376:/# mount /dev/sdb4 /home/
root@4ab972979376:/# df
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 2767622980 2268102844 358862504 87% /
tmpfs 65536 0 65536 0% /dev
tmpfs 8173456 0 8173456 0% /sys/fs/cgroup
shm 65536 0 65536 0% /dev/shm
/dev/sdb4 2767622980 2268102844 358862504 87% /home
適当なディレクトリを作成して,とりあえず file コマンドをコンパイルしてみることに.
root@4ab972979376:/# cd home
root@4ab972979376:/home# mkdir tmp
root@4ab972979376:/home/tmp# cd tmp
root@4ab972979376:/home/tmp# cp ../archives/source/file-5.37.tar.gz .
root@4ab972979376:/home/tmp# ls -al
total 897024
drwxr-xr-x 2 root root 4096 Jul 16 19:40 ./
drwxr-xr-x 12 root root 4096 Jul 16 19:40 ../
-rw-r--r-- 1 root root 887682 Jul 16 19:40 file-5.37.tar.gz
root@4ab972979376:/home/tmp# tar xf file-5.37.tar.gz
root@4ab972979376:/home/tmp# cd file-5.37
root@4ab972979376:/home/tmp/file-5.37# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
- snip -
config.status: creating doc/Makefile
config.status: creating python/Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands
root@4ab972979376:/home/tmp/file-5.37# make -j8
/usr/bin/make all-recursive
make[1]: Entering directory '/home/tmp/file-5.37'
Making all in src
make[2]: Entering directory '/home/tmp/file-5.37/src'
sed -e "s/X.YY/$(echo 5.37 | tr -d .)/" < ../src/magic.h.in > magic.h
/usr/bin/make all-am
make[3]: Entering directory '/home/tmp/file-5.37/src'
CC buffer.lo
CC magic.lo
- snip -
make[2]: Leaving directory '/home/tmp/file-5.37/python'
make[2]: Entering directory '/home/tmp/file-5.37'
make[2]: Leaving directory '/home/tmp/file-5.37'
make[1]: Leaving directory '/home/tmp/file-5.37'
root@4ab972979376:/home/tmp/file-5.37#
root@4ab972979376:/home/tmp/file-5.37# file src/.libs/file
src/.libs/file: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=1b00b02cdf34f849aa5b9f3127e602cfd5a8d17d, with debug_info, not stripped
root@4ab972979376:/home/tmp/file-5.37#
コンパイル通りましたね.できあがったバイナリも aarch64 用になっていますね.
/usr/local/bin 以下にインストールしてみて動作確認.
root@4ab972979376:/home/tmp/file-5.37# make install
Making install in src
make[1]: Entering directory '/home/tmp/file-5.37/src'
/usr/bin/make install-am
make[2]: Entering directory '/home/tmp/file-5.37/src'
- snip -
make[2]: Leaving directory '/home/tmp/file-5.37'
make[1]: Leaving directory '/home/tmp/file-5.37'
root@4ab972979376:/home/tmp/file-5.37# /usr/local/bin/file /usr/local/bin/file
/usr/local/bin/file: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=1b00b02cdf34f849aa5b9f3127e602cfd5a8d17d, with debug_info, not stripped
root@4ab972979376:/home/tmp/file-5.37#
動作しましたね.
ということで,docker の中でコンパイルできることが確認できました.ふう.
コンテナなので,システムに上書とか適当に書き換えてもコンテナを落とせば,元々の環境に戻るのも便利ですね.
コンパイルにかかった細かい時間は計測してないですが,体感ではそれほど早い感じはしないですね.ただ,CPU が 4C/8T なのでその分は高速かな.メモリもたくさん使えますし.
こいういう環境が整うと,新しくて早い CPU が欲しくなりますね.最近の Ryzen だと 12C/24T とかもあるから,それだとパッケージのビルド時間がかなり短縮できそうですね.
環境を整えて,開発用に使えるように徐々に調整していきたいと思います.
コンテナが動作するようになると,開発向けに一気にいろいろなことができるようになって便利になりますね.:-)
ざっと使ってみた感じは,個々のパッケージの作成はコンテナを使って,カーネルのビルドなどにはクロスコンパイラを使うのが効率的で良さそうかなと思っています.
まぁ,でも環境をきちんと整えてると時間がかかりそうなので,本格的に使うのはしばらく先送りかなと思ってます.
少し docker とか raspberry pi とかとは違う話もしましたが,そんな感じです.