***本記事にはプロモーションが含まれています。***
とりあえず調べてみる。
PITのモードは、2。gdbで、pit_ioport_writeにブレークポイントを仕掛けると、6回止まる。最初の3回は、BIOSが初期設定をしている。後の3回はhariboteがio_out8したもの。
PITの設定が終わると、pit_irq_timerが定期的に実行されるようになります。
関係ないけど、MS-DOSは、55msのタイマ割り込みを設定しているそうですね。
pit_get_next_transition_timeという関数は、irqが次に変化する時間を計算している。
PITの設定は、その時間をs->next_transition_timeに設定し、qemu_mod_timerで、expire_timeを設定している。
時間がたつと関数が実行されるメカニズムは、時間のタイムアウトを設定しておくと、vl.cのmain_loop_waitのなかで、qemu_run_timersを呼んで、時間切れがあったら、ts->cb(ts->opaque)というコールバック関数を呼んでいること。このts->cbにpit_irq_timerが登録されていて、実行される。
もう1つ、CPUの実行中に割り込みが起こるというのは、cpu-exec.cのcpu-exec関数のループの中で、env->interrupt_requestを調べる。CPU_INTERRUPT_HARDが設定されていると、cpu_get_pic_interruptでどの割り込み番号が設定されているかを調べる。do_interrupt(intno, 0, 0, 0, 1)で次に実行するenv->eipを設定したりして、ゲストOSがIDTに登録した関数が実行されるようにする。
QEMU内部での、プログラムとしての時間切れの処理と、ゲストOS内でやってほしいことの2つあるということか。
main_loop_waitで、pit_irq_timerを呼んでいるので、ゲストOSがHLTで止まると、Sleepしてしまい、PITも止まってしまうことになるのかな。
もう1つ、host_alarm_handlerがホストの時間に従って、割り込みを入れているようなんだけど、これって、どういう役割になるんだろうか。
あまりよくわかってなくて書いているので、間違っているかも。