Notes

Do not read codes but patch binary.

xv6 code reading(1.shell編)

今回(初回)はshellについて。普通はbootloaderから見て行くのかもしれないけど身近なものから。

恐らく、shellについて理解する最短で最良の方法が,こいつhttps://github.com/mit-pdos/xv6-public/blob/master/sh.cをじっくり読むこと。

ざっとみて、新しく気付いた点を簡単に列挙してみる。

  1. cd(change directory)は唯一の別processとして切り出されてないcommand   (逆にcdをexec経由で実行するってできない?->execされたプロセスからshellのプロセスのcwdを変更しなきゃダメ)
  2. shellのcommandは、5つ(list(;,&&)/pipe(|)/redirection(<,>)/back(&)/exec)に分類される
  3. parse後に,command毎に各種識別可能なtypeを持たせた構造体を二分木的に結合させ,topDownで処理
  4. systemcall側から分類すると、pipeはfork2回(close/dup/close/closeが続く),backはfork1回,listはfork1個にwaitを追加,redirはopen,execはexecのみという流れ。

因みにpipeのsystemcallに関しては、左右1と0のfileのtypeを"pipe"に設定しているだけで、そのあとにfileをread/writeした時にkernel内でtypeがfileだったら、kernel内にあるpipe専用の構造体に値をセットしましょっていう流れ。

redirectionのopenに関しては、> だと左のprocessの1に右のfile descriptor0番設定してね(逆はその逆)というだけでopen一つで行けてシンプルだ。

forkしてあげた先のedge nodeのexecで実行されたprocessはdefaultで親のfile descriptor(0/1/2)を引き継ぐので、入出力が上手く回るのね。

気になる点として

  1. shellのprocessがfd0/1/2以外をopenする可能性ってあるの?
  2. shell自体のprocessが持ってるpathはshellのproc構造体が知ってるけど、環境変数から与えられるexecで実行可能なpathをどう設計するのがベスト?
  3. shellのprocessが毎回のcommand実行時にcommand分の構造体の大きさを確保するsbrk()呼んでるけど、こいつ木のrootで一回呼べばよくね?

とりあえず以上。暇があったら拡張したい。