OS起動編⑮-4 mpmain() (Xv6を読む~OSコードリーディング~)
前回
jupiteroak.hatenablog.com
トップページ
jupiteroak.hatenablog.com
main.c
https://github.com/mit-pdos/xv6-public/blob/master/main.c#L51
// Common CPU setup code. static void mpmain(void) { cprintf("cpu%d: starting %d\n", cpuid(), cpuid()); idtinit(); // load idt register xchg(&(mycpu()->started), 1); // tell startothers() we're up scheduler(); // start running processes }
mpmain関数は、この関数を実行しているプロセッサがプロセスを実行できる状態にします。
mpenter関数から呼び出されたmpmain関数はAP(Application Processor)が実行します。
処理の内容
cprintf("cpu%d: starting %d\n", cpuid(), cpuid());
cprintf関数を呼び出して、メッセージを出力します。
idtinit();
idt関数を呼び出して、IDTR(割り込みディスクリプタテーブルレジスタ)に値をロードし、プロセッサがIDT(割り込みディスクリプタテーブル)を利用できるようにします。
xchg(&(mycpu()->started), 1);
xchg関数を呼び出して、アドレス&(mycpu()->started)で指定されたメモリ領域(mycpu()->started)に格納されている値 と 1の値 を交換します(startedの値が1になります)。
この命令が完了すると、BSP(BootStrap Processor)の処理は、startothers関数内のwhileループから脱出できるようになります。
scheduler();
scheduler関数を呼び出すことで、プロセッサが実行しているカーネルスレッドからRUNNABLEの状態であるプロセスへの切り替えが起こるはずですが、
BSP(BootStrap Processor)がuserint関数を実行完了しておらず、切り替え先のプロセスが存在しないため(RUNNABLEの状態であるプロセスが存在しないため)、scheduler関数内のfor文をループすることになります。
この状態は、BSP(BootStrap Processor)がuserint関数を実行完了するまで続きます。