RedBootにはtelnetでアクセスできる機能があります。この機能をRubyから叩いて、ファームウエアのアップデートをおこなってみました。
アップデートの手順は下記のようになります。
- flashの初期化
- tftpでkernelをメモリにロード
- ロードされたkernelをflashに焼く
- tftpでrootfsをメモリにロード
- ロードされたrootfsをflashに焼く
利用したgemはnet-pingとnet-telnetです。時間がかかる処理があるので、Timeoutは長めに設定してあります。tftpサーバにはZRouterでビルドしたFon_FON2201_kernel.gz.syncとFon_FON2201_rootfs_clean.iso.ulzmaを置いてあります。
# need boot delay to 5 sec
# example usage
# ruby redbootup.rb 192.168.1.1 Fon_FON2201
require 'net/ping'
require 'net/telnet'
if ARGV.size != 2 then
print "Usage: ruby redbootup.rb <target ip address> <build name>¥n"
exit
end
addr = ARGV[0]
port = 9000
target = ARGV[1]
pinger = Net::Ping::External.new(addr)
while pinger.ping == false do
sleep 1
print "."
end
print "¥nstart telnet¥n"
telnet = Net::Telnet.new("Host" => addr, "Port" => port,
"Timeout" => 3600, "Prompt" => /^RedBoot>/n)
telnet.puts("¥003")
telnet.cmd("fis init -f") {|c| print c}
STDOUT.flush
telnet.cmd("Match" => /^.*continue \(y\/n\)/n, "String" => "y") {|c| print c}
STDOUT.flush
cmd = "load -r -v -b 0x80050000 " + target + "_kernel.gz.sync"
telnet.cmd(cmd) {|c| print c}
STDOUT.flush
telnet.cmd("fis create -e 0x80050100 kernel") {|c| print c}
STDOUT.flush
cmd = "load -r -v -b 0x80050000 " + target + "_rootfs_clean.iso.ulzma"
telnet.cmd(cmd) {|c| print c}
STDOUT.flush
telnet.cmd("fis create -e 0x00000000 rootfs") {|c| print c}
STDOUT.flush
telnet.cmd("fis list") {|c| print c}
telnet.close
^Cを送るタイミングが遅くなる事があるようで、fconfigのBoot script timeoutを5秒くらいにしておくと確実です。
あらかじめBoot scriptは以下のように設定しておきます。
fis load -d kernel
exec
上記のスクリプトを実行してから、ターゲットの電源を入れるかrebootすると処理が実行されます。
出荷時のLunixの様に圧縮していないkernelを焼けば起動が早くなりますが、flashが8Mしかないので圧縮したカーネルを利用しています。
デフォルトでは192.168.1.2にtftpサーバがいることになっていますが、ここにZRouterでビルドしたファイルを置いておきます。
net-telnet便利ですが、ちょっと分かりづらいところがあります。
FreeBSDやMac OS Xのtelnetコマンドで^Cはコードが変換されてしまうようで、telnetコマンドでRedBootを止める事は出来ないようです。
スクリプトでresetしたいのですが、resetを送るとプロンプトが帰ってこなくてスクリプトがハングするので、reset送ってません。スクリプトが終了してコマンドプロンプトに戻ったら電源をOFF/ONしてください。
これで開けてシリアルコンソールをつながなくてもアップデートできるようになって、便利になりました。
FON2100はシリアルがおかしくて、RXをつないでブートするとブートしないのでリモートアップデートが大変便利です。
なぜかわからないのですが、他のターゲットに比べFONはなぜかこの処理遅いです。
AR5312系は全てのターゲットが4M Flashでイメージが収まらないので、redbootのスクリプトで起動するたびにtftpでrootfsを焼いてその後kernelをメモリにロードして実行するようにしているのです。AR5315系はFlashがSPIの8Mなんので、この方法で更新が必要な時だけリモートで焼く事にしました。
CURRENTに入れてもらったsys/mips/atheros/ar531xで一番お勧めは、ちょっとSDRAMが小さいのですがFON2201です。もちろん法律遵守で無線は使えません。実はdev/athをいじりたくないってのが本当の理由だったりするのですが。:-)