Thursday April 28, 2005 QEMU is a generic and free open source process emulator, and has the ability to run practically any operating system across platforms.
Well, almost.
I found this code about a month ago, and with some help from other Solaris type developers, google and the qemu-developers mailing list, I've been able to get the code working under Solaris 10, 32-bit X86. So far, I've been able to install Win98SE, Win2KPro, Win2K Svr SP4, WinXP Home upgrade and Win 2003 Server under QEMU on a Solaris host. In addition, JDS3, Solaris 10, and Solaris Express work, as well as things like the Knoppix live CD.
Windows products are most finicky. Win98SE actually runs pretty decently on my Toshiba M2, now that I added configure support for OpenSounds' OSS Audio driver. I've got an image that has all the latest patches, Real Player, Adobe Acroread 6.0, Quicktime, Flash/Multimedia plugins and the latest Mozilla product suite (Firefox, Thunderbird and Mozilla). Why Windows 98SE? It's very lightweight, and there are two patches for it. One which implements the halt instruction properly so when I leave the qemu instance idle, it's not sucking the CPU down. And second, the power management actually turns itself "off" so I don't actually have to quit from the qemu monitor session (Which you get into by typing "ctrl-alt-2")
However, getting Win2K, XP Home and Win 2003 installed can be somewhat traumatic. The emulation is not quite perfect, so the virtual machine tends to hiccup, especially during installs. There is a well-known bug when installing Win2K under QEMU, and manifests itself by filling up the virtual disk. This can be worked around by going into the QEMU monitor (ctrl-alt-2) and stopping the instance and restarting. I've done this a few times, and mostly it never worked. I eventually figured out from a QEMU user's mailing list posting that you can work around this problem by adding -hdachs cylinders,heads,sectors to the the start line for qemu, such that the virtual disk is has 16 heads and 63 sectors/per cylinder, and just do the math to divide the size of the virtual disk by (16*63*512) to get the number of cylinders.
However, I've found out that often times when I've gotten a Windows install to work, I can't patch it. Some technology called Slipstream which allows you to take a Windows install CD and add patches to it becomes very attractive, especially since the patching isn't quite 100%. I'll eventually figure out if this works and post how it goes.
The most current release of QEMU (0.7.0) available at http://fabrice.bellard.free.fr/qemu/download.html and the patch against qemu-0.7.0 to make it compile under Solaris 10/X86 is found at qemu-0.7.0-solpatch-050504. To configure and build QEMU-0.7.0 for Solaris, I used gcc-3.4.3, gmake, gnu fileutils and libSDL-1.2.8 from www.blastwave.org. If you've never used Blastwave's tools, checkout the website. It has a script called pkg-get which is Solaris derivitive of the Debian apt-get tools. The Blastwave Solaris packages all have dependencies, which pkg-get will automagically download and install for any package you download. In addition, the sound drivers at www.opensound.com can be downloaded and used for several months if you don't want to buy a license. They definitely seem to work better than using the stock Solaris audio driver, but that could just be a feature of the SDL library.
Once you have the the code downloaded, cd to the directory holding qemu-0.7.0/ directory and run
gpatch -p0 < qemu-0.7.0-solpatch-050504
to patch the current code. The configure script can be run like this depending on whether you have OSS sound drivers or not.
./configure --prefix=/tmp/qemu --with-oss=yes --oss-inc=/opt/oss/include or ./configure --prefix=/tmp/qemu --with-oss=no # if you don't have the OSS Sound drivers
If you're wondering why I used the prefix to be in /tmp/qemu - The code is quite "beta". You don't have to be root to run the code and given the fact that development on the code is going pretty quickly, I find this a very easy way to test out a set of patches or changes, without having to worry about stuff being left on the hard drive.
Here's an example shell script I use to start most images. I edit the first lines if I want to be able to get back to the virtual machine using the redir parameters :
#!/bin/bash
#
#CONFIG - set the USE variables to a value if you want their config
# value below to propogated into the QEMU start line.
#
USE_LOCALTIME=1
USE_SSH=1
USE_TELNET=1
USE_FTP=1
USE_FDA=
USE_CDROM=1
USE_AUDIO=1
USE_BOOT=1
USE_KEYMAP=1
USE_LOADVM=
USE_MEMORY=1 # should always have this defined
USE_HDA=1
#
##########################################################################################
#
# LOCALTIME_CONFIG : "-localtime" # whether to use localtime from the bios or not
#
LOCALTIME_CONFIG="-localtime"
#
# SSH_CONFIG : -redir tcp:5022:10.0.2.15:22 - redirect tcp port 5022 on the host OS
# to tcp port 22 in the guest OS.
# : -redir udp:5022:10.0.2.15:22 - redirect udp port 5022 on the host OS
# to udp port 22 in the guest OS
# This SSH_CONFIG is for allowing systems outside the HOST system to access the
# guest OS via SSH on port 5022 on the Host. The TELNET_CONFIG and FTP_CONFIG
# work the same way. FTP is a bit funky, in that you have to use passive mode
# often because of how the port redirector code works since it's part of the host.
#
SSH_CONFIG="-redir tcp:5022:10.0.2.15:22 -redir udp:5022:10.0.2.15:22"
TELNET_CONFIG="-redir tcp:5023:10.0.2.15:23"
FTP_CONFIG="-redir tcp:5021:10.0.2.15:21 -redir udp:5021:10.0.2.15:21"
#
# FDA_CONFIG : "-fda /vol/dev/rdsk/floppy/unnamed_floppy" to give access to the real floppy
# "-fda /export/src/iso/DU.img" to give access to the virtual floppy image DU.img
#
FDA_CONFIG="-fda /export/src/image/Knoppix_3.8/save_floppy.img"
#
# CDR_CONFIG : "-fda /vol/dev/rdsk/c0t0d0/knoppix" to give access to the real cdrom
# "-fda /export/src/iso/Knoppix-3.8.iso" to give access to a virtual cdrom through the iso image
#
CDR_CONFIG="-cdrom /vol/dev/dsk/c0t0d0/knoppix"
#
AUDIO_CONFIG="-enable-audio"
#
# BOOT_CONFIG : "-boot c" to boot off of first hard disk
# "-boot d" to boot off of second hard disk or CDROM
#
BOOT_CONFIG="-boot d"
#
# KEYMAP_CONFIG : "-k
This script sets up to run a qemu session with a 384MB memory segment, has a virtual CDROM that is actually the physical cdrom device in Solaris containing the Knoppix CD. You may also use an ISO image of a disk. "-boot d" tells qemu to boot from the CDROM, as opposed to "-boot c" which would be to boot from the first hard disk. The "-user-net" is a slirp based network config which uses a NE2000 driver interface to the guest OS, to make a connection out of the machine.
SLIRP networking in QEMU
The QEMU process provides a network layer to the Guested OS. As an example, to get Solaris 10 working under QEMU, you have to use the Install Time Update found at the Community Boot Driver ITU Floppy which has a specially modified version of the ni (ne2000) driver written by Masayuki Murayama and modified by Juergen Keil to work in the QEMU guest running Solaris. If you are using the -user-net option, the QEMU process sets up it's own internal DHCP and DNS servers, as well as a default router. The default address for the client is normally 10.0.2.15. This works very well, but because it's a user level process, it's much harder to get back to the virtual machine. The above redir parameters setup access back to the virtual machine, by having QEMU open up listeners on the ports specified, and then redirecting the traffic down through the slirp stack to the guest OS. An annoying side effect of using some internal software I use called inetmenu (which configures the networking correctly at boot time) caused my systems' default name to have a address of 127.0.0.1. What this did was screw up the "source" ip address on the packets entering the QEMU guest OS, which it never responded to. Eventually I figured out that problem, and solved it by doing a "telnet 192.168.30.151 5023" instead of a "telnet 127.0.0.1 5023". The reason this works on most systems is the hostname is usually not tied to localhost or 127.0.0.1. Once I use the real IP address of the Host system, qemu properly translated the packets to the guest OS, and I was able to log in.
Video as part of QEMU
The video config of the Virtual machine is a Cirrus Logic 5446. Under Solaris Xfree86 (Xsun), you can squeeze 1152x900 at 16-bits no problem. Getting it to work with Xorg is a little trickier. Knoppix has no problem driving the video at 1152x900 @ 16-bits.
Audio as part of QEMU
Audio config is a sound blaster 16, which seems to work ok. Though I've noticed better sound quality when using the OSS sound drivers. I think the libSDL is not very well optimized and I haven't had time to recompile it with a better compiler and under Solaris 10.
Another nice feature is the image files are easy to backup. All you need is disk space. I used a copy of a Win98SE image that I had installed to do the XP Home Upgrade. I didn't have any luck booting from the WinXP Home upgrade disk and having it recognize the Win98SE disk (or NT4 or any other valid Windows media I had). However, since you can start the upgrade to XP Home by booting into Win98SE and running the setup off the CDROM image, that's how I successfully got a working Win XP Home image. But QEMU is probably the biggest use of disk space that I have these days as I'm constantly retesting images and such.
Posted by Eric on April 29, 2005 at 07:26 PM EDT #
Posted by Gero Vermaas on August 25, 2005 at 04:51 AM EDT #
Posted by C.K.Kashyap on September 01, 2005 at 07:33 AM EDT #