This page contains recipes for using qemu to run FreeBSD inside virtual machines (especially non-native virtual machines) on a FreeBSD host. The goal is to have a at least one “blessed” qemu recipe for each architecture FreeBSD supports. For more details on running qemu in general including network configuration, see the qemu page.
For systems installed from an ISO image, the instructions assume you have downloaded an appropriate ISO image from a release or snapshot. When installing a new machine that requires a disk image, you can use truncate(1) to create an empty disk image before installing, for example:
truncate -s 16g /path/to/disk.img
If you wish to boot without a graphical console, add -nographic to the qemu command line.
First, install the U-Boot port, sysutils/u-boot-qemu-arm.
The serial console will be available on stdin and stdout.
qemu-system-arm -M virt -m 512m -nographic -bios /usr/local/share/u-boot/u-boot-qemu-arm/u-boot.bin -hda /path/to/disk.img
See also: QEMU
FreeBSD/aarch64 (aka ARM64) image can be booted in two ways: using U-Boot, or with UEFI image. For instructions on how to boot with UEFI, see QEMU. To boot using U-Boot, install sysutils/u-boot-qemu-arm64 port.
qemu-system-aarch64 -M virt -m 512m -cpu cortex-a57 -nographic -bios /usr/local/share/u-boot/u-boot-qemu-arm64/u-boot.bin -hda /path/to/disk.img
FreeBSD does not provide release images for mips, so a disk image must be built from source. Note that these instructions use a few placeholders:
| /path/to/rootfs | Local directory on the host to hold the contents of the root filesystem. |
| /path/to/disk.img | A file on the host to hold the UFS disk image of the root filesystem. |
| /path/to/src | The path to the source tree used for the build. |
make TARGET_ARCH=mips buildworld make TARGET_ARCH=mips buildkernel KERNCONF=MALTA mkdir /path/to/rootfs make TARGET_ARCH=mips installworld DESTDIR=/path/to/rootfs make TARGET_ARCH=mips installkernel KERNCONF=MALTA DESTDIR=/path/to/rootfs make TARGET_ARCH=mips distribution DESTDIR=/path/to/rootfs etcupdate extract -B -D /path/to/rootfs -s /path/to/src -M "TARGET_ARCH=mips"
Create /etc/fstab in the rootfs to mount '/dev/ada0' as an ufs filesystem for /. You might also wish to make other
changes to files in /etc such as enabling ssh.
makefs -M 4g -B be /path/to/disk.img /path/to/rootfs
The serial console will be available on stdin and stdout.
qemu-system-mips -kernel /path/to/rootfs/boot/kernel/kernel -nographic -hda /path/to/disk.img -m 2048
To use external GCC from ports instead of the in-tree GCC 4.2.1 use these steps to build the image:
pkg install mips-xtoolchain-gcc make TARGET_ARCH=mips CROSS_TOOLCHAIN=mips-gcc TARGET_CPUTYPE=mips3 buildworld make TARGET_ARCH=mips CROSS_TOOLCHAIN=mips-gcc TARGET_CPUTYPE=mips3 buildkernel KERNCONF=MALTA mkdir /path/to/rootfs make TARGET_ARCH=mips CROSS_TOOLCHAIN=mips-gcc installworld DESTDIR=/path/to/rootfs make TARGET_ARCH=mips CROSS_TOOLCHAIN=mips-gcc installkernel KERNCONF=MALTA DESTDIR=/path/to/rootfs make TARGET_ARCH=mips distribution DESTDIR=/path/to/rootfs etcupdate extract -B -D /path/to/rootfs -s /path/to/src -M "TARGET_ARCH=mips CROSS_TOOLCHAIN=mips-gcc"
To cross-compile simple programs using the rootfs and external GCC, use the following variables. Note that for C++ you may need to remove /usr/lib/include from the rootfs for builds to work correctly (note that this uses libc++ and so should work with C++11 programs):
ROOTFS=/path/to/rootfs
CC="mips-unknown-freebsd11.0-gcc -nostdinc -march=mips3 --sysroot=${ROOTFS} -isystem ${ROOTFS}/usr/include -B ${ROOTFS}/usr/lib -L${ROOTFS}/usr/lib -msoft-float"
CXX="mips-unknown-freebsd11.0-g++ -nostdinc -nostdinc++ -march=mips3 --sysroot=${ROOTFS} -isystem ${ROOTFS}/usr/include/c++/v1 -isystem ${ROOTFS}/usr/include -B ${ROOTFS}/usr/lib -L${ROOTFS}/usr/lib -msoft-float"
FreeBSD does not provide release images for mips64, so a disk image must be built from source. Note that these instructions use a few placeholders:
| /path/to/rootfs | Local directory on the host to hold the contents of the root filesystem. |
| /path/to/disk.img | A file on the host to hold the UFS disk image of the root filesystem. |
| /path/to/src | The path to the source tree used for the build. |
make TARGET_ARCH=mips64 buildworld make TARGET_ARCH=mips64 buildkernel KERNCONF=MALTA64 mkdir /path/to/rootfs make TARGET_ARCH=mips64 installworld DESTDIR=/path/to/rootfs make TARGET_ARCH=mips64 installkernel KERNCONF=MALTA64 DESTDIR=/path/to/rootfs make TARGET_ARCH=mips64 distribution DESTDIR=/path/to/rootfs etcupdate extract -B -D /path/to/rootfs -s /path/to/src -M "TARGET_ARCH=mips64"
Create /etc/fstab in the rootfs to mount '/dev/ada0' as an ufs filesystem for /. You might also wish to make other
changes to files in /etc such as enabling ssh.
makefs -M 4g -B be /path/to/disk.img /path/to/rootfs
The serial console will be available on stdin and stdout.
qemu-system-mips64 -kernel /path/to/rootfs/boot/kernel/kernel -nographic -hda /path/to/disk.img -m 2048
To use external GCC from ports instead of the in-tree GCC 4.2.1 use these steps to build the image:
pkg install mips-xtoolchain-gcc make TARGET_ARCH=mips64 CROSS_TOOLCHAIN=mips-gcc buildworld make TARGET_ARCH=mips64 CROSS_TOOLCHAIN=mips-gcc buildkernel KERNCONF=MALTA64 mkdir /path/to/rootfs make TARGET_ARCH=mips64 CROSS_TOOLCHAIN=mips-gcc installworld DESTDIR=/path/to/rootfs make TARGET_ARCH=mips64 CROSS_TOOLCHAIN=mips-gcc installkernel KERNCONF=MALTA64 DESTDIR=/path/to/rootfs make TARGET_ARCH=mips64 distribution DESTDIR=/path/to/rootfs etcupdate extract -B -D /path/to/rootfs -s /path/to/src -M "TARGET_ARCH=mips64 CROSS_TOOLCHAIN=mips-gcc"
To cross-compile simple programs using the rootfs and external GCC, use the following variables. Note that for C++ you may need to remove /usr/lib/include from the rootfs for builds to work correctly (note that this uses libc++ and so should work with C++11 programs):
ROOTFS=/path/to/rootfs
CC="mips-unknown-freebsd11.0-gcc -nostdinc -mabi=64 --sysroot=${ROOTFS} -isystem ${ROOTFS}/usr/include -B ${ROOTFS}/usr/lib -L${ROOTFS}/usr/lib -msoft-float"
CXX="mips-unknown-freebsd11.0-g++ -nostdinc -nostdinc++ -mabi=64 --sysroot=${ROOTFS} -isystem ${ROOTFS}/usr/include/c++/v1 -isystem ${ROOTFS}/usr/include -B ${ROOTFS}/usr/lib -L${ROOTFS}/usr/lib -msoft-float"
Note: This does not yet work. Both the default (g3beige) and mac99 machine types hang during boot.
See Also: QEMU
To disable the graphic console, use -nographic -vga none. Note that the default NIC provided by qemu(4) (llan(4)) does not provide media status. As a result, DHCP is not started by devd out of the box. Use SYNCHDHCP in /etc/rc.conf instead of DHCP to enable DHCP on boot.
qemu-system-ppc64 -cdrom /path/to/disc1.iso -drive file=/path/to/disk.img,format=raw -boot d
qemu-system-ppc64 -drive file=/path/to/disk.img,format=raw
Booting FreeBSD/riscv64 requires installing two ports: sysutils/opensbi and sysutils/u-boot-qemu-riscv64.
qemu-system-riscv64 -M virt -m 512m -nographic -bios /usr/local/share/opensbi/lp64/generic/firmware/fw_jump.elf -kernel /usr/local/share/u-boot/u-boot-qemu-riscv64/u-boot.bin -drive file=/path/to/disk.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0
FreeBSD/sparc64 should boot with qemu 2.6 and above with -nographic option. Confirmed with 10.4-STABLE snapshot (r326054) and qemu 2.9.0; however, 12.0-CURRENT hangs during the boot process (YMMV).
qemu-system-sparc64 -cdrom /path/to/disc1.iso -drive file=/path/to/disk.img,format=raw -boot d