kqemu-1.3.0pre6

新しいKqemuのバージョンが出ています。
Windows上で動かしてみたけど、動かなかった。
Linux上だと、RedHat 7.2が起動するようになっています。まだエラーメッセージが出ますけど。Fedora Core 4のレスキューCDも動かないです。Windowsは動きます。

savevmとloadvm

savevmとloadvmを使えたら、ゲストの起動が速くなっていいなと思い、FC4ゲストで使ってみました。ところが、read only file systemというエラーがでてファイルが書き込めなくなり、再起動してみるとfsckの雨あられ。結局、2度と起動できないイメージになってしまいました(涙)。
調べてみると、Linuxはメモリーにハードディスクのディスクキャッシュを保存しています。これが、実際のハードディスクの内容と異なってしまうと、次に書き込んだときに全く変な書き込みをすることになることが原因のようです。
つまり、savevmをした後、ファイルの操作をしてハードディスクの内容を変更した後QEMUを終了し、次にloadvmで立ち上げるとだめ、ということらしい。
これをなくすには、QEMUモニターでsavevmをしたらすぐに終了します。
(qemu) savevm save.img
(qemu) quit
次回立ち上げるときは、-loadvmオプションで立ち上げます。
[host] ./qemu -L ../pc-bios -hda linux.img -loadvm save.img
これでしばらく使ってみると、なんとか壊れずに動いているようです。最初から再起動してみると、すこしハードディスクのチェックが入りますけど。
開発で、QEMUがフリーズしてしまうなどのときは、こまめにsavevmをしておくのがいいみたいです。savevmの後ファイルをいじってしまった場合は、素直に最初から立ち上げ直しましょう。
それでも、壊れることがあるけれど。
KNOPPIXなどのCD-ROMベースのOSとは相性がいいと思います。ハードディスクイメージを1つ用意し、mountして使うとファイルを作ったりできるのでいいと思います。その場合、mountする前の状態をsavevmで保存しておきます。そして、mountして使用し、終了時にはumountして終了します。
次回の起動時は-loadvmを使うとマウント前の状態にすぐ戻りますから、時間の短縮になっていいです。mount作業が少し面倒になりますけど。やってみると、rootの権限でmountされるので、rootでしか保存したりできないのが少し問題かなと思った。
使い勝手をよくするには、ハードディスクのスナップショットと同時にメモリーの内容も保存できると、このような面倒がなくていいのですけどね。
それと、loadvm後は、Ctrl-Altを押した状態になっています。Ctrl-Altをもう一度押さないと普通の入力はできないのであしからず。
追記
某掲示板より、stop->savevm->quitの順番でやると安全性が増すそうです。
-kernel-kqemu -no-kqemuは、つけたりとったりしても大丈夫です。-m 256などのハードウェアの構成は変えてはいけないですけど。

gdb二刀流

ホストOS上でgdbの上でQEMUを動かし、そのゲストOS上でまたgdbの上でQEMUを動かすと、gdb二刀流みたいなことができます。
ゲストOSの中のQEMUは、-m 32でメモリを少なめにしないといけないけど。
どうしてこんなことを考えたかというと、Qvm86が動作した時、ホストのCPU上でどんなことが起こっているのか知りたくなったからです。
gdbstubを使った、gdbのリモート接続を使うと、三刀流とか四刀流もできたりするけど、使いこなすのは難しいかも。
まず、何を見たらいいのかわからないのが一番の問題だったりする。

x86_64 Linuxホストのタイマー

時計が不安定な理由がわかりました。cpuspeedサービスというCPUの周波数を変更するサービスが私のx86_64ホストでは動いて、それで時計が安定しなかったのでした。サービスを停止したら、時計がちゃんと動きました。
今まで、こんなサービスが動いているなんて知らなかった。Fedora Coreも、何もしなくてもSpeedStep/PowerNow!で省電力が有効になるところまで整備されてきたんですね。
Linuxホストでの、時計を正確にする方法をまとめると、
(1)max-user-freqを1024にすること。
(2)cpuspeedサービスを止めること。
でした。

Win2kとRTC

RTCのタイマーは、PICに割り込み終了の合図を送ることで動くようになりました。
ところが、Win2kは起動時にこそRTCを見に行くのですが、その後ぜんぜんアクセスしていないことが判明。x86_64 Linuxホストで、Win2kの時計が不安定な理由がRTCではないかと思ったのですが、徒労に終わった。せっかく作ったんですけどね。
その代わり、Win2kゲスト上でインターネットエクスプローラを立ち上げると、PITにアクセスしていることが判明。何をしているのかわからないけど。
それと、timeoutを0にすると、時計が2倍くらい速くなることが判明。割り込みも速くなっています。バグがうまく再現できているみたい。x86_64 Linuxホストでの時計の不安定さは何とかできそうな気がする。気のせいかも。

CPUのループ

QEMUは、cpu_execの中の大小2つのループでCPUの動作をエミュレートしています。大きいほうは、割り込みが起こったときにCPUの状態を変化させることをしています。小さい方はゲストのコードを解釈してダイナミックトランスレートして実行します。
少し気になったので、1秒あたりのループの回数を調べてみました。
大きいほうが、1秒間に2000回くらい、小さいほうが120000回くらいでした。ゲストのコードを実行しながら時々割り込みの対処をするといった感じでしょうか。

Linuxのタイマーパッチ

Linuxホストのタイマーのパッチを作りました。いろいろ試行錯誤したのですが、結局いつも/dev/rtcを使うようにトライしてみるようにするだけでした。
http://www.h7.dion.ne.jp/~qemu-win/download/qemu-20060407-linux-timer.patch
時計を正確にするには、2つのことをしてください。
(1) まず、ホストOSで、rootでmax-user-freqを1024に設定します。
[Linux host]#echo 1024 >/proc/sys/dev/rtc/max-user-freq
ホストOSを起動するごとに設定する必要があります。/etc/rc.d/rc.localに書いておくといいと思います。
(2) パッチをあてて、バイナリを作ります。patch -p0オプションで当てられます。
必須なのは、max-user-freqを設定することです。最近のカーネルならば、パッチは必要ないと思います。kernel-2.6.11-1.1369_FC4ホストではパッチが必要でしたが、kernel-2.6.15-1.1831_FC4ホストではその必要がありませんでした。
max-user-freqを設定しないと、Windows 2000でIEを立ち上げたとき、時計が速くなったり遅くなったりします。
タイマーは、RTC(Real Time Clock)が使えると1msのタイマーが使えます。Linux 2.6ゲストの時計が正確になります。そうでないと、setitimer/getitimerで設定していますが、これがLinuxゲストで時計が1/2に遅くなった原因でした。最近のカーネルでは、時計は1/4に遅くなると思います。
テストした環境は、次のとおりです。
Windows 2000 guest /FC4 kernel-2.6.11-1.1369_FC4 host
FC4-i386-rescuecd.iso guest/FC4 kernel-2.6.11-1.1369_FC4 host
Windows 2000 guest/FC4 kernel-2.6.15-1.1831_FC4 host
FC4-i386-rescuecd.iso guest/FC4 kernel-2.6.15-1.1831_FC4 host
Linux 2.4のホストではテストしていません。
x86_64のホストでは、Windows 2000ゲストの時計がとても不安定です。1ms間隔の割り込みは起こっているのですが、時計がうまく動きません。遅れることはないみたいだけど。

Linuxのタイマー

Linuxホスト上のタイマーを調べています。必要なのは、max-user-freqを1024にすることだということはわかりました。rootで実行します。
[Linux host] # echo 1024 >/proc/sys/dev/rtc/max-user-freq
これだけでも、時計が安定する場合もあります。もう少し調べてみます。