home | tech | misc | code | bookmarks (broken) | contact | README


QEMU notes

Last update to this page was in: 2019-02-13.

QEMU setup

Network setup of QEMU on NetBSD (NAT)

This section provides you a way to have NAT working for your guest machine, i.e., it is isolated in an internal network and use its host as router.

After installing QEMU on a NetBSD host, some changes might be necessary. First, create a tap device with the follwing command:

# sysctl -w net.inet.ip.forwarding=1
# ifconfig tap0 10.0.0.1
# qemu-system-x86_64 -nographic -curses -boot c -net nic -net tap,ifname=tap0,script=no,downscript=no -m 326M emul.img

Also, you need to setup NAT for the host. I tried to configure this with NPF, but I couldn't. So I tried a configuration for PF, which worked. The contents of /etc/pf.conf is:

emul="10.0.0.10"
ext_if="wm0"
int_if="tap0"
rdr on $ext_if proto {tcp udp} from any to any port 23 -> $emul port 22
nat pass on $ext_if from $int_if:network -> ($ext_if:0)
pass out
block in on $ext_if
pass in on $ext_if proto {tcp udp} from any to any port 22
pass in on $ext_if proto {tcp udp} from any to any port 23
pass in on $ext_if proto {tcp udp} from any to $emul port 22
pass in on $ext_if proto icmp all

Enable it on /etc/rc.conf and start it:

# echo 'pf=YES' >> /etc/rc.conf
# /etc/rc.d/pf start

Network setup of QEMU on NetBSD (bridge mode)

In this section, we setup an environment to allow your guest machines have real public IPs on your network. The Networking - KVM guide is good, but it is GNU/Linux specific. Anyway it describes this method as "Public Bridge". It is worth taking a look at it.

First, create your tap and bridge devices:

# ifconfig tap0 create
# ifconfig bridge0 create

Add your real and tap interfaces to the bridge (in this guide we are using wm0 as real network interface, but the name of it in your computer may vary. Check it with the ifconfig(8) command):

# brconfig bridge0 add wm0
# brconfig bridge0 add tap0

Bring the tap interface and bridge up:

# ifconfig tap0 up
# ifconfig bridge0 up

Now you can run qemu:

$ qemu-system-x86_64 -boot c -m 500M -net nic -net tap,script=no,downscript=no emul.img

Network setup of QEMU on Ubuntu Linux Host (NAT)

To make this little guide, I basically followed this guide, which is a very good one.

Unlike it, though, I prefered to oversimplify it, so it not require nothing more than qemu (not kqemu) and uml-utilities. If you don't have them yet, fetch them:

# apt-get install qemu
# apt-get install uml-utilities

With the uml-utilities package, the tun kernel module and the tunctl user-level command become available. If the package manager didn't load the module itself, do that now:

# modprobe tun

Ok, now let's create a tap device (where <username> is the name of the user that will run QEMU, usually the user that you are logged on:

# tunctl -t tap0 -u <username>

We need to create (or edit) the script in /etc/qemu-ifup. This script is called whenever you run QEMU, to configure interfaces necessary to make networking work on QEMU:

#!/bin/sh

sudo /sbin/ifconfig $1 172.20.0.1 netmask 0xffffff00 up

# IFNAME_INTERNET=eth0
# sudo /sbin/iptables -t nat -A POSTROUTING -o $IFNAME_INTERNET -j MASQUERADE
# sudo /bin/sh -c "/bin/echo 1 > /proc/sys/net/ipv4/ip_forward"

Comment out the last three lines (and set them up accordingly to your environment) if you want NAT and it is not enabled by default.

Note

I may had done something wrong, but I've had to make sure that the address I used on the script (172.20.0.1) was not in the network of any of other interfaces (virtual or not) setup on the same machine.

At last, we just call qemu:

qemu -hda <your-image> -net nic -net tap,ifname=tap0 -localtime -m 256

Note

QEMU will call the /etc/qemu-ifup script and pass tap0 as parameter, configuring it. I think it can be configured manually, without using the /etc/qemu-ifup script, but I didn't try that.

Finally, after booting your machine on QEMU, configure the network interface of the emulated machine with a IP on the same network of tap0:

# ifconfig eth0 172.20.0.2

And networking on QEMU is working.

Running qemu without X11 support

By default, qemu uses SDL to render output. If you want it to use the terminal you are running it, use:

$ qemu -nographic -curses ...other options

This link help me with that.

Troubleshooting

Can't boot CentOS GNU/Linux: ... IO-APIC + timer doesn't work! ...

When booting, if you get an error like this:

[    0.026000] ..MP-BIOS bug: 8254 timer not connected to IO-APIC
[    0.030000] Kernel panic - not syncing: IO-APIC + timer doesn't work!  Boot w
ith apic=debug and send a report.  Then try booting with the 'noapic' option.
[    0.030000]
[    0.030000] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.10.0-957.el7.x86_64 #
1
[    0.030000] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1
.11.1-0-g0551a4be2c-prebuilt.qemu-project.org 04/01/2014
[    0.030000] Call Trace:
[    0.030000]  [<ffffffff84d61dc1>] dump_stack+0x19/0x1b
[    0.030000]  [<ffffffff84d5b4d0>] panic+0xe8/0x21f
[    0.030000]  [<ffffffff8539ec49>] check_timer+0x454/0x625
[    0.030000]  [<ffffffff8539f643>] setup_IO_APIC+0x27f/0x2a0
[    0.030000]  [<ffffffff8539b0a2>] native_smp_prepare_cpus+0x328/0x3b2
[    0.030000]  [<ffffffff853862aa>] kernel_init_freeable+0xc3/0x21f
[    0.030000]  [<ffffffff84d4fec0>] ? rest_init+0x80/0x80
[    0.030000]  [<ffffffff84d4fece>] kernel_init+0xe/0x100
[    0.030000]  [<ffffffff84d74c24>] ret_from_fork_nospec_begin+0xe/0x21
[    0.030000]  [<ffffffff84d4fec0>] ? rest_init+0x80/0x80

According to this e-mail, try passing the no_timer_check or noapic options to the kernel, via the grub screen.