For developers‎ > ‎


This page is about running PureDarwin on the QEMU emulator and is not about running Mac OS X.

QEMU is a hardware emulator that can be used to run operating systems on virtualized hardware, not unlike VMware or Parallels. It is an open source project.
The ability to run PureDarwin on emulated hardware can be very useful, especially for development, testing and debugging.

If you get the "Error parsing plist file", then you need to increase the amount of virtual RAM. At least 330 MB seem to be required. If the kernel just crashes and the boot prompt appears again, press F8 and enter mach_kernel.voodoo <enter>.

Running PureDarwin Xmas on QEMU

On Linux hosts

To get PureDarwin Xmas to run in QEMU, fetch QEMU from svn, compile, run without kqemu (it might work on OSX-supported cpus). Update: if you can get a 0.10 binary of qemu for your platform (some are linked below), you don't necessarily need to compile from svn any more. Update 2: As of Ubuntu 9.10, the QEMU that can be installed with sudo apt-get install qemu is sufficient, so you don't need to compile or download a special version of QEMU any more. Use the following configuration:

-hda someemptydiskimage (if you want some disk to work on) -hdb puredarwinxmas.vmdk -cdrom purdarwinxmas.vmdk -boot d -m 512
-hda puredarwinxmas.vmdk -cdrom purdarwinxmas.vmdk -boot d -m 512
-hda puredarwinxmas.vmdk -cdrom purdarwinxmas.iso -boot d -m 512

QEMU can (at least on some platforms) emulate the Realtek RTL8139 network interface.
An open source driver for this NIC is included with PureDarwinXmas. Enable the interface in QEMU with the -net nic,model=rtl8139 -no-kvm-irqchip -net user option.
Run it using the instructions above (although -hda puredarwinxmas.vmdk -cdrom puredarwinxmas.vmdk -boot d -m 512 seems the more reliable option).
X will probably fail to start first time, but can then be kicked into life with startx or pd_startx.

PureDarwin Xmas running on openSUSE. Credits: oxygene 

PureDarwin Xmas on Ubuntu 8.10 (using the binary linked below) and mach_kernel.voodoo. 

Command used:
qemu -hda 'puredarwinxmas.vmdk' -cdrom 'puredarwinxmas.vmdk' -boot d -m 512
press F8 when asked
Then have to launch X11 manually:

On Windows hosts

PureDarwin Xmas on MS Windows XP (using the binary linked above).
Credits: oxygene

On Mac OS X hosts

QEMU 0.10.1 from MacPorts can run PureDarwin Xmas with
qemu -hda puredarwinxmas.vmdk -cdrom puredarwinxmas.vmdk -boot d -m 512

Note: if you want to run qemu from a different location, use the -L option as:
qemu -L ./pc-bios/ -hda puredarwinxmas.vmdk -cdrom puredarwinxmas.vmdk -boot d -m 512

If you don't boot by default with the Voodoo kernel (xnu-dev), at boot press F8...
And enter
mach_kernel.voodoo rd=disk1s3 -v

or, if you have the vmdk as -hda:
mach_kernel.voodoo rd=disk0s3 -v

Wait for a bit on failed to open/create the journal... if that happens.
At the end of the KEXTs decompression phase, the CPU FSB clock and ration should be adjusted by the voodoo kernel.
After the KEXTs decompression phase, you should see the kernel booting (notice the network adapter supported).
Then depending your settings, a login prompt or X should be waiting for you.
It is necessary to launch X11 manually by issuing /usr/X11R6/bin/startx.

QEMU 0.10.1 from MacPorts running PureDarwin on Mac OS X 10.5.

QEMU devices

Here is a list of potential devices found in a QEMU guest OS.

"0x1013","0x00B8","Cirrus Logic","CL-GD5446","64-bit VisualMedia Accelerator"
"0x8086","0x7000","Intel Corporation","82371SB","PIIX3 PCI-to-ISA Bridge (Triton II)"
"0x8086","0x7113","Intel Corporation","82371AB/EB/MB","PIIX4/4E/4M Power Management Controller"
"0x10EC","0x8139","Realtek Semiconductor","RTL-8139/8139C/8139C","Realtek RTL8139 Family PCI Fast Ethernet NIC"
"0x8086","0x7010","Intel Corporation","82371SB","PIIX3 IDE Interface (Triton II)"
"0x8086","0x1237","Intel Corporation","82440LX/EX","PCI & Memory"

QEMU network

The dawn of networking support in PureDarwin finally appears with QEMU.

QEMU vlan network capability is entangled with the "user mode network stack".
This network stack supports ip, tcp, udp, dhcp, tftp, etc.. but ICMP.
It also acts as a proxy between the qemu process and the target process, with tcp/udp data field decapsulation and forward.

The user network stack

Credits: Partial network support already existed, thanks to "hingwah" who helped and pointed its existence to us.

As said in 3.7.3 Using the user mode network stack QEMU documentation ("The DHCP server assign addresses to the hosts starting from"), the interface is well auto-assigned (notes: KernelEventMonitor (confid_plugins) has been added and seems to be responsible of the client DHCP capability) as the route to the virtual available gateway (a firewall / dhcp server).


Append -net user if it is not already there to the qemu command line:
[...] -net nic,model={i82551|i82557b|rtl8139} -no-kvm-irqchip -net user [...]

Be prepare to ping the gateway continuously, it's a workaround.
As user inp reported on #puredarwin, adding '-no-kvm-irqchip' to the qemu call solves this issue with the rtl8139 driver.

Of course, it's mandatory to have a Kernel EXTension matching its respective device.
E.g. below with the realtek kext matching its respective virtual RTL8139 device in QEMU:


An example of a "correct" configuration, where everything has been provided automatically (KernelEventMonitor) via DHCP.

What expected: should respond to ping (gateway firewall/dhcpd). should be the default route. should answer to DNS query. should answer to SMB (if available). is where starts the first guest ip address.

What is well known:
It seems that network hangs easily if the gateway is not pinged when network operations are needed. As user inp reported on #puredarwin, adding '-no-kvm-irqchip' to the qemu call solves this issue with the rtl8139 driver.

Ping workaround

ping the gateway ( from the guest side (PureDarwin) seems necessary at this time.
If it is not the done, the connection simply hangs or fails to establish sometimes.
As user inp reported on #puredarwin, adding '-no-kvm-irqchip' to the qemu call solves this issue with the rtl8139 driver.

Depending the ping interval (-i) against the virtual gateway, the bandwith varies (a pseudo bandwith control state; qos?).
Below is an example across the time, where the interval took the no value, then 0.9, 0.5, 0.1 and 0 (This example was done downloading nmap).


Guest fingerprint (

The famous Fyodor `nmap' basic fingerprint result against (guest: en0) looks like (X running without --no-listen tcp as shown).

Gateway fingerprint (

Interesting to see what looks like from nmap point of view the virtual gateway (user mode network stack):

DNS server fingerprint (


QEMU options

This is another non exhaustive list of (reported to work) options available. Some part also needs investigations and feedback.

Standard options

-M machine      select emulated machine (-M ? for list) Need investigations. (could be interesting to see how it is close or not the reality when it is possible to compare the cases)
-cpu cpu        select CPU (-cpu ? for list) Need investigations.
-fda/-fdb file  use 'file' as floppy disk 0/1 image No thanks.
-hda/-hdb file  use 'file' as IDE hard disk 0/1 image Reported to work with a iso, dmg, vmdk (convert or not).
-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image Need investigations.
-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master) Reported to work with a iso, dmg, vmdk (convert or not).
-m megs         set virtual RAM size to megs MB [default=128]384 and 512 are ok.
-smp n          set the number of CPUs to 'n' [default=1] Work well with default value or 1. Need investigations (Kernel panic with voodoo kernel even with reflecting modifications (cpus=2) in /Library/Preferences/SystemConfiguration/
-k language     use keyboard layout (for example "fr" for French) Need investigations, not working.
-vga [std|cirrus|vmware] Need investigations. Seems to works fine without -vga .... provided (default settings cyrus?). 
-usb            enable the USB driver (will be the default soon) Need investigations.
-usbdevice name add the host or guest USB device 'name' Need investigations.
-name string    set the name of the guest PureDarwin.
-uuid %08x-%04x-%04x-%04x-%012x specify machine Need investigations, UUID C0FFEEC0-FFEE-C0FF-EEC0-FFEEC0FFEEC0 has no effect.

Network options

According to the `man', "The NIC is an ne2k_pci by default on the PC target", but some other valid values are: 
i82551i82557b, i82559er, ne2k_pci, ne2k_isa, pcnet, rtl8139, e1000, smc91c111, lance and mcf_fec.

-net nic[,vlan=n][,macaddr=addr][,model=type]
                create a new Network Interface Card and connect it to VLAN 'n' -net nic,model=rtl8139 is enabled by PureFoundation. Need investigations.
-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n) "d" with the corresponding target is functional.
-redir to test. Need investigations
-tftp prefix
-macaddr addr

The option "-net nic,model={i82551|i82557b}" seems to match with AppletIntel8255x from DarwinBuild:

Live options

Press ctrl+alt+2 to switch to QEMU monitor:
Press ctrl+alt+3 to switch to serial0 console:
Press ctrl+alt+4 to switch to parallel0 console:
Patches to run stock XNU on QEMU
Currently, it appears that one needs to used a patched version of the XNU kernel called mach_kernel.voodoo to run on QEMU. This is even true when running QEMU on an Intel Mac on Mac OS X (tested with a MacBook Pro).

Alexander Graf has sent patches to the QEMU mailing list that allow Darwin to run on QEMU natively.
Specifically, these patches
They also add some other functionality that is not relevant for running Darwin.

It seems that the necessary patches have made their way into QEMU 0.10, as this version doesn't need special patching any more.

probono's networking experiments 12/2011

The experiments are done with a "fuller" PureDarwin installation than Xmas or Nano. Above it says "everything has been provided automatically (KernelEventMonitor) via DHCP", however it doesn't do that for me (I must be missing something still). Hence I set up networking by hand, which is a bit cumbersome:

The following are my tests on Ubuntu 12/2011; probono

# qemu: pci_add_option_rom: failed to find romfile "pxe-rtl8139.bin"
# can be solved with
sudo apt-get install kvm-pxe

# Launch qemu as root and with -redir tcp:22::22 for SSH access
sudo qemu -hda /dev/sdc -net nic,model=rtl8139 -no-kvm-irqchip -net user -redir tcp:22::22

# Inside qemu
ifconfig en2 up
ping # works (which is the gateway provided by qemu)

# Create /etc/rc.local with the following content to
# bring en2 up automatically at boot time
ifconfig en2 up
sudo route add

# Headless SSH server inside qemu
sudo qemu -hda /dev/sdc -net nic,model=rtl8139 -no-kvm-irqchip -net user -redir tcp:22::22 -vnc :1 -redir tcp:80::80

# Works :-)

# The only thing that does not work yet is DNS
# scutil --dns # resolver #1 is empty, which is a problem -- very ugly workaround:
echo 'nameserver' > /etc/resolver/com
echo 'nameserver' > /etc/resolver/org
echo 'nameserver' > /etc/resolver/net
echo 'nameserver' > /etc/resolver/de
echo 'nameserver' > /etc/resolver/edu

Rafael's networking information 01/2012

Our reader Rafael writes:

For the network problem it's just a matter of patching kvm module and you can use full acceleration, the patch is know (qemu dev don't want it because it's specific to qemu userland software and they want kvm module to remain compatible with other userland software - which ones? ):

Pick the latest kernel module from:
Open the x86/ioapic.c file:
search for this function:
int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
and change:
        level ^= entry.fields.polarity;
        //level ^= entry.fields.polarity;

And then rtl8139 will work as well as AppleIntelE1000 from :
svn co
--> but this last is derived from linux so it lacks debug specific part but I think this is the more interesting given you can redistribute it.

If you use recent xnu kernel you also need to patch qemu (or use kernel patched) to tell you use apic version 14 ( qemu dev don't want ton upgrade apic version as they don't have too to run linux or windows) or you will hit an assert/kp from kernel.

Open hw/apic.c from qemu source:
In this function:
static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
        val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
        val = 0x14 | ((APIC_LVT_NB - 1) << 16); /* version 0x14 */ 

Thanks Rafael for sharing this information, which is not easy to find. kvm is doing really great these days.

QSOC project on Darwin support in QEMU


Subpages (2): hfsprogs Q - [kju:]
Aladin Quet,
Apr 28, 2009, 4:13 PM