2

In the past you could trivially replace NVIDIA proprietary drivers on the fly after switching to the text console, killing X.org and unloading (rmmod) the appropriate NVIDIA modules, and installing new drivers.

However nowadays NVIDIA recommends to run the driver with KMS support, options nvidia-drm modeset=1 and that makes it impossible to unload kernel modules ("The device is busy").

The Linux kernel allows to unbind the graphical driver from the text console by running this command:

echo 0 > /sys/class/vtconsole/vtcon1/bind

However this command results in all the text consoles being completely dead. They just freeze, the system keeps running.

Looks like after this command, one needs to run another command to make the kernel re-enable built-in drivers which drove text consoles prior to NVIDIA drivers, only the Internet has no information on that.

This question is not limited to NVIDIA drivers. Would be nice to know how to unload an open source KMS driver, be it Intel, AMD or Nouveau.

Here's what I see on boot:

Console: colour dummy device 80x25
printk: console [tty0] enabled
fbcon: Deferring console take-over
fbcon: Taking over console
Console: switching to colour frame buffer device 128x48

Here's what I have in my .config:

CONFIG_SYSFB=y
CONFIG_SYSFB_SIMPLEFB=y
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=200
CONFIG_FB_CMDLINE=y
CONFIG_FB_NOTIFY=y
CONFIG_FB=y
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_VESA=y
CONFIG_FB_EFI=y
CONFIG_FB_SIMPLE=y

Here's what I have in /sys:

$ find /sys -iname '*fb*'
/sys/class/graphics/fb0
/sys/class/graphics/fbcon
/sys/devices/platform/simple-framebuffer.0/graphics/fb0
/sys/devices/virtual/graphics/fbcon
/sys/module/drm_kms_helper/parameters/drm_fbdev_overalloc
/sys/module/drm_kms_helper/parameters/fbdev_emulation
/sys/module/fb
/sys/module/fb/parameters/lockless_register_fb
Artem S. Tashkinov
  • 26,392
  • 4
  • 33
  • 64

1 Answers1

0

According to the kernel fbcon documentation, you have to:

  1. Download or install vbetool. This utility is included with most distributions nowadays, and is usually part of the suspend/resume tool.

  2. In your kernel configuration, ensure that CONFIG_FRAMEBUFFER_CONSOLE is set to 'y' or 'm'. Enable one or more of your favorite framebuffer drivers.

  3. Boot into text mode and as root run:

     vbetool vbestate save > <vga state file>
    

    The above command saves the register contents of your graphics hardware to <vga state file>. You need to do this step only once as the state file can be reused.

  4. If fbcon is compiled as a module, load fbcon by doing:

    modprobe fbcon
    
  5. Now to detach fbcon:

    vbetool vbestate restore < <vga state file> && \
    echo 0 > /sys/class/vtconsole/vtcon1/bind
    
  6. That's it, you're back to VGA mode. And if you compiled fbcon as a module, you can unload it by rmmod fbcon.

  7. To reattach fbcon:

    echo 1 > /sys/class/vtconsole/vtcon1/bind
    
  8. Once fbcon is unbound, all drivers registered to the system will also become unbound. This means that fbcon and individual framebuffer drivers can be unloaded or reloaded at will. Reloading the drivers or fbcon will automatically bind the console, fbcon and the drivers together. Unloading all the drivers without unloading fbcon will make it impossible for the console to bind fbcon.

The documentation also provides an example script (you need to ensure you have the prerequisites):

#!/bin/bash
# Unbind fbcon

# Change this to where your actual vgastate file is located
# Or Use VGASTATE=$1 to indicate the state file at runtime
VGASTATE=/tmp/vgastate

# path to vbetool
VBETOOL=/usr/local/bin


for (( i = 0; i < 16; i++))
do
  if test -x /sys/class/vtconsole/vtcon$i; then
      if [ `cat /sys/class/vtconsole/vtcon$i/name | grep -c "frame buffer"` \
           = 1 ]; then
        if test -x $VBETOOL/vbetool; then
           echo Unbinding vtcon$i
           $VBETOOL/vbetool vbestate restore < $VGASTATE
           echo 0 > /sys/class/vtconsole/vtcon$i/bind
        fi
      fi
  fi
done

Although, if it stills hangs after following these steps, ipaqmaster did deal with a lot of blocking case in this script in the gpuLockHandler function.

Moreover, in the Nouveau KMS documentation, CONFIG_VT_HW_CONSOLE_BINDING is also a prerequisite (in case you still miss something).

setenforce 1
  • 482
  • 2
  • 6
  • 1
    Sadly, `vbetool vbestate save > /tmp/vbestate` doesn't work: `mmap /dev/zero: Operation not permitted Failed to initialise LRMI (Linux Real-Mode Interface).` It's run under `root`. I'm now trying the solution posted here: https://bugs.launchpad.net/ubuntu/+source/vbetool/+bug/1875240 `mount -o remount,exec /dev; mount | grep " /dev " -> devtmpfs on /dev type devtmpfs (rw,nosuid,relatime,seclabel,mode=755)` - my kernel doesn't want to apply `exec` to `/dev` – Artem S. Tashkinov Jun 30 '23 at 13:29
  • 1
    `exec` is indeed applied, it's just not shown (only `noexec` gets shown) but `vbetool` still doesn't work. `# CONFIG_STRICT_DEVMEM is not set` so everything should work. – Artem S. Tashkinov Jun 30 '23 at 13:35
  • 1
    I have `CONFIG_DEVTMPFS_SAFE=y` enabled but it shouldn't affect vbetool after remounting with `exec`. Debian users also say `exec` doesn't help: https://forums.debian.net/viewtopic.php?t=147117 – Artem S. Tashkinov Jun 30 '23 at 13:41
  • 1
    Here it says vbetool cannot work any longer: https://www.reddit.com/r/debian/comments/icq1r1/vbetool_dpms_devmem_operation_not_permitted/ *vbetool is an artifact of the legacy XF86 (usermode) video architecture. Now that the linux kernel has real (kernel-mode) drivers for video hardware, it no-longer support the horrible kludges of the past. To set DPMS parameters for the console in the modern world, use `setterm --blank`* I give up. Sorry, took too much of your time but I need something contemporary, i.e. applicable to kernels 6.3/6.4 and newer going forward. – Artem S. Tashkinov Jun 30 '23 at 13:44