【メモ】UNIX V6コードリーディング(割り込み, p154〜159)
今回の内容
前回の続きから.
アセンブリで書かれたcallとtrapの実行を詳しく見ていきます.
call, trapの実行
書籍ではあまり言及されていない箇所が多くあまり進みませんでした.
以下, ざっくりとした理解です.
(間違っている箇所がありそう.)
割り込みの場合は, call
の内部でr0
に格納された割り込みハンドラが呼び出されます.
このr0
に割り込みハンドラが格納される箇所は前回見たとおりです.
トラップの場合は, nofault
にトラップハンドラが指定されている場合とそうでない場合で分岐が発生します.
nofault
にトラップハンドラが指定されている場合は, そのトラップハンドラが呼び出されます.
そうでない場合は, callの中へとジャンプしC言語で書かれたtrap
関数が呼び出されます.
(アセンブリ中では_trap
で参照されています.)
基本的には, スタックになにが積まれていくのかが大事なようです.
ちらっと先読みした感じだと, この後割り込みハンドラ/トラップハンドラに処理が移った際にこのスタックがC言語で書かれた関数の引数になるようです.
trap
トラップ種別が含まれたPSWの値をカーネルスタックに格納します.
trap
関数内でこの種別によって処理が分岐するんでしょうか.
nofault
が0かで分岐するのをtst
, bne
命令で実現しています.
nofault
にトラップハンドラが指定されている場合:
SR0
レジスタを1で初期化.
ここが若干謎で, SR0
の1ビット目が1になるとMMUが有効になるらしい.
しかし, なぜこのタイミングでSR0
に1を格納しているのかがわからない.
実は割り込みが発生したタイミングでMMUが無効になってたりするんでしょうか.
nofault
をカーネルスタック上の割り込みされたプロセスのpc
が格納されている場所に格納.
rtt
命令でnofault
が指すトラップハンドラに飛びます.
もう一つよくわかっていないのが, この後のトラップハンドラからどうやってユーザープログラムに復帰するのかということ.
rtt
によって割り込まれたプロセスのPSWとpcが元に戻されているところまではわかるのですが...
nofault
にトラップハンドラが指定されていない場合:
あまり細かく読んでいないのでざっくりと.
jsr
命令でr0
を退避, _trap
のアドレスを代わりに格納してcall1
にジャンプ.
call
の中へジャンプ.
call
全然読めてないです.
最終的には割り込みハンドラへと飛んでいく感じ?
次回の予定
もう少しcallとtrapを詳しく.