2020-07-23低レベル勉強会に参加しました.Zoom.usでの開催でした.
内容はLinux名刺的なものを開発しようという内容で,リファレンスとしてSDカードサイズの小さなLinuxの動作するarmコンピュータのSipeed Lichee Nanoを使いました.
欲しい場合は1000円ちょいくらいからで入手できそうです.
- Sipeed Lichee Nano – スイッチサイエンス 1045円 + 送料200円 =1245円
- Lichee Nano – Shigezone Online 990円 + 送料400円 = 1390円
- 【5705】SIPEED-LICHEE-NANO Sipeed Lichee Nano 1050円 + 送料350円 = 1400円
- LicheePi Nano 16M flash: マイコン関連 秋月電子通商-電子部品・ネット通販 1000円 + 送料500円 = 1500円
- Sipeed Lichee Nano Linux 開発ボード 16M Flash – Seeed Studio 707円+ shipping
Lichee Nanoを持っていない人はリモートで触れるようにしてあったので持っていない私も楽しめました.
このリモート開発の仕組みはLichee NanoとRaspberry PiをUSB経由のUARTで接続し,Raspberry PiでGNU screenを起動,ssh経由でGNU screenに繋いで操作という感じです.
GNU screenをGotty等にするとウェブブラウザで参加できてちょっと便利かもと思ったりも.(GoTTYは開発止まってるように見えるから別のもののほうがいいかもしれない)
Lichee Nanoで何かを動かしたい.armだけどarmhf動くのかな?とりあえずなにか転送して動かしてみようと.
とりあえずDebianのarmhfバイナリをuuencodeしてコピペで転送してみます.これが動けばDebianのパッケージ群が利用できるかもだけど…….
まずは簡単そうなfortuneを試します.
$ apt download -t armhf fortune-mod
$ unar fortune-mod_1.99.1-7+b1_armhf.deb
$ cd fortune-mod_1.99.1-7+b1_armhf
$ tar xf data.tar.xz
$ cd usr/games
Lichee Nanoはserialで接続されていて,Internetには繋がっていないのでバイナリファイルの転送にはuudecode/uuencodeを使いました.久々です.
手元のGNU sharutils 4.15.2のuudecodeにはbase64を使う -m, --base64
があるので良さそう.と思ったけどLichee Nanoの方はbusyboxのもので非対応でした.
$ gzip -c fortune | uuencode fortune.gz > fortune.gz.uu
$ cat fortune.gz.uu | xclip
# cat | uudecode #ここでクリップボードから貼り付け
# zcat fortune.gz > fortune
# rm fortune.gz
そして……
# ./fortune
-sh: ./fortune: not found
# ldd ./fortune
checking sub-depends for 'not found'
checking sub-depends for '/lib/libc.so.6'
/lib/ld-linux.so.3 (0xb6fa0000)
librecode.so.0 => not found (0x00000000)
libc.so.6 => /lib/libc.so.6 (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)
これを動かすのはダイナミックリンクされているものを用意してあげないといけないのでストレージの容量的に難しいですね.
ここではgzipで圧縮しましたが,Lichee Nanoのbusyboxにxzがありました.gzipよりxzにしたほうが小さくなりますね.試してみるとこんな感じでした.$ xz -c fortune | uuencode fortune.xz > fortune.xz.uu
-rw-r--r-- 1 matoken matoken 22368 Jul 23 15:11 fortune #元ファイル
-rw-r--r-- 1 matoken matoken 30844 Jul 23 14:58 fortune.uu #uudecode
-rw-r--r-- 1 matoken matoken 14975 Jul 23 15:08 fortune.gz.uu #zip + uudecode
-rw-r--r-- 1 matoken matoken 13047 Jul 23 15:47 fortune.xz.uu #xz + uudecode
そういえばあまり有名ではないですがbasE91なんてものもあります.base64よりサイズが小さくなりますが導入からやらないといけないのでちょっと面倒.
Hello worldを試してみます.適当にプログラムを用意してスタティックリンクでコンパイルしてみます.
$ cat hello.c
#include <stdio.h>
int
main(void)
{
printf("Hello, world!\n");
return 0;
}
$ gcc -static ./hello.c
$ ./a.out
Hello, world!
$ ls -l a.out
-rwxr-xr-x 1 pi pi 571120 7月 23 16:18 a.out
でかい……
とりあえずでかいのはおいといてこれだとarm64なので動くはずがない.ということでクロスコンパイル環境を用意します.
今回試したホストはDebian sid amd64/Ubuntu 20.04 LTS arm64/Raspberry Pi OS arm64です.いずれも同じ手順でOKでした.
crossbuild-essential-<arch>
パッケージで各種アーキテクチャの環境が導入できるようです.
$ apt-cache search crossbuild-essential-
crossbuild-essential-amd64 - Informational list of cross-build-essential packages
crossbuild-essential-arm64 - Informational list of cross-build-essential packages
crossbuild-essential-armel - Informational list of cross-build-essential packages
crossbuild-essential-armhf - Informational list of cross-build-essential packages
crossbuild-essential-i386 - Informational list of cross-build-essential packages
crossbuild-essential-powerpc - Informational list of cross-build-essential packages
crossbuild-essential-ppc64el - Informational list of cross-build-essential packages
crossbuild-essential-s390x - Informational list of cross-build-essential packages
crossbuild-essential-mips - Informational list of cross-build-essential packages
crossbuild-essential-mips64 - Informational list of cross-build-essential packages
crossbuild-essential-mips64el - Informational list of cross-build-essential packages
crossbuild-essential-mips64r6 - Informational list of cross-build-essential packages
crossbuild-essential-mips64r6el - Informational list of cross-build-essential packages
crossbuild-essential-mipsel - Informational list of cross-build-essential packages
crossbuild-essential-mipsr6 - Informational list of cross-build-essential packages
crossbuild-essential-mipsr6el - Informational list of cross-build-essential packages
沢山あります.今回はarmlf/armhfの crossbuild-essential-armel
, crossbuild-essential-armhf
を導入しました.
$ sudo apt install crossbuild-essential-armel crossbuild-essential-armhf
gccだけでいい場合はarmlfは gcc-arm-linux-gnueabi
,armhfは gcc-arm-linux-gnueabihf
だけでOKです.
まずは arm-linux-gnueabihf-gcc
を使ってarmhfのバイナリを作ります.
$ /usr/bin/arm-linux-gnueabihf-gcc -static ./hello.c
$ strip a.out
$ xz -c a.out | uuencode a.out.xz > a.out.xz.uu
armhfは駄目そうです.
# cat | uudecode
^d
# xzcat ./a.out.xz > ./a.out
# chmod +x ./a.out
# ./a.out
Segmentation fault
次は gcc-arm-linux-gnueabi
でarmlfのバイナリを作って試すと動きました.
$ /usr/bin/arm-linux-gnueabi-gcc -static ./hello.c
$ strip a.out
$ xz -c a.out | uuencode a.out.xz > a.out.xz.uu
# cat | uudecode
^d
# xzcat ./a.out.xz > ./a.out
# chmod +x ./a.out
# ./a.out
Hello, world!
# /usr/bin/time -f "%M KB" ./a.out
Hello, world!
2144 KB
この辺りで今回は時間切れ.次回の同じような感じになりそうです.興味のある方は以下のページから.
とりあえずarmelのバイナリが動くようなのがわかったので面白そうな小さなプログラムを試そうかなと思っています.cowsayとか好きなんだけどこれはPerlなので容量的に難しそう.とりあえずfortuneあたりかな?
以前PQI Air PenでやったようにSD cardを用意してそこにDebian armlf環境を展開してchrootとかもできそうです.