2012年06月13日
QEMU 1.1.0 が Windows (MinGW) 環境で正常動作しない不具合と回避方法
以前 QEMU 1.0.1 をビルドしたのですが、RAM ディスクで arm-test ぐらいは動いたものの、Debian を qcow2 イメージからブートさせることはできませんでした。
これはどうやら、私のビルド環境の問題などではなく、既知の不具合だったようです。
これはどうやら、私のビルド環境の問題などではなく、既知の不具合だったようです。
QEMU 1.1.0 がリリースされたので、同じようにビルドしてみたのですが、結果は同じでした。
configure 後に生成される config-host.mak の CFLAGS を修正して、-O2 を -O0 にすれば動作する点も 1.0.1 と同じでした。
(ただし、version.rc のビルドエラーは修正されたようです。)
Qemu On Windows のサイトで、1.1.0 の正常動作するバイナリが配られていないかな?と確認しにいったところ、以下のような記述を発見しました。
2012/6/21 追記
gcc の pragma GCC を以下のように使用して、coroutine-win32.c の最適化を抑制するという方法でも上手くいきました。
February 29, 2012: updated for Qemu-1.0.1 - Still a "to be tested" version. See bug report win32: git rev 59f971d crashes when accessing disk (coroutine issue). In my version a workaround was to compile coroutine-win32.c without optimisation (-O0): contains qemu-system-arm.exe, qemu-system-i386.exe, qemu-system-ppc.exe, qemu-system-sparc.exe, qemu-system-x86_64.exe and the linux-0.2.img imageどうやら TLS 絡みで、コルーチンライブラリが正しく動作していないようです。GCC 4.6.2 依存?(私の環境も GCC 4.6.2 です。) というわけで、以下のように、普通にビルドしただけでは動作しないことと、
$ tar jxvf qemu-1.1.0-1.tar.bz2以下のように、coroutine-win32.c だけを -O0 でビルドしてリンクしなおしたバイナリは Debian が動作することを確認しました。(ちなみに、QEMU の make 時に、gcc にどのような引数が渡されているのかは、make V=1 とすることで確認できます。)
$ cd qemu-1.1.0
$ mkdir bin
$ ./configure --prefix=/c/kmc/qemu/qemu-1.1.0/bin --target-list=arm-softmmu --python=/c/Python27/python.exe --disable-strip
$ make
$ make install # ここまでは MinGW Shell 上での作業
> cd c:\kmc\qemu\qemu-1.1.0\bin # ここからはコマンドプロンプト上で実行する必要があります。
> qemu-system-arm.exe -m 256 -M versatilepb -hda debian_lenny_armel_xwindow.qcow2 -append "root=/dev/sda1 mem=256m" -kernel vmlinuz-2.6.32-5-versatile -initrd initrd.img-2.6.32-5-versatile
*** stack smashing detected ***: terminated # 途中で abort() してしまう。
$ gcc -I/c/kmc/qemu/qemu-1.1.0/slirp -I. -I/c/kmc/qemu/qemu-1.1.0 -I/c/kmc/qemu/qemu-1.1.0/fpu -m32 -D__USE_MINGW_ANSI_STDIO=1 -DWIN32_LEAN_AND_MEAN -DWINVER=0x501 -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fstack-protector-all -Wendif-labels -Wmissing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -IC:/MinGW/include/libpng14 -mms-bitfields -IC:/MinGW/include/glib-2.0 -IC:/MinGW/lib/glib-2.0/include -I/c/kmc/qemu/qemu-1.1.0/include -MMD -MP -MT coroutine-win32.o -MF ./coroutine-win32.d -O0 -g -c -o coroutine-win32.o coroutine-win32.c
$ make
$ make install
2012/6/21 追記
gcc の pragma GCC を以下のように使用して、coroutine-win32.c の最適化を抑制するという方法でも上手くいきました。
--- coroutine-win32.c.orig 2012-06-21 14:42:37 +0900 +++ coroutine-win32.c 2012-06-21 14:43:38 +0900 @@ -21,6 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#pragma GCC push_options +#pragma GCC optimize ("O0") #include "qemu-common.h" #include "qemu-coroutine-int.h" @@ -90,3 +92,4 @@ { return current && current->caller; } +#pragma GCC pop_options