まどかの 日記

[2005/01/24〜2005/01/30の日記]
[2005/01/31〜2005/02/06の日記]
[2005/02/07〜2005/02/13の日記]
[2005/02/14〜2005/02/20の日記]
[2005/02/21〜2005/02/27の日記]
[2005/02/28〜2005/03/06の日記]
[2005/03/07〜2005/03/13の日記]
[2005/03/14〜2005/03/20の日記]
[2005/03/21〜2005/03/27の日記]
[2005/03/28〜2005/04/03の日記]
[2005/04/04〜2005/04/10の日記]
[2005/04/11〜2005/04/17の日記]
[2005/04/18〜2005/04/24の日記]
[2005/04/25〜2005/05/01の日記]
[2005/05/02〜2005/05/08の日記]
↑過去3ヶ月くらいの日記はこちら↑

まどかは「P/ECE Hand Book」を応援しています



1309
2005/05/15()
 ファミコンのビデオを見ました(^^
 今日はお昼から友人夫婦が遊びに来てくれたので、お茶してから、一緒にファミコンのビデオを見ました。
 
 ファミコンのビデオに収録されている高橋名人の映画を見た後、実際にスターソルジャーを遊んで高橋名人と毛利名人のすごさを改めて実感しました(^^;

 その後夕飯に近所の焼肉屋に行ったら、偶然専門学校時代の友人にばったり会ってびっくり。
 待ち時間の間ずっと喋ってました。

 で、家に帰ってからh、またちょっとファミコンの整理をしておしまい。
 それでは、おやすみなさーい。

1308
2005/05/14()
 カラオケと買い物
 今日はお昼に行きつけのインド・パキスタン屋でカレーバイキング。
 その後カラオケ2時間と帰りにダイエーで買い物しておしまい。
 で、夕飯後は嫁さんとファミコンの整理。

 明日は嫁さんの友人夫婦が遊びに来る予定です。
 それでは、おやすみなさーい。

1307
2005/05/13()
 やっぱり動かないー(j−j
 今日も1日Linuxのブートと格闘していたのですが、今日も負け戦。

 使っているBusyboxのVer.がダメなのかと、ここで紹介されているBusybox Ver.0.60.5をDLしてきて組み込んだのですが、やっぱり上手く動かないので、アプリケーションではなく、設定の段階で間違っているのかも知れません。

 また、まだinitrdについても全然理解できていないので、来週はそこら辺からまた勉強していきたいと思います。
 と、いうわけで、今日も遅くまでかかったけど、進展無しでしゅーりょー。
 それでは、おやすみなさーい。

1306
2005/05/12()
 MMUとP0〜4領域とかわかってきました
 今日はMMUのアドレス変換機能をONにした時点で止まってしまう不具合を追求するべく、SH3のハードウェアマニュアルを熟読して、MMU関連の知識を蓄えました。

 結局MMUのアドレス変換機能をONにした時点でフリーズしてしまう不具合は、モニタプログラムがMMUでアドレス変換機能をONにした時にアドレス変換の対象となってしまうP0領域に配置されていたからでした。
 
 SH3やSH4にはMMUやメモリのキャッシュ機構があるので、P0〜P4という5種類の扱いが違う領域が存在し、それぞれにキャッシュが効く・効かないや、アドレス変換の対象になる・ならないが決まっています。
 そして、P0〜P4のどの領域に書き込むかは、アドレスの上位3ビットによって指定します。
 何も指定しなくて上位4bitが7以下の場合はP0、8の場合はP1、続いてAがP2、CがP3、そしてEがP4です。
 
 P0領域はアドレス変換の対象になります。つまり、0x00000000〜0x7FFFFFFFまでの2GBはユーザーが指定できる仮想アドレス空間となり、MMUのアドレス変換機能によって少ない物理メモリのどこかに動的に割り当てられるわけです。
 なんかすごいですね。よく考えたものだ(^^
 
 で、今回のフリーズは、恐らくMMUのアドレス変換機能をONにした直後になにかしらのモニタ側の処理(恐らくシリアル通信周り)が実行されて、でも、アドレス変換機能によって元のアドレスとは違うアドレスへ飛ばされたりしているので上手く動かなかったのだと思います。
 
 その証拠に、元のモニタプログラムをアドレス変換の対象にならないP2領域に配置するように作り直したら上手く動くようになりました。
 ああ、なんかややこしいですね(^^;
 色々守らないといけないお約束があって大変ですが、それらは色々な便利な機能を実現させるためのルールなので、きっちり便利な機能のありがたみも含めて勉強していきたいと思います。
 
 と、いうわけで、ようやくLinuxもとりあえず起動が終わり、一番最初のinitプログラムを実行するところまで来たのですが、肝心のinit(/sbin/initなど)が上手く動かない問題がまた新たに発覚。

 一難去ってまた一難っていうか、これで何難目だ(^^:
 
 起動時のinitプログラムはBusyboxを利用しているのですが、これが何か相性とか都合が悪かったりするのでしょうか。

 というところで、続きは明日。
 それでは、おやすみなさーい。

1305
2005/05/11()
 起動できたは良いが……
 さて、昨日の段階で、SDRAM上からプログラムを起動するまでが出来たので、今日は早速SH用のLinuxカーネルのバイナリデータをモニタ経由でSDRAMに書き込んで実行してみました。
 すると、圧縮したLinuxカーネルを展開し、展開先に制御を移して、Linuxのブートシーケンスに入るのですが、途中でMMU(Memory Management Unit)のアドレス変換機能をONにした段階で止まってしまう不具合が発生し、また困ってしまいました。

 MMUとは、プロセスが必要とするメモリサイズよりも、物理メモリが少ない場合に、途中でアドレスを変換することにより物理メモリ資源をやりくりしてくれる機能(あとは記憶保護とか)で、これがあると、物理メモリのアドレス空間よりも大きなアドレス空間をアプリケーションに割り当てることができる(論理アドレス空間)ので、かなり便利なのです。

 よく聞く仮想記憶方式っていうのは、このMMUの機能とハードディスクなどの2次記憶装置(媒体)を用いて実現されます。MMUが無くても、仮想記憶は実現できるのですが、そこらへんはMinixuCLinuxなどを参考にすると良いみたいです。

 と、MMUの話はこれくらいにして、今はLinuxのブート途中でMMUのアドレス変換機能をONにすると止まってしまう不具合に悩まされているのですが、Linuxのソースはアドレス変換機能がONの状態でも動くように作られているので問題は無いとして、あと考えられる要因としてはモニタプログラム側になるので、モニタプログラムを疑ってソースを見直すことにしました。

 で、試しにモニタプログラム上でMMUCR(MMU制御レジスタ)の値を操作してMMUのアドレス変換機能を有効にしてみたら、案の定フリーズしてしまったので、やはり問題はモニタプログラムにあると見当をつけました。

 ちなみに、モニタプログラムには、指定アドレスのデータをバイト・ワード・ダブルワード単位で読み書きできる機能を付けたので(ダンプはまだ無いですが)、制御レジスタの値もモニタへコマンドを送ることで制御できます。
 この機能をつけたことで、ようやくモニタプログラムらしくなりました。
 前回の割り込みが上手くいかない不具合の時点でデバッグ用にシステムレジスタやコントロールレジスタの状態も表示できるようにしたので、なんかだんだん形になってきて嬉しいです(^^

 というわけで、今日はここまで。
 それでは、おやすみなさーい。

1304
2005/05/10()
 割り込みがかからない原因が判りました(^^
 今日もモニタプログラムの続き。
 昨日は割り込み処理を作ったはいいが、何度やっても割り込みルーチンの飛び先アドレスが0になってしまい、リセットがかかってしまう不具合に悩まされてしまいました。

 で、今日はこのアドレスが0になる原因を探るべくソースの見直しに入ったのですが、もう一度割り込みルーチンのアドレスをテーブル定義している部分を見てみると、すぐに原因が判ってしまいました(^^;

 なんと(別になんとって言うほどのことではありませんが(^^;)、割り込みテーブルがRAMのセクションに配置される指定になっているではありませんか!
 このモニタプログラムの設計ではRAM領域は全てSDRAM上に取るようにリンカスクリプトの部分で設定しているので、テーブルをRAM上にとってしまうと、書き込み時にはSDRAM上にデータはあっても、起動時にはキレイさっぱり消えてしまうので、0になってたりしても当然ですね(^^;

 元のソースの動作していた環境では、RAM領域としておきながら、結局フラッシュメモリの部分にアドレスが指定してあったので、電源切っても消えなくて、しかもRAMだけどもあらかじめデータを定義してあるテーブルなので、書込み操作も一切無く、RAM指定だってことに気付かなかったのでしょうね。

 ちなみに、今練習で作っているモニタプログラムはリトルエンディアンで動くように作っている(Linuxをリトルエンディアンで動かしたいので)のですが、このモニタプログラムをフラッシュメモリに書き込むプログラムがなんとビッグエンディアンでしか動かないので、自作のモニタプログラムを動かす場合はいったん電源を切って、ジャンパでリトルエンディアンに切り替える必要があります。

 しかも、ビッグエンディアンで動いているプログラムで普通にリトルエンディアンのプログラムのバイナリデータをフラッシュメモリに書き込むと、データが上位・下位で逆転して書き込まれてしまうので、あらかじめリトルエンディアンのバイナリを反転させておく必要があったりして結構大変です(^^;
 ま、バイナリの状態で反転させる変換ルーチンを作ってMakefileに組み込んでおくだけなので、大変だったのは最初だけですが(笑)


 と、いうわけで、割り込みが上手くいかない不具合も、テーブルをROM領域に移動させることで万事解決。
 これでシリアル受信もばっちりだと思いきや、今度はTeraTermでファイル送信した場合に、受信したバイト数が全然足りないという不具合に悩まされて、また割り込みルーチンがおかしいのかもって見直してみるも状況は変わらず。

 使っているシリアルポートがFIFO付きの奴なので、受信時にはちゃんとFIFOの中身を全部取ってくるようにしていなかったのが原因かと直して試してみるもやはり好転せず。

 これだけやってもおかしいのはもしかして送り側に何か問題があるのではないかということで、TeraTermのファイル送信周りの設定を見直してみたら、実は送信時にバイナリ指定していなかったのが原因でした(爆

 モニタプログラム自身を書き込む時はモトローラのSフォーマットといって、書き込み先番地とデータがテキスト形式で書かれているファイルを送信するので、バイナリ指定しなくてもちゃんと送れたのですが、今回のモニタに送るデータはバイナリ形式としたので、TeraTermでバイナリにチェックを入れないと上手く送れていなかったのでした(^^;

 ちなみに、テキスト形式で送ると、ある特定の文字で置き換えが発生するので、それで受信バイト数がおかしくなっていたのだと思います。

 ってなわけで、ようやくバイナリデータを受信して、SDRAMに書き込んで、指定アドレスから実行(指定アドレスへジャンプ)するまでができました。

 テスト用に、SDRAM上のアドレスから実行するように配置した(リンカスクリプトでそのようにセクションをマッピングした)簡単なプログラムを用意して、モニタプログラムでSDRAMに書き込んで実行してみました。

 今度は見事に成功し、モニタプログラムから別のプログラムをSDRAM上に書き込んで実行できるようになりました。
 なんていうか、これで、P/ECEでメニューからアプリを選んで実行しているときのカーネルの動作に似たことが出来たことになりますね。

 P/ECEでは、実行対象のPEXファイルのファイル名をpceAppExecFile APIを通じてカーネルに渡して、カーネルでは指定のPEXファイルを開いて、ZIP圧縮を解除しながらSRAMに展開後のデータを書き込んで、SRAM上のアドレスを指定してAppInitとかAppProcとかをカーネル側から呼び出しているわけですね(^^

 今回のモニタプログラムでは指定のアドレスから実行した後は、制御を全てそちらに移してしまいますが、通常のLinuxやWindowsみたいにカーネルが管理する場合は、カーネル側から指定のアドレスの関数を呼び出すみたいになるんですね。
 これは、P/ECEのカーネルのソースを読むとよくわかるんですが、やっぱりソースを読むと勉強になりますねぇ。
 と、いうところで、今日はおしまい。
 それでは、おやすみなさーい。

1303
2005/05/09()
 モニタプログラム進めました
 今日からまたSH3評価ボード上でLinuxを起動させるための、SDRAM書き込みプログラム(仮称モニタプログラム)の続きです。

 一応シリアルでデータを受けてSDRAMに書き込めるように処理は書いたものの、受信バイト数を表示しながら受けようとすると、割り込みを使って受信していないので、案の定取りこぼしがおきるので、これではいけないと、割り込みを使っての受信方法に切り替えることにしました。

 今は、評価ボードについてきたGDBスタブのソースを元に、モニタプログラムを作っているのですが、サンプルのシリアル制御関数は割り込みを使わないタイプで、割り込みじゃないタイプの方が取りこぼし無くできるのでしょうけど、せっかくなので割り込み処理の練習ということで、割り込みの方に進めます。

 で、ややあって、割り込み対応のシリアル受信ルーチンはできたのですが、何度やっても上手く割り込み受信ルーチンに飛んでいかないので、ちょっと困ってしまいました。

 割り込み処理なんて、よく使うものだし、ちゃんと割り込みベクタテーブルに関数のアドレスを登録しているし、割り込み用の関数もちゃんと割り込み用に作っているので、こんなところで失敗するはずがないのですが、なぜか上手く動かないんです。

 チマチマデバッグで、事象レジスタの値なども確認して、確かにシリアル受信割り込みがかかっているし、割り込み例外を処理するルーチンにも来てるのは確認しました。
 なのに、目的の割り込みルーチンに飛ばないのはなぜか?
 念の為、飛び先のアドレスを表示させてみたら、なぜか0番地ということになっている。
 シリアル受信の割り込みを開始したところでリセットがかかるので、飛び先が0になっているというのは合点が行くのですが、なぜ0になってるのか。

 飛び先は、テーブルとしてアセンブラルーチン内に記載されているので、ちゃんと書き込まれているはず……
 なのに、0になってしまうのはなぜじゃー!?

 と、いくら考えても今日ではわからなかったので、続きはまた明日。
 それでは、おやすみなさーい。