ちょっと書き足したので、NetBSD Advent Calendar 2022に登録しました。
NetBSD/armでもmrubyを動かしてみました。
母艦はFreeBSD/arm64のBastilleBSDのjailです。NetBSDは9.99.107でmrubyは3.1です。
ストレージ系のドライバがまだないので、mdを使ったインストーラのイメージに寄生します。
pkgsrcでのクロスビルドも考えたのですが、mrubyにはクロスビルドの仕組みがあるので、それを使うことにしました。
まず、NetBSDのtoolをbuild.shで作ります。このあとにcrt0.oなどを用意するためにreleaseをビルドします。
これを元にmrubyをビルドします。
MRuby::CrossBuild.new('cross-netbsd-arm') do |conf|
conf.toolchain :gcc
BIN_PATH = "/usr/home/hiroki/netbsd-tools/earmv4/bin"
SYSROOT_PATH = "/usr/home/hiroki/netbsd-src/obj/destdir.evbarm/"
conf.cc.command = "#{BIN_PATH}/armv4--netbsdelf-eabi-gcc"
conf.cc.flags << "--sysroot=#{SYSROOT_PATH}"
conf.archiver.command = "#{BIN_PATH}/armv4--netbsdelf-eabi-gcc-ar"
conf.linker.command = "#{BIN_PATH}/armv4--netbsdelf-eabi-gcc"
conf.linker.flags << "-static --sysroot=#{SYSROOT_PATH}"
conf.gem core: "mruby-bin-mirb" do |spec|
spec.linker.libraries = %w(edit termcap)
end
conf.gembox 'default'
end
実行環境はダイナミックリンクが使えないので、スタティックでリンクしています。またバイナリはstripしてサイズを小さくします。バイナリサイズは1918108バイトでした。
これで出来上がったmrubyの実行ファイルをramdisk.fsに入れてINSTALLなカーネルをビルドしてu-bootでロードできるイメージを作ります。
INSTALLなカーネルは内部のramdisk.fsをmdとしてマウントしてシングルユーザでsysinstを起動するようになっています。
ramdisk.fsはreleaseのビルドでできるのですが、けっこう苦労しました。mdのデフォルトのサイズは3Mでパンパンで入らないので、大きくしました。
listにmrubyのバイナリファイルを追加して、build.shでrelaseを流したところ、3Mに収まらずnbmakefsがエラーになりました。
releaseのフルビルドはけっこう時間がかかるので、結局nbmakefsを直接たたいてramdisk.fsを作りトライ&エラーしました。
% cd distrib/evbarm/instkernel/ramdisk/obj
% /usr/home/hiroki/netbsd-tools/earmv5/bin/nbmakefs -t ffs -B le -s 6144k -F work.spec -N /usr/home/hiroki/netbsd-src/etc -o bsize=4096,fsize=512 -o optimization=space,minfree=0 -f 15 ramdisk.fs.tmp work && mv -f ramdisk.fs.tmp ramdisk.fs;
実機でイメージをtftpしてbootmして実行してsysinstを抜けてshでmrubyを実行してみます。
# cat /tmp/fib.rb
def fib n
return n if n < 2
fib(n-2) + fib(n-1)
end
puts fib(32)
# /bin/mruby /tmp/fib.rb
ORION(armv5 500MHz)なのですが21秒くらいでけっこう早いし、十分実用になると思います。
STR91xx(armv4 250MHz)でも試したしたところ40秒でクロック相当で妥当なところだと思います。