Freebsd QEMU comconsole

If you run a FreeBSD VM under QEMU with -nographic and the terminal goes silent right after the kernel modules load — no login prompt, no panic, just nothing — the VM hasn’t frozen. It booted successfully. The issue is that kernel output is going somewhere you can’t see.

This post explains why that happens and how to fix it properly.


The Root Cause

FreeBSD supports two console backends: vidconsole (virtual VGA framebuffer) and comconsole (serial port, ttyu0). Official VM disk images from download.freebsd.org default to vidconsole — a reasonable choice for hypervisors that expose a graphical display.

QEMU’s -nographic mode suppresses the display window and maps your terminal to the VM’s serial port instead. The problem is the FreeBSD kernel is unaware of this. It continues writing to vidconsole, which effectively goes nowhere in a -nographic session.

The bootloader, however, outputs to both VGA and serial simultaneously. That’s why you see the FreeBSD logo, the boot menu, and the kernel module lines — all of that is bootloader output. The moment the kernel takes control, it drops to vidconsole only, and your terminal goes quiet.

The handoff point is visible in the output:

/boot/kernel/zfs.ko size 0x788828 at 0x2795000
/etc/hostid size=0x25
/boot/entropy size=0x1000

Everything after that last line is the kernel running — login prompt included — just on a VGA console you can’t access from a -nographic session.


Temporary Fix: Redirect at the Bootloader Prompt

To get through without modifying the image, interrupt autoboot when you see the countdown. Press Space to pause it, then at the loader prompt:

set console="comconsole"
boot

This tells the kernel to route console I/O through the serial port for this boot only. You’ll see full kernel output and get a working login prompt.


Permanent Fix: /boot/loader.conf

Once inside the VM, make the change persistent:

echo 'console="comconsole"' >> /boot/loader.conf

From the next boot onward, the kernel will direct all console output to ttyu0 automatically. No more intercepting the bootloader, no more silent boots. This is the right fix if you’re using this image regularly for development or testing.


Alternative: Skip the Console Entirely, Use SSH

If you don’t need to observe the boot sequence at all, daemonize the VM and access it over SSH:

qemu-system-x86_64 \
    -enable-kvm \
    -m 4G \
    -smp 4 \
    -hda ~/vms/FreeBSD-16.0-CURRENT-amd64-zfs.qcow2 \
    -display none \
    -daemonize \
    -nic user,hostfwd=tcp::2222-:22

Give it roughly 30 seconds to reach multi-user mode, then:

ssh -p 2222 root@localhost

When you’re done:

kill $(pgrep qemu-system)

This approach sidesteps the console issue entirely and works well for quick test sessions where sshd is already enabled in the image.


Why It’s Easy to Misdiagnose

The bootloader’s dual-output behavior is what makes this particularly deceptive. Because you do get output right up to the kernel handoff, it’s natural to assume something went wrong during kernel initialization — a ZFS import failure, a module panic, something with entropy. In practice, none of that. The system is fully operational, just talking to a VGA display you have no visibility into.

Kernels built with BOOT_COMCONSOLE in their config, or images specifically targeting headless/serial environments, won’t exhibit this. The stock VM images are built for general-purpose use, so VGA is the sensible default — it just doesn’t play well with -nographic out of the box.


Summary

GoalSolution
Fix for one bootPress Space → set console="comconsole"boot
Fix permanentlyecho 'console="comconsole"' >> /boot/loader.conf
Skip console, SSH only-display none -daemonize + SSH after ~30s

Adding console="comconsole" to /boot/loader.conf is the one-time fix that makes FreeBSD under QEMU behave predictably for all subsequent work. After that, -nographic sessions give you full console output from boot to login with no intervention required.


Leave a comment

Discover more from /root

Subscribe now to keep reading and get access to the full archive.

Continue reading