Lions' 本読み (84)
psig の核心部分がイメージできてない。
なんとなく整理してみるに
- シグナルは発行されてすぐに割り込む訳ではなくて trap とか clock の処理の一部としてハンドラが起動される (正確には psig 手続きが呼び出される、かな)
- フレームポインタ (r5) は C の trap から戻る時点で復帰 (r2, r3, r4 も同様)
- あら、この根拠が忘却の彼方だorz
- csv と cret の話が出てます (345p)
- アセンブラの trap の最後らへんの rtt 命令で PS と PC が復帰
で、色々確認してるとやはり以下の psig の核心部分が微妙にイメージできていないことが分かった。
4051 if((p=u.u_signal[n]) != 0) { 4052 u.u_error = 0; 4053 if(n != SIGINS && n != SIGTRC) 4054 u.u_signal[n] = 0; 4055 n = u.u_arg[R6] - 4; 4056 grow(n); 4057 suword(n+2, u.u_ar0[RPS]); 4058 suword(n, u.u_ar0[R7]); 4059 u.u_ar0[R6] = n; 4060 u.u_ar0[RPS] =& ~TBIT; 4061 u.u_ar0[R7] = p; 4062 return; 4063 }
何が微妙か、というと
- カーネルスタックからユーザモードな PC と PS は復帰できる
- PC にはシグナルハンドラの先頭の命令な番地が格納されているはず
- 本来の PC と PS はユーザスタックに格納される
- カーネルスタックな r6 の領域に新しいスタックポインタな値が格納されている
- これ、どこで復帰するのかが分からない
- スタックのてっぺんに積まれている PC と PS をどうやって復帰させるのかも微妙
そもそもどんな流れて、な部分をちょっと整理してみると
- kill でシグナル発行
- 何らかの理由で ISR なアセンブラの trap が kick される
- この時、カーネルスタックに切り替わる
- PC と PS がカーネルスタックに push される
- C の trap 乃至 clock 手続きが呼び出される
- この時、csv 手続きにより r2 から r5 が保存される
- trap 乃至 clock から psig 手続きが呼び出される
- 上で引用した命令を実行して return する
- trap 乃至 clock から return する時に r2 から r5 が復帰
- ISR なアセンブラから戻る時に PC および PS がカーネルスタックから pop
- ユーザモードに戻る時にユーザスタックに切り替わる
- ここでカーネルスタックに保存した r6 から復帰して欲しいけれど
- シグナルハンドラの実行が始まる
始まるのは良いのですが問題が二つある。
- スタックのてっぺんには PC と PS が積まれている
- スタックポインタがてっぺんを指しているかどうか分からない
うーん、もう少し確認してみます。
ちなみに
明日は Lions' 呑み会だったりして。