Sipeed Lichee Nanoでhello world

2020-07-23低レベル勉強会に参加しました．Zoom.usでの開催でした．

低レベル勉強会2020年07月 – connpass

内容はLinux名刺的なものを開発しようという内容で，リファレンスとしてSDカードサイズの小さなLinuxの動作するarmコンピュータのSipeed Lichee Nanoを使いました．

荔枝派Nano 全流程指南 — 荔枝派Nano 全流程指南 documentation

欲しい場合は1000円ちょいくらいからで入手できそうです．

Sipeed Lichee Nano – スイッチサイエンス 1045円 + 送料200円 =1245円

Lichee Nano – Shigezone Online 990円 + 送料400円 = 1390円

【5705】SIPEED-LICHEE-NANO Sipeed Lichee Nano 1050円 + 送料350円 = 1400円

ＬｉｃｈｅｅＰｉ　Ｎａｎｏ　１６Ｍ　ｆｌａｓｈ: マイコン関連 秋月電子通商-電子部品・ネット通販　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は開発止まってるように見えるから別のもののほうがいいかもしれない)

端末をリアルタイムに Web で共有できる GoTTY – matoken’s meme

Lichee Nanoで何かを動かしたい．armだけどarmhf動くのかな?とりあえずなにか転送して動かしてみようと．

とりあえずDebianのarmhfバイナリをuuencodeしてコピペで転送してみます.これが動けばDebianのパッケージ群が利用できるかもだけど……．

まずは簡単そうなfortuneを試します.

Debian sidでfortune-modパッケージのarmhfバイナリパッケージをダウンロードして展開(add archtecture armhfしてある環境)

$ 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のもので非対応でした．

ローカル端末で圧縮してuuencodeしてクリップボードへ

$ 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よりサイズが小さくなりますが導入からやらないといけないのでちょっと面倒．

unix:commands:base91 [wiki.matoken.org]

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なので動くはずがない．ということでクロスコンパイル環境を用意します．

CrossToolchains – Debian Wiki

今回試したホストは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

この辺りで今回は時間切れ．次回の同じような感じになりそうです．興味のある方は以下のページから．

低レベル勉強会2020年08月 – connpass

とりあえずarmelのバイナリが動くようなのがわかったので面白そうな小さなプログラムを試そうかなと思っています．cowsayとか好きなんだけどこれはPerlなので容量的に難しそう．とりあえずfortuneあたりかな?

以前PQI Air PenでやったようにSD cardを用意してそこにDebian armlf環境を展開してchrootとかもできそうです．

PQI Air Pen Hack – Speaker Deck