Friday, May 24, 2013

Return to Linux, Compiling QEMU with MinGW.

I've begun my adventures with Raspberry Pi, for this summer.  I'm hopping to get the kids up to speed on some of the finer points of computer programming and computer architecture.  Something beyond the Apple app store.  So my first Raspberry Pi "project" was to get the Raspbian OS running on Windows so I could poke around at it.  This was fairly straight forward, all you need is to download the image and click.  Apple App store revised.

So playing with the pre-built Win32-Qemu binaries with Raspbian did show a few errors.  The first and foremost is that it isn't emulating a RPi at all.  It is actually emulating a Versatile board which is close to the RPi but only just.  The solution is to grab a branch of Qemu that has been patched to emulate RPi.  So now the fun begins... How to compile Qemu for Win32 without Linux?  Well the supported answer is MinGw used to compile.  Problem is... Qemu seems to have some *VERY* sloppy bounds checks and the code is absolutely trashing memory.  The Windows loader shuts it down as soon as it sees "bad" behavior.  Others seem to have the build working better, but I've yet to find their magic combo.  Here's my not so magic combo.

Abridged version for those with short attention
wget mingw-get-inst-20120426.exe
wget python-2.6.6.msi
wget gtk+-bundle_2.24.10-20120208_win32.zip
wget SDL-devel-1.2.15-mingw32.tar.gz
wget qemu-1.4.1.tar.bz2
unpack_all.sh
install_all.sh
cd SDL-lib && make native
cd qemu-src && ./configure
make && make install
Straight forward enough, and compiles, but throws exceptions on execution. Now for the deeper dive


0) Grab cygwin, for wget.exe and unzip.exe on your own

Cygwin is easy enough to get, just download setup.exe from http://www.cygwin.com .  Once the installer launches, choose the default options.  Most people just install to c:\Cygwin.  Durring setup you can search for packages.  I just make sure I have wget and unzip selected.  When the install is finished (takes a while) you should be able to call wget and unizp by simply calling c:\cygwin\bin\wget.  Don't add the bin directory to your path as it could conflict with MinGW.


1) Grab and install mingw-get-inst-20120426.exe.

This is pretty easy, just go to http://www.mingw.org and grab the binary mentioned from download.  Once grabbed, run the installer and install EVERYTHING except ADA and Fortran (unless of course you really want to.


2) Grab and install python-2.6.6.msi.

Same deal, download the 2.6 msi from http:\\www.python.org and follow the prompts


3) Grab and install the Gtk+ multipass.

Again, we start with, obvious enough http://www.gtk.org.  Fish around and grab the zip.  This is where we start to get technical.  Gtk+ has a "bundle" that you can grab that will put in all your dependencies, and there are a few.  This "multipass" means the only outstanding dependency is SDL.  In any case, when you installed (1) you should have gotten a C:\MinGW directory.  Under that directory are the lib, include and bin directories that the bundle is going to land stuff in.  So... just unzip gtk+-bundle_2.24.10-20120208_win32.zip directly into C:\MinGW and your compiler should find all the goodies.


4) Grab and install the SDL libraries.

This starts simple enough.  Download the SDL libraries from http://www.libsdl.org.  Now, unlike Gtk+, we are going to install these in the "/usr" hierarchy.  To do this properly, we are going to drop into a MinGW shell.  Back in step (1) we should have gotten a "MinGW Shell" icon that launches something called MSys.  So the way this plays out is as follows.
a) Save the .tar.gz file to C:\MinGW\msys\1.0
b) Launch the MinGW Shell from start menu / button / icon
c) Once in the shell type "mkdir /usr/src && cd /usr/src"
d) Then untar with command "tar -xzvf ../../name.tar.gz"
e) Now install with "cd libsdl && make native"
Sounds weird, but that should have done the trick.  I would have opt'ed for "make install" on (4e) but "make native" is really what they want.

5) Finally grab and expand QEMU source.

The QEMU source is located at http://wiki.qemu-project.org/.  Just as before we are going to drop this tarball in C:\MinGW\msys\1.0.
a) Save the .tar.gz file to C:\MinGW\msys\1.0
b) Launch the MinGW Shell from start menu / button / icon
c) Once in the shell type "cd /usr/src"
d) Then untar with command "tar -xzvf ../../name.tar.gz"
From here we are getting to the meat of the matter.

6) Run ./configure in QEMU

In linux, as I recall, there are configure scripts to "prep" the source for compilation.  The ./configure script has help, so it might be worth running ./configure --help to learn more.  Basically the only option I provided was the python path.  I also added a prefix so I didn't pollute my Program Files.  You may need to mkdir /usr/bld.
a) cd QEMU-src-dir
b) ./configure --python=c:/Python26/python.exe --prefix=/usr/bld

7) Now we pull the trigger... Make QEMU

This is easy enough, but takes a while.
a) cd QEMU-src-dir
b) make && make install

8) Now we need something to test

Although you may have a linux image you want to test, best start with something simple.  Turns out QEMU links to some simple linux images to standardize this process.  We will grab the simplest from http://wiki.qemu.org/Testing.
a) Download linux-0.2.img.bz2
b) Save the file to C:\MinGW\msys\1.0\bld
c) Un-bzip the image "bzip2 -d linux-0.2.img.bz2"

9) Now we test our build

Keep in mind that I actually added "--prefix=/usr/bld" to my ./configure arguments, so my qemu files are not where they are "supposed" to be.  Now I'm going to test this from a MinGW shell so that all the dependencies map out correctly, but other tests fail equally.
a) cd /usr/bld
b) ./qemu-system-i386 linux-0.2.img
Initially things look good, but fail quickly after the disk is mounted.  Looking through the errors, they all seem to be of type 0xc0000005 which is generally an access violation.  A program reading or writing from memory it is not supposed to.  On some systems it throws a DEP exception which seems right in line with a 0xc0000005.  I've tried various options like -nographic to exclude SDL.dll from consideration, and all combinations seem to fail.  I'm tempted to say that QEMU just doesn't work on Windows... except... some people are managing to build for Windows like http://www.omledom.com/.  It is possible that they are cross-compiling these binaries from Linux, but for the fact that QEMU.org seems to claim that QEMU will build (and presumably run) when built under MinGW.  I just don't see how.

4 comments:

  1. Posted the question to the QEMU-devl mailing list, as well as contacting the omledon.com webmaster to try to learn some tricks of the trade.

    ReplyDelete
  2. Fixed... Kinda. Using the above config with "--enable-debug" cures the access violations. Or.. using the better MinGW toolchain fixes it too. But both approaches cause the performance to be through the floor.

    ReplyDelete
  3. Hi Dan,

    Did you manage to cross compile W32 qemu on Linux?
    If I'm not mistaken, you have to cross-compile zlib first, then qemu.

    And this is how I build zlib:
    make -f win32/Makefile.gcc CC=/usr/bin/i586-mingw32-gcc RC=/usr/bin/i586-mingw32-windres

    The problem is I don't know how to configure qemu to use that zlib... :D

    I'm using 64-bit Debian, anyway.

    ReplyDelete
  4. No, I didn't compile FromLinux->ToWin32, I compiled FromWin32->ToWin32. For Debian, you just grab the zlib binaries "apt-get install zlib" or "apt-cache search zlib" for other options.

    ReplyDelete