Lions' 本読み (54)

ナチュラルが原因で急遽お休みを頂戴することに。昨晩ぐぬぬぬ的な終わり方だったので 2h ドライブからの帰宅後に早速本を開くなど。
実は昨晩まごろくさんから以下なアドバイスを頂戴してて

uはuser構造体+カーネルスタックでPPDAです。プロセスの切替え時に,次に実行するプロセスのそれをカーネルアドレス空間の 7 ページ目に張り付けます。故にuは何時も固定。

http://twitter.com/magoroku15/status/215467052444553217 より引用
ふむふむ、と言いつつも微妙な違和感。なんとなくきちんと理解できていない。
何がか、というとまず、retu の以下の部分。

0740: _retu:
0741:        bis $340,PS
0742:        mov (sp)+,r1
0743:        mov (sp),KISA6
0744:        mov $_u,r0

例の参考図書では 0743 で proc[n].p_addr を KISA6 にコピーする、という記述あり。補足説明として KISA6 は 7 番目の PAR を指します、とあります。これがまごろくさんの言われてる_プロセスの切り替え時に,次に実行するプロセスのそれを_のあたりになる模様。
ただ、テキスト 318p に以下な p_addr 属性に関する記述があって

データセグメントがメインメモリにあるならば、これはブロック番号である。
そうではなく、データセグメントがスワップアウトされているならば、これはディスクレコード番号である。

Lions' Commentary on UNIX より引用
基本的にはスワップインされてる状態で retu が呼び出される、という前提があるのかどうなのか、retu を呼び出すのは swtch と expand との事なので逆に手繰っていってみると何かが見えてくるのかな。
て、眺めてみても何も見えてこず、何故だと言いつつ swtch 手続きを俯瞰してみるに、proc 配列を探索する条件がアレでした。

2208            if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) {

コアに居るの前提なのかorz
ちなみにこのあたりの面倒を見てるのが proc#0 な sched 手続きな模様です。

とは言え

まだ理解できてない。ちょっといくつか列挙してみます。

  • 6 章 309p にある per process data area に関する記述
    • UNIX は、物理メモリのさまざまな位置を指すためにこのレジスタを明示的に操作する。(Lions' Commentary on UNIX より引用)
  • 例の参考図書の 17p の記述
    • $_u の内容を r0 にコピーします。$_u は 140000 で、7 番目の PAR に設定されたページの先頭を指します。(例の参考図書より引用)

あ、以下な記述もありますね。

これは名前 u で通用し、常にカーネルアドレス 0140000 である。すなわち、カーネルアドレス空間の 7 ページ目の先頭で見つけられることになっている。

(Lions' Commentary on UNIX より引用)
んーと、かなり無理矢理な理解というか類推なんですが、

0743:        mov (sp),KISA6

は引用してる通り、7 番目の PAR なので proc[n].p_addr なアドレスがそこに格納されてて 0140000 を参照すると MMU が 7 番目の PAR に格納されてるソレをもとに云々、という事なのかな。
なんか仮想アドレスと物理アドレスがごっちゃになってる感満点ですね。ここの例で言えばおそらくは

  • u が存在する 0140000 は仮想アドレス
  • 7 番目の PAR に格納されている値で実際の位置を変えることができる

ということは proc[n].p_addr には物理アドレスが格納されてないとマズい、のかな。とは言え基本的に 5 章で出てくる malloc とか mfree というソレは MMU 無視している、という認識で良いのかどうか微妙。