initプロセス (カーネルコンテキスト)

昨日,initプロセスに話が及んだので,その辺を追っかけてみよう.userinitで,initプロセスのプログラムカウンタをinit0関数に設定したところまで見た.カーネルの初期化の最後にスケジューラが呼ばれ,initプロセスがスケジューリングされる.

pc/main.c
  237:         p->sched.pc = (ulong)init0;
  238:         p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);

init0関数の全体を次に示すが,181〜184行目でslashとdotを設定している.slashは名前空間のルートを指し,dotはカレントディレクトリに相当するのだろうけど,ccloneを使ってslashのチャネルをクローンしている.186行目のchandevinit関数は,devtabに登録された各デバイスの初期化関数(init)を呼んでいる.続いて,189〜200行目は環境変数の設定だ.何度か出てきたcputypeなんかはここで設定している.最後にtouserでカーネルコンテキストからユーザコンテキストに遷移する.

pc/main.c
  167: void
  168: init0(void)
  169: {
  170:         int i;
  171:         char buf[2*KNAMELEN];
  172: 
  173:         up->nerrlab = 0;
  174: 
  175:         spllo();
  176: 
  177:         /*
  178:          * These are o.k. because rootinit is null.
  179:          * Then early kproc's will have a root and dot.
  180:          */
  181:         up->slash = namec("#/", Atodir, 0, 0);
  182:         pathclose(up->slash->path);
  183:         up->slash->path = newpath("/");
  184:         up->dot = cclone(up->slash);
  185: 
  186:         chandevinit();
  187: 
  188:         if(!waserror()){
  189:                 snprint(buf, sizeof(buf), "%s %s", arch->id, conffile);
  190:                 ksetenv("terminal", buf, 0);
  191:                 ksetenv("cputype", "386", 0);
  192:                 if(cpuserver)
  193:                         ksetenv("service", "cpu", 0);
  194:                 else
  195:                         ksetenv("service", "terminal", 0);
  196:                 for(i = 0; i < nconf; i++){
  197:                         if(confname[i][0] != '*')
  198:                                 ksetenv(confname[i], confval[i], 0);
  199:                         ksetenv(confname[i], confval[i], 1);
  200:                 }
  201:                 poperror();
  202:         }
  203:         kproc("alarm", alarmkproc, 0);
  204:         touser(sp);
  205: }