qemu

multi system emulator

WWW CVSWeb GITHub
  1. Package version
    qemu-8.2.1
  2. Maintainer
    Brad Smith

QEMU is an open source machine emulator. It can run OSes and programs
made for one machine (e.g. an ARM board) on a different machine (e.g.
your own PC). By using dynamic translation, it achieves very good
performance.

+-----------------------------------------------------------------------
| Running ${PKGSTEM} on OpenBSD
+-----------------------------------------------------------------------

==> Quick Start

1. Get a bootable CDROM image:

$ ftp https://cdn.openbsd.org/pub/OpenBSD/snapshots/i386/cd74.iso

or to use a 64-bit client OS or SPARC64, respectively:

$ ftp https://cdn.openbsd.org/pub/OpenBSD/snapshots/amd64/cd74.iso

$ ftp https://cdn.openbsd.org/pub/OpenBSD/snapshots/sparc64/cd74.iso

2. Create a virtual disk image:

$ qemu-img create -f qcow2 virtual.img 10G

3. Install the OS:

$ qemu-system-i386 -m 64 -monitor stdio -no-fd-bootchk \
-hda virtual.img -cdrom cd74.iso -boot d

or:

$ qemu-system-x86_64 -m 64 -monitor stdio -no-fd-bootchk \
-hda virtual.img -cdrom cd74.iso -boot d

$ qemu-system-sparc64 -m 64 -monitor stdio \
-hda virtual.img -cdrom cd74.iso -boot d \
-net nic,model=ne2k_pci -net user

NOTE: start this inside an xterm or equivalent.
NOTE: be sure to choose serial console during install.
NOTE: -no-fd-bootchk permits booting faster when no floppy is
in use, but is not supported for qemu-system-sparc.
NOTE: qemu-system-ppc* and qemu-system-sparc* currently fail with
J or S malloc flags

4. Compress the virtual disk:

$ qemu-img convert -c -O qcow2 virtual.img v.tmp && \
mv v.tmp virtual.img

NOTE: do not do this while QEMU is running / using this virtual
disk.

5. Boot normally from the virtual disk:

$ qemu-system-i386 -m 64 -nographic -no-fd-bootchk -hda virtual.img

or:

$ qemu-system-x86_64 -m 64 -nographic -no-fd-bootchk -hda virtual.img

$ qemu-system-sparc64 -m 64 -nographic -hda virtual.img \
-net nic,model=ne2k_pci -net user

==> Networking

1. Default Settings

By default, QEMU sets up the equivalent of the following networking:

-net nic,vlan=0,model=e1000,macaddr=52:54:00:12:34:56
-net user,vlan=0

Also, inside this virtual usermode network, it uses the 10.0.2.0/24
and serves DHCP from inside this virtual network. Static address
can be used if one cannot or does not want to do DHCP in the
guest OS:

Guest OS IP : 10.0.2.15
Default Gateway : 10.0.2.2
Nameserver : 10.0.2.3

It is sufficient for most operations, QEMU itself performs NAT
and then makes userland network calls for TCP/UDP operations.
ICMP and other things are not possible in this mode.

NOTE: If you use one '-net' cmdline argument, QEMU assumes you
know what you want and clears defaults for the rest of the
-net defaults.

NOTE: The guest mode networking does not currently support IPv6,
and QEMU will complain that it cannot find a DNS server
if /etc/resolv.conf contains only IPv6 DNS servers.

2. tap mode

Sometimes it is desirable to configure QEMU to access a network
via layer2 directly. One way of doing this without having to run
QEMU as root is to let root open /dev/tapN and pass the file
descriptor to QEMU. The tap(4) interface should preferrably be
configured before starting QEMU:

$ doas ifconfig tap0 192.168.0.254

The interface can also be configured as part of a bridge(4), in
which case the ip address can be omitted:

$ doas ifconfig bridge0 add tap0 add em0 up

The tunnel and bridge interfaces can also be configured at system
startup by editing /etc/hostname.tapN and /etc/hostname.bridgeN,
respectively (see hostname.if(5)).

After configuring the virtual network we can use doas to let
root open the tunnel device and then use doas again to drop
privileges and start QEMU:

$ doas sh -c "doas -u $USER qemu-system-i386 -nographic -net nic \
-net tap,fd=3 -no-fd-bootchk -hda virtual.img 3<>/dev/tap0"

NOTE: if you use sudo instead of doas, remember that sudo calls
closefrom(2). In order to have more than one fd passed tap
interface, a line to sudoers akin to:

Defaults closefrom_override

then calling sudo via 'sudo -C 5 -u $USER qemu-system-i386 ..'
is required. See sudoers(5) and sudo(8) for details.

An alternative to the procedure described above is to have QEMU
set up the network via ${SYSCONFDIR}/qemu-ifup. This is not
recommended however, since you would have to run QEMU as root,
and there is no way to drop from root privileges at this point.

${SYSCONFDIR}/qemu-ifup contains some default settings that
permit one to do the following:

# qemu-system-i386 -net nic -net tap -no-fd-bootchk -hda virtual.img

It presumes you wish the tap(4) interface to talk to the interface
holding the default IPv4 route (falling back to trunk0 if no
route is found), and that you want 'bridge0' to be used to bridge
the two.

Setting the environment variables ETHER and BRIDGE will override
these settings, respectively.

When starting QEMU, the script attempts to output useful
information, but there are also error messages that occur as
well. On my laptop, I want to route / nat natively using PF and
also have layer2 access to the QEMU networks. I thus have this
as /etc/hostname.trunk101:

inet6 fe80::1c 64 lladdr 00:03:25:0d:7a:2c
inet 10.7.255.1 255.255.255.0
inet6 alias 2001:240:58a:45::1c

I have dhcpd configured to run on trunk101, and also run rad.
For QEMU, the startup looks like this:

# export ETHER=trunk101
# export BRIDGE=bridge101
# qemu-system-i386 -net nic,vlan=0,macaddr=52:54:00:12:35:00 \
-net tap,vlan=0 -vnc :0 -localtime -usb -usbdevice tablet \
-m 256 -no-fd-bootchk -hda virtual.img -monitor stdio
{tap0 (bridge101 <-> trunk101)ifconfig: bridge101: No such process
ifconfig: bridge101: No such process
}
(qemu)

The errors are normal and should be ignored. One can verify the
networking is properly configured by verifying the bridge
interface:

$ ifconfig bridge101
bridge101: flags=41<UP,RUNNING>
groups: bridge
priority 32768 hellotime 2 fwddelay 15 maxage 20 holdcnt 6 proto rstp
designated: id 00:00:00:00:00:00 priority 0
tap0 flags=3<LEARNING,DISCOVER>
port 16 ifpriority 0 ifcost 0
trunk101 flags=3<LEARNING,DISCOVER>
port 6 ifpriority 0 ifcost 0
Addresses (max cache: 100, timeout: 240):

NOTE: When running multiple QEMU sessions simultaneously on the
same bridge, care must be taken because the network MAC
address defaults to 52:54:00:12:34:56 for every QEMU
instance. To change this, observe the macaddr= syntax in
the above example and choose a unique lladdr per QEMU nic.

==> Mice

NOTE: Certain OS's work much better with the USB tablet device
than the normal PS/2 mouse handling. See the above example
for usage.

==> Serial Console

Installing OpenBSD via serial console is sometimes desirable.
X may not be available, and so on. There are two ways to
accomplish this, both in effect the same solution:

a. qemu-system-i386 -vnc :0 -serial stdio .. virtual.img \
-cdrom install74.iso -boot d

- this option permits you to use VNC from some system to
connect to the QEMU instance and 'set tty com0' at the
'boot>' prompt.
- you may then disconnect VNC and use the terminal from
which you started QEMU to do the install.

b. qemu-system-i386 -nographic .. virtual.img -fda floppy74.fs -boot a

- this maps both the serial port and the (qemu) monitor
prompt to the terminal QEMU was started on.
- to flip between them, Ctrl-a c; see the QEMU man page for
other commands that work in -nographic mode.
- preparation of the floppy image to force serial console
mode is straightforward:

vnconfig vnd0 floppy74.fs
mount /dev/vnd0c /mnt
mkdir /mnt/etc
echo set tty com0 > /mnt/etc/boot.conf
umount /mnt
vnconfig -u vnd0

.. be sure to choose 'yes' for setting com0 to be the serial
console.

NOTE: OpenBSD poweroff does work with QEMU, which actually causes
QEMU itself to exit. This is a good thing, as it is
currently not possible to set what block device is booted
from at runtime from QEMU. So if you start an installation
booting from a CD-ROM, you will always boot off a CD-ROM
every time you reboot that QEMU session until you exit and
start QEMU again booting off the virtual hard drive.

==> daemonized QEMU

Sometimes you want QEMU to start as part of a system script.

Adding to some of the above, the -daemonize option comes in
handy, as well as the telnet: designator for -serial and monitor.
This is a complete example that may be cut-and-pasted into
rc.local:

hddir=/var/vm
USER=qemu
if [ -x ${TRUEPREFIX}/bin/qemu ]; then
echo -n 'Qemu: vmi386'
(
ifconfig bridge101 add trunk101 add tap0 up

sh -c "doas -u $USER \
${TRUEPREFIX}/bin/qemu-system-i386 \
-daemonize \
-nographic \
-net nic,vlan=0,macaddr=52:54:00:4e:62:8f \
-net tap,vlan=0,fd=3 \
-m 128 \
-hda $hddir/virtual.img \
-serial telnet:127.0.0.1:1080,server,nowait \
-monitor telnet:127.0.0.1:1081,server,nowait \
-no-fd-bootchk 3<>/dev/tap0"
)
echo "."
fi

NOTE: this presumes the user `qemu' exists, create it or set
USER= to an existing user to use this example.

  • debug

  • devel/gettext,-tools
  • devel/meson
  • devel/ninja
  • shells/bash
  • STEM->=4.0.2:textproc/py-sphinx,python3
  • textproc/py-sphinx_rtd_theme,python3
  • lang/python/3.10
  • devel/gmake
  • devel/dwz
  • STEM->=5.4.0:archivers/xz

  • emulators/qemu,-ga