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' 呑み会だったりして。