個人的に Qbilinux ってディストリビューションを作成しています。その環境の上で色々な作業をしてますが,ARM の開発環境をもっと効率の良い物にでないかなぁっと昔から思っていました.
過去,クロスコンパイラを作ってみたり,qemu 上で動作させてみたり.
で,今回,Qbilinux 上で docker が動作するようになったので,docker 上に ARM 開発環境を構築できないかなと思い立ち.
少し検索してみたところ,下記のページを発見.すばらしい.
元ネタはここらしい.
ふむふむ.
とりあえず,最初はドキュメント通り試してみようかなということで 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 とかとは違う話もしましたが,そんな感じです.