前回記事の、検証を実際にやってみた。
1)ゲストマシン環境下では実質、シリアルは最大4ポートが限界
QEMUが440BXをベースとしているせいかIRQが足りない(笑)。
IRQが15までしかないようで空き状況を考えると、4ポートが限界です。
※ゲストOSが対応しているPCIシリアルカードをPCIパススルーとかすれば、これはこれでできるかもしれない。
今回はターゲットOSがMS-DOSだったため、これは難しかった。MCDPC.EXEが対応している必要があったので。
シリアルポートは、マッピングでQEMU側でも4ポートをサポートしている。
例えば、ホストマシンの/dev/ttyS4~S7をゲストマシンのCOM1~4に割り当てるためには、QEMUの起動オプションに、
-parallel none -serial /dev/ttyS4 -serial /dev/ttyS5 -serial /dev/ttyS6 -serial /dev/ttyS7
を追加する。IRQ消費を防ぐためにパラレルポートは削っておく。
すると、ゲストマシン環境下では、下記のようにI/OaddrとIRQが割り当てられる。
COM1 = 3F8, IRQ = 4 < ---- COM1 COM2 = 2F8, IRQ = 3 <---- COM2 COM3 = 3E8, IRQ = 4 <---- COM3 COM4 = 2E8, IRQ = 3 <---- COM4しかしこの状況のゲストマシン環境下ではゲストOSにもよるのだが、上記の手法では、IRQの4と3が競合して問題が発生してしまった。 MS-DOSはもちろんWindowsXPでも競合問題が解決できなかった。 つまり、このままでは2ポートまでしか認識できない。ISAとして認識してるようである。 今回どうしたかというと、競合を回避するためにIRQを変更してみた。 変更方法としては、QEMUのオプションで変更方法がないようなので、QEMUをソースインストールしパッチを当てる。I/OaddrとIRQは、
COM1 = 3F8, IRQ = 4 < ---- COM1 COM2 = 2F8, IRQ = 3 <---- COM2 COM3 = 3E8, IRQ = 5 <---- COM3 COM4 = 2E8, IRQ = 7 <---- COM4となるようにすることとする。最新版をダウンロード。
# tar zxvf qemu-kvm-0.14.0.tar.gz # cd qemu-kvm-0.14.0 # vi hw/serial.c (下記部分を修正) ----- static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 }; ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 5, 7 }; ----- # make clean # ./configure \ --disable-spice \ --disable-sdl \ --disable-xen \ --enable-mixemu \ --enable-vnc-thread \ --enable-kvm # make # make install
とすることで、回避できた。
ちなみにMS-DOSだとCOM4がMCDPC.EXEは認識するのだが、WindowsXP環境のDOS窓環境でMCDPC.EXEを動かすとCOM4が認識しなかった(謎)。
ということで、MS-DOSを使うことになりました。
ちなみにゲストOSがCentOSの場合で、ゲスト側のIRQを変更する場合は、こうするとできそうだが未検証。
Linuxカーネルのソースを修正(下記部分を修正)
# vi linux/arch/x86/include/asm/serial.h ----- #define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ #define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 5, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 7, STD_COM4_FLAGS }, /* ttyS3 */ -----
2)MS-DOSのCPU1コア100%の件
ゲストマシンのOSがMS-DOSの場合、アイドル状態(コマンドプロンプトによる入力待ち等)になると、アプリケーションによってはCPUを占領されてしまう。何にもしない無限ループでCPUを占領(笑)。
VMwareで公開されていた、DOSIDLE.EXEを常駐させてみると、コマンドプロンプト等ではCPU負荷は下げられたが、アプリケーションによってはCPUが占領された(アプリの作り方によるもの。当時はこれが主流だった)。
これはもうどうしようもない(笑)。結局、MS-DOSにCPU1コア分を割当てるような状況になってます。^^;
とりあえず、仮想環境で5マシンをVM化してみた。相変わらず1コアだけが100%。(T_T)。
まぁ、これでしばらく使ってみたいと思います。