Tag: zip

Sipeed Lichee Nanoでhello world

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

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

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

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を試します.

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 
-rw-r--r-- 1 matoken matoken 14975 Jul 23 15:08 fortune.gz.uu  + uudecode
-rw-r--r-- 1 matoken matoken 13047 Jul 23 15:47 fortune.xz.uu  + uudecode

そういえばあまり有名ではないですがbasE91なんてものもあります.base64よりサイズが小さくなりますが導入からやらないといけないのでちょっと面倒.

Hello worldを試してみます.適当にプログラムを用意してスタティックリンクでコンパイルしてみます.

$ cat hello.c
 <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とかもできそうです.

壊れたzipファイルからデータを復旧する

Flickrからダウンロードしたアーカイブがダウンロードに失敗したのか内容が見られないです.
アーカイブが壊れている場合 -F でどうにかなりそう?

$ zip -l data-download-1.zip
		zip warning: missing end signature--probably not a zip file (did you
		zip warning: remember to use binary mode when you transferred it?)
		zip warning: (if you are trying to read a damaged archive try -F)

zip error: Zip file structure invalid (data-download-1.zip)

-F では駄目で -FF を試してみる

$ zip -F data-download-1.zip --out data-download-1_fix.zip
Fix archive (-F) - assume mostly intact archive
		zip warning: bad archive - missing end signature
		zip warning: (If downloaded, was binary mode used?  If not, the
		zip warning:  archive may be scrambled and not recoverable)
		zip warning: Can't use -F to fix (try -FF)

zip error: Zip file structure invalid (data-download-1.zip)

-FF である程度救える感じ

$ zip -FF data-download-1.zip --out data-download-1_fix.zip
Fix archive (-FF) - salvage what can
		zip warning: Missing end (EOCDR) signature - either this archive
					 is not readable or the end is damaged
Is this a single-disk archive?  (y/n): y
  Assuming single-disk archive
Scanning for entries...
 copying: img_20140426_180357_13952989767_o.jpg  (1935629 bytes)
 copying: img_20140723_180327_14575993850_o.jpg  (2639807 bytes)
 copying: img_20140723_180323_14576035839_o.jpg  (3302817 bytes)
 copying: img_20140723_180400_14576043890_o.jpg  (3611376 bytes)
   :
 copying: imgp1491_15854514735_o.jpg
		zip warning: no end of stream entry found: imgp1491_15854514735_o.jpg
		zip warning: rewinding and scanning for later entries

こういう耐障害性は非圧縮tarやafioとかのほうが強いでしょうがWindowsなんかでは多分標準で扱えないしダウンロードに失敗した場合は再度試みることが出来るのでやっぱzipでいいのかな.

ちなみに今回はFlickrから同じファイルを3回ダウンロードしても全部同じ内容で壊れていたので恐らくFlickr側で壊れているなてことでデータを再リクエストしました…….

環境
$ dpkg-query -W zip tar afio
afio    2.5.1.20160103+gitc8e4317-1
tar     1.30+dfsg-2
zip     3.0-11+b1
$ lsb_release -d
Description:    Debian GNU/Linux unstable (sid)
$ uname -m
x86_64