moyashi さんの記事を読んで以来、ずっと欲しかったPQI Airシリーズなんですが、USのAmazonでは売ってなかったり無駄に高かったりして二の足を踏んでました。ある日、郵便局を使うと数百円で荷物が送れることが分かったので、日本のAmazonで買って実家に発送して送ってもらうことでついにゲットしました。
- ひとりぶろぐ » デジカメ内部でRubyを動かす狂気!無線LAN内蔵SDカードアダプタPQI Air Cardの間違った使い方
- ひとりぶろぐ » ポケット無線LANルータの新顔PQI Air Penの著しく間違った使い方
ただ、Cardの方を動かせるmicroSDを持ってなかったので、今はPenでちょっと遊んでみただけです。何をやったかというと、mruby
を動かしてみました。CRubyはちょっと動かせる自信なかったですが、最初から組み込み向けのmruby
なら簡単かなぁと思ってやってみたら簡単でした。
Cross Compile
PQI AirのハードウェアはCPUがMIPSで、使い慣れているx86/x86_64とは違います。ので単にいつもLinuxで使ってるバイナリをコピーしてもダメです。
# cat /proc/cpuinfo
system type : Atheros AR9330 (Hornet)
processor : 0
cpu model : MIPS 24Kc V7.4
BogoMIPS : 232.96
wait instruction : yes
microsecond timers : yes
tlb_entries : 16
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0000, 0x0c68, 0x0ff8, 0x0393]
ASEs implemented : mips16
shadow register sets : 1
core : 0
VCED exceptions : not available
VCEI exceptions : not available
さすがにここでコンパイルするのは、その環境を準備するところで挫折しそうなのでクロスコンパイル(別のアーキテクチャ用のバイナリをコンパイルする)をしました。
やり方はmoyashiさんが紹介されているSourcery CodeBenchというツールチェインを使って静的リンクでコンパイルしただけです。楽チン。
Macで動かすにはこれ自体をセルフビルドする必要があったので萎えて、Vagrantで適当に32bit Linuxを起動して、インストール。適当にPATH
を通しておきます。以下はVagrantfile
の例。
$ cat Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "precise32"
config.vm.box_url = "http://files.vagrantup.com/precise32.box"
config.vm.provision :shell, :inline => "apt-get install build-essential -y"
end
$ vagrant up
$ vagrant ssh
mruby
は最近ビルド方法が変わったらしく、rubyが必要なのでこれも適当に。Vagrantのboxだと大抵入ってるかな。あと必要なパッケージも適当に。Vagrantfileに書いといてもいいね。
$ sudo apt-get install bison git
これで適当にクロスコンパイルの準備ができました。
make mruby
とりあえずコード取ってきます。
$ git clone https://github.com/mruby/mruby.git
$ cd mruby
mruby
はbuild_config.rb
というファイルでコンパイルの方法を色々変えられます(多分)。今回は以下を追加してみました。意味は簡単でMIPS用のgcc
やar
が先ほどのSoucery CodeBenchに入ってるので、それを適当なオプションとともに指定してるだけです。
MRuby::CrossBuild.new('pqi-air') do |conf|
toolchain :gcc
conf.gembox 'default'
conf.cc.command = "mips-linux-gnu-gcc"
conf.cc.flags << %w(-g -O2 -Wall -static -march=24kc)
conf.linker.command = "mips-linux-gnu-gcc"
conf.linker.flags << %w(-s -static)
conf.archiver.command = "mips-linux-gnu-ar"
end
もともとあるMRuby::Build
の方を消すとundefined method 'build_dir' for nil:NilClass
なるエラーになってしまうのでそれも残しておきます(何かやり方間違ってる気が。。。)
あとはmake
したらできあがり。
$ make
ruby ./minirake
(in /home/vagrant/mruby)
Build summary:
================================================
Config Name: pqi-air
Output Directory: build/pqi-air
Binaries: mrbc
Included Gems:
mruby-sprintf
mruby-print
mruby-math
mruby-time
mruby-struct
mruby-enum-ext
mruby-string-ext
mruby-numeric-ext
mruby-array-ext
mruby-hash-ext
mruby-range-ext
mruby-proc-ext
mruby-symbol-ext
mruby-random
mruby-bin-mirb
- Binaries: mirb
mruby-bin-mruby
- Binaries: mruby
================================================
$ file build/pqi-air/bin/*
build/pqi-air/bin/mirb: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, statically linked, for GNU/Linux 2.6.12, with unknown capability 0x41000000 = 0xf676e75, with unknown capability 0x10000 = 0x70401, stripped
build/pqi-air/bin/mrbc: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, statically linked, for GNU/Linux 2.6.12, with unknown capability 0x41000000 = 0xf676e75, with unknown capability 0x10000 = 0x70401, stripped
build/pqi-air/bin/mruby: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, statically linked, for GNU/Linux 2.6.12, with unknown capability 0x41000000 = 0xf676e75, with unknown capability 0x10000 = 0x70401, stripped
実行!
あとは出来上がったフォルダ一式(と言いつつ静的リンクした実行ファイルしか試してませんが。。。)をPQI Air Penに挿したSDカードにコピーしたら実行!
# ./mruby -e 'p 1+1'
2
# ./mirb
mirb - Embeddable Interactive Ruby Shell
This is a very early version, please test and report errors.
Thanks :)
> a = {:foo => 1, :bar => 2}
=> {:foo=>1, :bar=>2}
> a.each { |k,v| p "#{k} => #{v}" }
"foo => 1"
"bar => 2"
=> {:foo=>1, :bar=>2}
感動的ですね、こんなちっこいマシンの上でrubyが動くなんて。mirb
はreadline
がないせいか、カーソルキー効かなくて不便ですが。。。
mruby
のことは実はさっぱり分かってないのですが、色々楽しめそうです。興味ある方はぜひ遊んでみて下さい or 遊び方教えて下さい。