QEMU – Disable Framebuffer in QEMU Guests

consoledrmframebufferqemuterminal

The QEMU options -display curses and -nographic -device sga (the serial graphics adapter) are very convenient for running QEMU outside of a graphical environment.

(think: remote ssh connection, rescue system etc.)

Both modes fail to work with framebuffer text mode, though. The new default with some Linux distirbutions (e.g. Fedora 25) seems to be that at some point during boot a framebuffer text mode seems to be activated such that with -display curses QEMU just displays '1024×768 Graphic mode'. With SGA just nothing is printed.

Thus my question: how can I force the kernel (and the rest of startup) to just use the old-school initial text mode?

Addendum

Adding the nomodeset kernel parameter (and removing the rhgb one) doesn't make a difference.

Most convenient would be some QEMU configuration that forces the kernel to just detect the most basic text mode – since the guest wouldn't have to be modified.

Setting up a serial console (via e.g. adding the console=ttyS0 kernel parameter to the guest) works in my environment, but I observed some escape sequence issues with the Gnome terminal. Also this doesn't help with boot loaders that already use the framebuffer (e.g. the one on the Fedora 25 server ISO) – and needs a modification of the guest.

Fedora Guest Example

With Fedora 25 as guest, the switch to the framebuffer happens during initrd runtime, some log messges (from the serial console):

[    1.485115] Console: switching to colour frame buffer device 128x48
[    1.493184] bochs-drm 0000:00:02.0: fb0: bochsdrmfb frame buffer device
[    1.502492] [drm] Initialized bochs-drm 1.0.0 20130925 for 0000:00:02.0 on minor 0

These messages also show up with the nofb and vga=normal (guest) kernel parameters.

Best Answer

As of 2017, qemu doesn't provide text-mode-only graphics card emulation for x86-64 that would force a guest to stay in text mode.

Current distributions like Fedora 25 come with the bochs_drm kernel module that enables a frame buffer (e.g. 1024x768 graphics mode), by default. In contrast to that, e.g. Debian 8 (stable) doesn't provide this module and thus it stays in old-school text-mode during the complete boot.

Thus, when running qemu from a terminal (e.g. with -display curses) it makes sense to enable a serial console as fail safe:

console=tty0 console=ttyS0

or

console=tty0 console=ttyS0,115200

(Kernel parameters for the guest, default speed is 9600, both settings works with qemu, make the settings persistent in Fedora via assigning them to GRUB_CMDLINE_LINUX in /etc/sysconfig/grub and executing grub2-mkconfig -o /etc/grub2.cfg or grub2-mkconfig -o /etc/grub2-efi.cfg)

In case nothing else works one can then switch inside qemu via Alt+3 to the serial console, then.

A second measure is to disable the framebuffer via a bochs_drm module parameter - i.e. via setting it on the guest kernel command line:

bochs_drm.fbdev=off

Blacklist Alternative

Alternatively, the bochs_drm module can be blacklisted - i.e. via creating a config under /etc/modprobe.d - say - bochs.conf:

blacklist bochs_drm

Since the initramfs mustn't load the bochs_drm module, as well, one has to make sure that this config is included into the initramfs. On Fedora like distributions this is achieved via:

# dracut -f

UEFI Boot

When booting qemu with an UEFI firmware (e.g. -bios /usr/share/edk2/ovmf/OVMF_CODE.fd) the disabling of the bochs fbdev isn't enough. The Fedora boot then hangs while trying to switch to the bochs framebuffer. Blacklisting the bochs_drm fixes this but it isn't sufficient. One just gets a 640 x 480 graphics mode that isn't reset to text mode by the kernel. Thus, for UEFI guests one has to take the serial console route.

Serial Console

Using the serial console in combination with -display curses yields a suboptimal user experience as the curses interferes with the vt110/vt220 terminal emulation. Thus, it only suffices for emergencies.

A better solution is to completely switch the display off and use the combined serial/monitor Qemu mode:

-display none -serial mon:stdio -echr 2

(where Ctrl+b h displays a help and Ctrl+b c switches between the modes)

With Fedora 27, the Grub2 is configured with serial console support, by default. Thus, it can be controlled via the serial terminal, as well.

Calling resize after login updates the terminal geometry, thus, the resulting terminal behaves as good as a local one.

Multi-User Target

In case the guest image has a graphical login manager installer it makes sense to disable it:

# systemctl set-default multi-user.target

Otherwise, on has to switch to the first virtual console after each boot (e.g. Alt+2 or Alt+3 when using the curses display).

Related Question