Linuxカーネルのメモリーマップ

Linuxカーネルが、メモリーをどのように使っているのか少し検索してみました。
解説サイトを見てみると、0から3GB(0xC0000000)まではユーザー空間、3G(0xC0000000)から4GBまではカーネル空間で、3GB以降は物理メモリの0から1GBまでにマップされているとあります。
また、最近のカーネルではゾーンにより使い方は異なり、
ZONE_DMA 0 - 16MB
ZONE_NORMAL 16MB - 896MB(0x38000000)
ZONE_HIGHMEM 896MB -
の3つに分かれている。ZONE_HIGHMEM領域はZONE_NORMALにマップされて使われる。x86では、0 - 128MB(0x08000000)まではカーネルのデータの保存に使われる。
のだそうです。
ところが、Linux.imgのログを調べて、どんなアドレスを使っているのか見てみると、0x90000000以降のアドレスが出てきて、全然3GB以降ではないのです。
なんか変だと思い、RedHat 7.2も調べてみました。
RedHat 7.2 Linux 2.4.9-13 0xC0000000以降
RedHat 9 Linux 2.4.21 0x90000000以降
RedHat 7.2は、解説の通りになっています。でも、RedHat 9は違うのでした。カーネルが2.4系列なら大きな変更はないものと思っていましたが、メモリの扱い方が違うのですね。それとも、RedHat 9はそういうオプションで作られているのでしょうか。
もっと調べてみると、Fedora Core 4もレスキューCDは、0xC0000000だけど、インストール済みのものは0x90000000だったりする。謎だ。

VNC Server

CVSに、VNCサーバの機能が取り込まれました。
qemu -L ../pc-bios -hda linux.img -vnc 1
とすると、display 1(ポート5901番)を使えます。画面を表示するには、TightVNCなどのクライアント
をつかって、localhost:1とします。
Windowsホストでも動きました。
keymapsが無いというエラーがでたら、keymapsディレクトリごとpc-bios以下にコピーすればいいです。
また、-usb -usbdevice tabletオプションとともに使うと、マウスも捕捉する必要がなくなります。
qemu -L ../pc-bios -hda linux.img -vnc 1 -usb -usbdevice tablet

マウスの捕捉

CVSに、マウスが画面に自動的にグラブされる機能が追加されています。
-usb -usbdevice tablet
というオプションを付けると、Windows 98以降のOSで、今までのようにCtrl-Altを押さなくてもよくなります。

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サービスを止めること。
でした。

仮想化やクラウドについて