蟹(REALTEK)さんのRTL8196が入ったターゲットが手に入ったので、ちょっと試してみましたがダメでした。これは調べた事のメモです。
RTL8196はRLX4181というLexraという会社が作ったMIPS系のCPUアーキテクチャを搭載したSOCです。LexraはMIPS社と喧々諤々やったみたいで、それにより両者とも消耗しLexraは表舞台から消えたようです。
REALTEKは2000年代前半からLexraのCPUを利用していたようです。最初にリリースされたものはRTL8181ではないかと思われます。
RTL8196はおそらく2000年代後半から提供されていて、当初はメモリ&Flashとも小さな機種で使われていましたが、2010年代中頃には結構大きなメモリ&Flashの機種でも使われるようになりました。
RTL8196はRTL8650B/8651Cの後継のようです。RTL8196はRTL8196BとRTL8196CとRTL8196D,RTL8196Eがあり、RTL8196Cにはレビジョンが二つあります。またRTL8197,RTL8198というチップもあるようです。
Lexraのインストラクションセットはmips1となっています。またいくつか存在しないインストラクションがあるということです。
ビルド環境に付いてはgcc/binutilにパッチをあてて使えるようにしていて、正式版にはマージされていないようです。
REALTEKが提供しているSDKに含まれるブートのプログラムはREALTEKオリジナル(?)のようでu-bootなどではありません。
このブートプログラムはかなり原始的で、圧縮の処理がないようです。このためファームウエアのイメージは自己解凍ELFとして作られています。イメージはこれをcvimgというツールで変換してkernelのファイルかrootfsのイメージとしています。
SDKに含まれる自己解凍プログラムはrtkloadというコードで、ifdefやコメントアウトが入り交じりかなりひどいコードです。
no sys signature at 0009E000!
no sys signature at 00020000!
Jump to image start=0x80500000...
decompressing kernel:
Uncompressing Linux... done, booting the kernel.
done decompressing kernel.
start address: 0x80003630
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
decompressing kernelからstart addressがrtkloadのコードになります。
OpenWRTでは書き直していて、lzma-loaderというものを使っているようです。
no sys signature at 0009E000!
no sys signature at 00020000!
Jump to image start=0x80500000...
OpenWrt kernel loader for Realtek rtl819xx
Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
Copyright (C) 2013 Roman Yeryomin <roman@advem.lv>
Decompressing kernel to 80000000... done!
Seems kernel_entry address is different from load address, so...
Starting kernel from 80003530...
[ 0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Flashが8Mのターゲットなのでとりあえず圧縮はせず、生のカーネルを焼いてブートを試してみました。
ZRouterでビルドしてカーネルをターゲットに放り込むshスクリプトは下記のようになります。
#!/bin/sh
TERGET="Au_HomeSpotCube"
ENTRY=`readelf -h ${TERGET}_kernel | awk '/Entry point address/{print $4}'`
echo ${ENTRY}
./cvimg linux ${TERGET}_kernel.kbin ${TERGET}_kernel.rtl ${ENTRY} 30000
IMG=${TERGET}_kernel.rtl
echo "bin
put ${IMG}
quit" | tftp 192.168.1.6
当初Little Endianかと思ったらBig Endianでした。
これでちゃんと実行されているかは、mips/mips/locore.Sのstartに下記のコードを入れて確認しました。
li a0, 0xb8002000
li a1, 0x50
sb a1,0(a0)
これでシリアルコンソールにPの文字がでるので、とりあえずカーネルまで実行が移っている事が確認できました。
ところが、FDTのkobjの処理で、Undefined Exception happen.となってしまいます。現在のFreeBSDのmipsはmips32でコンパイルされているのですが、おそらく無いインストラクションとかがあるのかもしれません。
試しにmips1でビルドしてみたら、なぜかgccが吐いたコードにll/scが入ってasがそんな命令知らないとエラーになっていました。
kbojの問題でFDTの問題ではなかったのですが、FDTもendianが絡んできて、big endianでちゃんと動くのか不明です。
ちなみにUndefined Exception happen.はブートが出しているメッセージで、カーネル側がエクセプションハンドラを書き換える前にエクセプションが発生するとブート側に処理が戻ってしまいます。ブートのコードを見てみたら、エクセプションすべて同じメッセージでどのエクセプションが発生しているかも分かりません。
ノーマルのgccでは対応できないし、ましてやclangでは眼中にないとおもわれ、あきらめた方が良さそうです。
後日追記:蟹さんは最近MIPS 24KなSOCも作っているようです。またまた不思議なのはRTL8197DはLexraベースでRTL8197Fは24Kのようです。普通は、CPUアーキテクチャが違う製品を同じ製品ナンバーにしないとおもうのですが。。。