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: }