FreeBSD
MIPS
1
どのような問題がありますか?

この記事は最終更新日から3年以上が経過しています。

投稿日

更新日

[失敗]FreeBSDの蟹さん

蟹(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アーキテクチャが違う製品を同じ製品ナンバーにしないとおもうのですが。。。

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
ユーザー登録ログイン

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
Go強化月間~開発する上で知っておくべき知見を共有しよう~
~
エンジニア夏休み企画!~自由研究や読書感想文を発表しよう~
~
1
どのような問題がありますか?
ユーザー登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
ユーザー登録ログイン
ストックするカテゴリー