how to switch between nouveau and nvidia driver at boot time

my system is running opensuse leap 42.1 with plasma 5.7.3:
Laptop=Dell latitude E6510, RAM=8Gb, GPU=GT218 NVS 3100M, CPU=i7 Q 720 @ 1.60GHz
upgraded 13.2 to leap 42.1, using wolfi repos. I’m running KDE 4.14.18 and plasma 5.7.3, KDE frameworks 5.24.0, KDE applications 16.04.3, Kernel 4.1.27-27-default

nvidia drivers cons:
-After resume from RAM keyboard doesn’t works on many applications
-sometimes not all icons are shown in the system tray
-some graphical glitch after resume from RAM
-do not works at full resolution 1920x1080
nvidia drivers pros:
-works well with dual monitor

nouveau drivers cons:
-I haven’t tested now, but time ago it didn’t works well with dual monitor
nouveau drivers pros:
-After resume from RAM keyboard works
-all icons are shown in the system tray
-works at full resolution 1920x1080
-no graphical glitch after resume from RAM

so I think it would be useful to have the possibility to easily switch between nouveau and nvidia to have a better working opensuse

about switching*(https://forums.opensuse.org/showthread.php/502378-Switching-between-nouveau-and-nvidia-driver-at-boot-time/page2)


#Make sure we are in command of /usr/X11R6/lib
if  -e /etc/ld.so.conf.d/nvidia-gfxGO*.conf ]; then
    /bin/rm /etc/ld.so.conf.d/nvidia-gfxGO*.conf
fi  

#Check graphics mode fix symlinks
if  `grep -c "nouveau" /proc/cmdline` -gt 0 ]; then
    update-alternatives --set libglx.so /usr/lib64/xorg/modules/extensions/xorg/xorg-libglx.so
    /bin/cat > /etc/X11/xorg.conf.d/20-nouveau.conf << END 
Section "Device"
Driver "nouveau"
EndSection
END
    # use Mesa's libGL
    ln -sf  /usr/lib64/libGL.so.1.2.0 /usr/lib64/libGL.so.1
fi 

if  `grep -c "nouveau" /proc/cmdline` -eq 0 ]; then
    update-alternatives --set libglx.so /usr/lib64/xorg/modules/extensions/nvidia/nvidia-libglx.so
    /sbin/ldconfig /usr/X11R6/lib64
    /bin/rm /etc/X11/xorg.conf.d/20-nouveau.conf
    # use nvidia's libGL
    ln -sf  /usr/X11R6/lib64/libGL.so.1 /usr/lib64/libGL.so.1
fi

and install two identical distro but the graphic drivers.
I think to start with the script could be a good solution.
but the script was for KDE4, and as said here:
“…nvidia breaks Mesa’s OpenGL… …you’d need to set an environment variable…” so may be the script doesn’t works with plasma5 or needs only to add something.
how can I use the script and where I have to save it?
is there a way to have two lines in grub to boot with nvidia and with nouveau??
manythanks, ciao, pier :-)*

At least the last one is a known common problem with the nvidia driver.
Try to disable compositing before suspending. Should fix the graphical corruption at least.

See also this thread https://forum.kde.org/viewtopic.php?f=111&t=121590

-do not works at full resolution 1920x1080

It should.

nouveau drivers cons:
-I haven’t tested now, but time ago it didn’t works well with dual monitor

Should work AFAIK.

nouveau drivers pros:
-After resume from RAM keyboard works
-all icons are shown in the system tray
-works at full resolution 1920x1080
-no graphical glitch after resume from RAM

Your list doesn’t look like you need the nvidia driver at all… :wink:

so I think it would be useful to have the possibility to easily switch between nouveau and nvidia to have a better working opensuse

That’s not easily possible, as nvidia replaces some of Mesa’s libraries with its own versions.
Just having nvidia installed therefore breaks nouveau’s OpenGL support (and even Mesa’s software renderer).

OTOH, OpenGL will not work with nvidia if you put back the original (i.e. Mesa’s) libraries.

about switching*(https://forums.opensuse.org/showthread.php/502378-Switching-between-nouveau-and-nvidia-driver-at-boot-time/page2)

and install two identical distro but the graphic drivers.

If you use that script to switch, you don’t have to “install two identical distro but the graphic drivers”.

I think to start with the script could be a good solution.
but the script was for KDE4, and as said here:
“…nvidia breaks Mesa’s OpenGL… …you’d need to set an environment variable…” so may be the script doesn’t works with plasma5 or needs only to add something.

There’s nothing KDE4 specific at all in that script.
It should work regardless of the desktop you use.

how can I use the script and where I have to save it?

You need to start that script during boot, e.g. by putting it into /etc/init.d/boot.local.
That’s mentioned in the thread you linked to: https://forums.opensuse.org/showthread.php/502378-Switching-between-nouveau-and-nvidia-driver-at-boot-time?p=2675282#post2675282

Then you can switch to the nouveau driver by adding “nouveau” to the kernel parameters.

Note that I never tried that script myself as I don’t have any nvidia card, and that thread was about 13.2, things might have changed though I believe it should still work.

is there a way to have two lines in grub to boot with nvidia and with nouveau??

Yes.
You could add a “nouveau” line manually (via /boot/grub2/custom.cfg e.g.).

But I would probably create a copy of /etc/grub.d/10-linux.sh (name it /etc/grub.d/10-linux-nouveau.sh e.g.) that adds “nouveau” to the line starting with ‘linux=’/‘linuxefi=’ (i.e. the kernel parameters).
This would create those entries automatically.*

there isn’t /etc/grub.d/10-linux.sh

pla@suseST-pla:/etc/grub.d> ls
00_header  10_linux-nouveau  30_os-prober  80_suse_btrfs_snapshot
00_tuned   20_linux_xen      40_custom     90_persistent
10_linux   20_memtest86+     41_custom     README

I suppose it should be /etc/grub.d/10_linux
and there isn’t a line starting with ‘linux=’/‘linuxefi=’
this is the content of /etc/grub.d/10_linux

#! /bin/sh
set -e

# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.

prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"

. "${datarootdir}/grub2/grub-mkconfig_lib"

export TEXTDOMAIN=grub2
export TEXTDOMAINDIR="${datarootdir}/locale"

CLASS="--class gnu-linux --class gnu --class os"

if  "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
  OS=GNU/Linux
else
  OS="${GRUB_DISTRIBUTOR}"
  CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,^:alnum:]_],_,g') ${CLASS}"
fi

# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
  /dev/loop/*|/dev/loop[0-9])
    GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^^(]*(\(^)]\+\)).*/\1/"`
  ;;
esac

# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
# and mounting btrfs requires user space scanning, so force UUID in this case.
if  "x${GRUB_DEVICE_UUID}" = "x" ] ||  "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
    || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
    || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
  LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
  LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi

if  "x$GRUB_CONMODE" != "x" ]; then
  GRUB_CMDLINE_LINUX="conmode=${GRUB_CONMODE} ${GRUB_CMDLINE_LINUX}"
fi

case x"$GRUB_FS" in
    xbtrfs)
    if  "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ]; then
    GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} \${extra_cmdline}"
    else
    rootsubvol="`make_system_path_relative_to_its_root /`"
    rootsubvol="${rootsubvol#/}"
    if  "x${rootsubvol}" != x ]; then
        GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
    fi
    fi;;
    xzfs)
    rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2&gt;/dev/null || true`
    bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
    LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}"
    ;;
esac

title_correction_code=

hotkey=1
incr_hotkey()
{
   -z "$hotkey" ] && return
  expr $hotkey + 1
}
print_hotkey()
{
  keys="123456789abdfgijklmnoprtuvwyz"
  if  -z "$hotkey" ]|| $hotkey -eq 0 ]|| $hotkey -gt 30 ]; then
    return
  fi
  echo "--hotkey=$(expr substr $keys $hotkey 1)"
}

linux_entry ()
{
  os="$1"
  version="$2"
  type="$3"
  args="$4"

  if  -n "${linux_root_device_thisversion}" ]; then
    root_device="root=${linux_root_device_thisversion}"
  else
    root_device=""
  fi

  if  -z "$boot_device_id" ]; then
      boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
  fi
  if  x$type != xsimple ] ; then
      case $type in
      recovery)
          title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;;
      *)
          title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;;
      esac
      if  x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] ||  x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
      replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
      quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
      title_correction_code="${title_correction_code}if  \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
      grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id&gt;gnulinux-$version-$type-$boot_device_id")"
      fi
      echo "menuentry '$(echo "$title" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
      hotkey=$(incr_hotkey)
  else
      echo "menuentry '$(echo "$os" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
      hotkey=$(incr_hotkey)
  fi      
  if  x$type != xrecovery ] ; then
      save_default_entry | grub_add_tab
  fi

  # Use ELILO's generic "efifb" when it's known to be available.
  # FIXME: We need an interface to select vesafb in case efifb can't be used.
  if  "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
      echo "    load_video" | sed "s/^/$submenu_indentation/"
      if grep -qx "CONFIG_FB_EFI=y" "${config}" 2&gt; /dev/null \
      && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" "${config}" 2&gt; /dev/null; then
      echo "    set gfxpayload=keep" | sed "s/^/$submenu_indentation/"
      fi
  else
      if  "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then
      echo "    load_video" | sed "s/^/$submenu_indentation/"
      fi
      echo "    set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/"
  fi

  echo "    insmod gzio" | sed "s/^/$submenu_indentation/"

 if  $PLATFORM != emu ]; then # 'search' does not work for now
  if  x$dirname = x/ ]; then
    if  -z "${prepare_root_cache}" ]; then
      prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
    fi
    printf '%s
' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/"
  else
    if  -z "${prepare_boot_cache}" ]; then
      prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
    fi
    printf '%s
' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
  fi
 fi
  message="$(gettext_printf "Loading Linux %s ..." ${version})"
  if  -d /sys/firmware/efi ] &&  "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
    sed "s/^/$submenu_indentation/" &lt;&lt; EOF
    echo    '$(echo "$message" | grub_quote)'
    linuxefi ${rel_dirname}/${basename} ${root_device} ro ${args}
EOF
  else
    sed "s/^/$submenu_indentation/" &lt;&lt; EOF
    echo    '$(echo "$message" | grub_quote)'
    linux    ${rel_dirname}/${basename} ${root_device} ${args}
EOF
  fi
  if test -n "${initrd}" ; then
    # TRANSLATORS: ramdisk isn't identifier. Should be translated.
    message="$(gettext_printf "Loading initial ramdisk ...")"
    if  -d /sys/firmware/efi ] &&  "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
      sed "s/^/$submenu_indentation/" &lt;&lt; EOF
    echo    '$(echo "$message" | grub_quote)'
    initrdefi ${rel_dirname}/${initrd}
EOF
    else
      sed "s/^/$submenu_indentation/" &lt;&lt; EOF
    echo    '$(echo "$message" | grub_quote)'
    initrd    ${rel_dirname}/${initrd}
EOF
    fi
  fi
  sed "s/^/$submenu_indentation/" &lt;&lt; EOF
}
EOF
}

machine=`uname -m`
case "$machine" in
    i?86 | x86_64) klist="/boot/vmlinuz-* /vmlinuz-* /boot/kernel-*" ;;
    s390 | s390x)  klist="/boot/image-* /boot/kernel-*" ;;
    aarch64)       klist="/boot/Image-* /boot/kernel-*" ;;
    *) klist="/boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* \
        /boot/kernel-*" ;;
esac
list=`for i in $klist; do
    if grub_file_is_not_garbage "$i" ; then
        echo -n "$i " ;
    fi
    done`

case "$machine" in
    i?86) GENKERNEL_ARCH="x86" ;;
    mips|mips64) GENKERNEL_ARCH="mips" ;;
    mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
    arm*) GENKERNEL_ARCH="arm" ;;
    *) GENKERNEL_ARCH="$machine" ;;
esac

PLATFORM="native"
if  -d /sys/firmware/efi ]&& "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
    PLATFORM="efi"
else
    case "$machine" in
        s390*) PLATFORM="emu" ;;
    esac
fi

prepare_boot_cache=
prepare_root_cache=
boot_device_id=
title_correction_code=

# Extra indentation to add to menu entries in a submenu. We're not in a submenu
# yet, so it's empty. In a submenu it will be equal to '	' (one tab).
submenu_indentation=""

is_top_level=true
while  "x$list" != "x" ] ; do
  linux=`version_find_latest $list`
  gettext_printf "Found linux image: %s
" "$linux" &gt;&2
  basename=`basename $linux`
  dirname=`dirname $linux`
  rel_dirname=`make_system_path_relative_to_its_root $dirname`
  if  $PLATFORM != "emu" ]; then
    hotkey=0
  else
    if  "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] &&
        "x${GRUB_FS}" = "xbtrfs" ] ; then
       rel_dirname="\${btrfs_subvol}$dirname"
    else
       rel_dirname="$dirname"
    fi
  fi
  version=`echo $basename | sed -e "s,^^0-9]*-,,g"`
  alt_version=`echo $version | sed -e "s,\.old$,,g"`
  linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"

  initrd=
  for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
       "initrd-${version}" "initramfs-${version}.img" \
       "initrd.img-${alt_version}" "initrd-${alt_version}.img" \
       "initrd-${alt_version}" "initramfs-${alt_version}.img" \
       "initramfs-genkernel-${version}" \
       "initramfs-genkernel-${alt_version}" \
       "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
       "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
    if test -e "${dirname}/${i}" ; then
      initrd="$i"
      break
    fi
  done

  config=
  for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
    if test -e "${i}" ; then
      config="${i}"
      break
    fi
  done

  # try to get the kernel config if $linux is a symlink
  if test -z "${config}" ; then
    lnk_version=`basename \`readlink -f $linux\` | sed -e "s,^^0-9]*-,,g"`
    if (test -n ${lnk_version} && test -e "${dirname}/config-${lnk_version}") ; then
      config="${dirname}/config-${lnk_version}"
    fi
  fi

  # check if we are in xen domU
  if  ! -e /proc/xen/xsd_port -a -e /proc/xen ]; then
    # we're running on xen domU guest
    dmi=/sys/class/dmi/id
    if  -r "${dmi}/product_name" -a -r "${dmi}/sys_vendor" ]; then
      product_name=`cat ${dmi}/product_name`
      sys_vendor=`cat ${dmi}/sys_vendor`
      if test "${sys_vendor}" = "Xen" -a "${product_name}" = "HVM domU"; then
        # xen HVM guest
        xen_pv_domU=false
      fi
    fi
  else
    # we're running on baremetal or xen dom0
    xen_pv_domU=false
  fi

  if test "$xen_pv_domU" = "false" ; then
    # prevent xen kernel without pv_opt support from booting
    if (grep -qx "CONFIG_XEN=y" "${config}" 2&gt; /dev/null && ! grep -qx "CONFIG_PARAVIRT=y" "${config}" 2&gt; /dev/null); then
      echo "Skip xenlinux kernel $linux" &gt;&2
      list=`echo $list | tr ' ' '
' | grep -vx $linux | tr '
' ' '`
      continue
    fi
  fi

  initramfs=
  if test -n "${config}" ; then
      initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"`
  fi

  if test -n "${initrd}" ; then
    gettext_printf "Found initrd image: %s
" "${dirname}/${initrd}" &gt;&2
  elif test -z "${initramfs}" ; then
    # "UUID=" and "ZFS=" magic is parsed by initrd or initramfs.  Since there's
    # no initrd or builtin initramfs, it can't work here.
    linux_root_device_thisversion=${GRUB_DEVICE}
  fi

  if  "x$is_top_level" = xtrue ] &&  "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
    linux_entry "${OS}" "${version}" simple \
    "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"

    submenu_indentation="$grub_tab"
    
    if  -z "$boot_device_id" ]; then
    boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
    fi
    # TRANSLATORS: %s is replaced with an OS name
    echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' $(print_hotkey) \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
    hotkey=$(incr_hotkey)
    is_top_level=false
  fi

  linux_entry "${OS}" "${version}" advanced \
              "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
  if  "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
    linux_entry "${OS}" "${version}" recovery \
                "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_RECOVERY}"
  fi

  list=`echo $list | tr ' ' '
' | grep -vx $linux | tr '
' ' '`
done

# If at least one kernel was found, then we need to
# add a closing '}' for the submenu command.
if  x"$is_top_level" != xtrue ]; then
  echo '}'
fi

echo "$title_correction_code"


and the lines are many :), where I have to add nouveau??
manythanks

Just some musing…

Wonder if a different approach that either uninstalls or installs the nVidia driver on boot (or with a reboot), invoked early in the boot sequence (ie. as a requirement to achieve multi-user.target, or before plymouth can start to load). The nVidia and nouveau files can be cached.

This approach would likely be implemented as a GRUB menu option, and would avoid setting up an nVidia and nouveau configuration side by side (and would therefor not require a working update-alternatives).

It would seem to me that this suggested approach would be a “more natural” approach that is consistent with the current architecture that requires only one or the other, and not both drivers to be installed (and used) at a time. This might also be a better approach now that today’s GPU drivers are kernel-mode so have to be compiled on demand during boot instead of the very old days when User mode drivers can simply be switched. AFAIK from what I’ve observed, GPU drivers are compiled into the kernel during boot, not implemented as kernel loadable modules so I really doubt any approach that was described in the forum thread about creating a script to switch would work.

TSU

Yes, I haven’t verified.

Yes, it’s actually 10_linux that creates your Linux/openSUSE boot menu entry.

I suppose it should be /etc/grub.d/10_linux
and there isn’t a line starting with ‘linux=’/‘linuxefi=’

With “linux” or “linuxefi”, they are in the linux_entry() function that creates a Linux boot menu entry.

#! /bin/sh
set -e

# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
...
linux_entry ()
{
...

  message="$(gettext_printf "Loading Linux %s ..." ${version})"
  if  -d /sys/firmware/efi ] &&  "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
    sed "s/^/$submenu_indentation/" << EOF
    echo    '$(echo "$message" | grub_quote)'
    linuxefi ${rel_dirname}/${basename} ${root_device} ro ${args}
EOF
  else
    sed "s/^/$submenu_indentation/" << EOF
    echo    '$(echo "$message" | grub_quote)'
    linux    ${rel_dirname}/${basename} ${root_device} ${args}
EOF
  fi
...

append nouveau at the end of those two lines, after the “${args}”.
(of course there would also be other ways to do it… :wink: )

And you would probably also want to modify the title, so that you can identify and select the correct one.
Search for “title=”… :wink:

plymouth is started even before / is mounted.

But actually that script does some form of “uninstallation”.
It switches between nvidia’s files and Mesa’s.

And TBH, personally I wouldn’t want to have the nvidia driver being installed or uninstalled during boot, this can take minutes…

This approach would likely be implemented as a GRUB menu option, and would avoid setting up an nVidia and nouveau configuration side by side (and would therefor not require a working update-alternatives).

This would again require two independent systems, or some startup script that does the work you mentioned.

So in the end it would be exactly the same.

AFAIK from what I’ve observed, GPU drivers are compiled into the kernel during boot, not implemented as kernel loadable modules

That’s nonsense.

THe GPU drivers’ kernel modules are loadable modules like all other kernel modules, and are loaded during boot.
In the case of the nvidia driver the kernel module is compiled at installation time, because the nvidia driver only comes with the kernel module’s source code (it would be impossible to ship modules for all available kernel versions, flavors, and so on).
But again, it will not be compiled into the kernel. It will be copied to /lib/modules/ then during installation, where the kernel can load it from (or not).

I’m not running an nvidia GPU at the moment, so haven’t looked at this for a year or so…
Are you sure that the GPU is compiled as a <loadable> kernel module?
Today’s Linux kernel loads as a base “monolithic” part where I thought the GPU is compiled into, and then during boot or sometimes later, the “second half” of the kernel which includes the <loadable> kernel modules are added only after then the boot sequence continues.

Unless I didn’t interpret what I’ve seen correctly, this is the reason why you you can’t willy-nilly switch between display drivers without a reboot (because the GPU drivers have to be compiled into the monolithic part which can’t change during that system session).

Note that I’m not saying that display drivers aren’t distributed as a package/module, I’m saying that the <type> of module is important, and that GPU drivers are not distributed as KLM (kernel loadable modules), or at least that was my educated guess which could turn out to be wrong(?!).

If I’m wrong, a telling indicator would be that you can switch between nvidia and nouveau kernel mode drivers without a reboot.

TSU

Yes.

Otherwise you’d need to recompile the module and the kernel on each kernel update.
(To compile something into the kernel, you’d need to compile the kernel itself too)

If I’m wrong, a telling indicator would be that you can switch between nvidia and nouveau kernel mode drivers without a reboot.

The problem is that you cannot unload the kernel module while the device is in use (and normally it is in use even in “text” mode).
And you maybe cannot completely reinitialize the graphics card if it is/was in use already (without a reboot).

Other than that, it should indeed work to switch to text mode, install/uninstall the nvidia driver, and then start graphics mode again, to switch between nvidia and nouveau.
But IMHO that’s even more complicated, and as I said, (un)installing the nvidia driver (and compiling the kernel module) can take quite long.

done, but it doesn’t works, no new line in grub,
so I added nouveau using grub editor (pressing “e” )
I get a non-graphic login, so I uninstalled nvidia drivers
but now I have a graphic-login but cannot login, plasma5 gives me this error:
could not start kdeinit5, check your installation
kde4 doesn’t login, gnome doesn’t login, icewm login but cannot start yast
what can I do to have a working leap??

You need to run “sudo grub2-mkconfig -o /boot/grub2.cfg” afterwards to recreate the boot menu.

But the good news is that this will be done automatically when you install kernel updates.

so I added nouveau using grub editor (pressing “e” )
I get a non-graphic login, so I uninstalled nvidia drivers

Why did you uninstall the nvidia driver?

Just reboot and do not add the “nouveau” option.

Editing the boot menu in place (via pressing ‘e’) does not permanantly change anything.

but now I have a graphic-login but cannot login, plasma5 gives me this error:
could not start kdeinit5, check your installation
kde4 doesn’t login, gnome doesn’t login, icewm login but cannot start yast
what can I do to have a working leap??

Find out what went wrong.

As a first step, look at /var/log/Xorg.0.log.

I would guess that you miss libglx or libGL though.
Try to reinstall Mesa-libGL1 and run:

sudo update-alternatives --set libglx.so /usr/lib64/xorg/modules/extensions/xorg/xorg-libglx.so

to activate Xorg’s libglx.

PS: instead of reinstalling Mesa-libGL1, it should also suffice to run:

sudo ln -sf  /usr/lib64/libGL.so.1.2.0 /usr/lib64/libGL.so.1

:slight_smile: ok, I didn’t run it…

I remembered that anything of permanent happen pressing “e”, so I rebooted, without adding nouveau, twice, but I get a non-graphic login, so I thought that the script made something that broke something and uninstalled nvidia driver hoping that the automagic uninstallation process make the job :wink:

ok I will do

:wink: manythanks, it worked

I didn’t try this becouse I red firstly the reinstall way and it worked, I suppose it is the opposite that the script did

Actually it (both commands) is exactly what the script should do when you boot with the “nouveau” option, I even copied and pasted it.

Ok, so it seems the libglx was the (only) problem.
But I don’t see how, if the exact same commands fixed your system afterwards…

Can you please post your current script (copy/paste it) to see whether you made some mistake maybe?

Also, try to add this line, maybe it would help:

#Make sure we are in command of /usr/X11R6/lib
if  -e /etc/ld.so.conf.d/nvidia-gfxGO*.conf ]; then
    /bin/rm /etc/ld.so.conf.d/nvidia-gfxGO*.conf
fi  

#Check graphics mode fix symlinks
if  `grep -c "nouveau" /proc/cmdline` -gt 0 ]; then
    update-alternatives --set libglx.so /usr/lib64/xorg/modules/extensions/xorg/xorg-libglx.so
    /sbin/ldconfig /usr/lib64
    /bin/cat > /etc/X11/xorg.conf.d/20-nouveau.conf << END 
Section "Device"
Driver "nouveau"
EndSection
END
    # use Mesa's libGL
    ln -sf  /usr/lib64/libGL.so.1.2.0 /usr/lib64/libGL.so.1
fi 

if  `grep -c "nouveau" /proc/cmdline` -eq 0 ]; then
    update-alternatives --set libglx.so /usr/lib64/xorg/modules/extensions/nvidia/nvidia-libglx.so
    /sbin/ldconfig /usr/X11R6/lib64
    /bin/rm /etc/X11/xorg.conf.d/20-nouveau.conf
    # use nvidia's libGL
    ln -sf  /usr/X11R6/lib64/libGL.so.1 /usr/lib64/libGL.so.1
fi

PS: Actually it is to be expected that that script will break your system if you uninstall the nvidia driver.
The script is still run on boot, and if you don’t set “nouveau” it will try to activate the nvidia driver (its OpenGL libraries), which of course will fail if the driver is not installed leaving you with no OpenGL at all (which in turn makes Plasma5, GNOME, and many other applications just fail to start completely).

So, if you uninstall the nvidia driver, you need to disable or remove the script before you reboot, or add “nouveau” to the boot options.

It would of course also be possible to change the script to use nouveau by default, and only switch to nvidia if some special boot option is added.

ok, now that I know how to come back to a working system I’ll start again from zero :slight_smile:
uninstalled nvidia drivers
deleted the /etc/grub.d/10_linux_nouveau
deleted the script in boot.local
–the system works–

later, after a bit of sun see and sand of beach :wink: I’ll:
reinstall the nvidia drivers
insert the script in boot.local
try adding “nouveau” typing “e” at boot
–so the only test is on the script–

manythanks, ciao, pier :slight_smile:

First, a quick comment on what I posted before about the nvidia “module”

Wolfi is right that the nvidia driver is installed and accessed as a loadable kernel module, in fact <all> the GPU modules that are distributed by the mainline kernel or are later installed can be found in the following location

/lib/modules/`uname -a`/kernel/drivers/gpu/drm/

But, I also found what misled me, it was not my imagination that the initrd is modified on boot to support the nvidia module, apparently a new linking interface has to be installed to access the nvidia module, the nvidia module isn’t automatically accessible without these initrd modifications which are typically not required by usual loadable kernel modules.

So, I then looked at the nvidia RPM package itself to see if it might actually be possible to switch between nvidia and nouveau. Of course, if you can switch GPU drivers without a reboot, then you should easily be able to also switch on boot. I didn’t see any show-stopper in the RPM package contents but there is an interesting comment in the code

Modprobe blacklist files have been created at /etc/modprobe.d to prevent Nouveau from loading. This can be reverted by deleting 
/etc/modprobe.d/nvidia-*.conf

So, today it might be possible to switch between the nvidia and nouveau drivers by simply removing or writing this one file?
So, something like the following can be tried


#this file switches from an installed nVidia driver to nouveau
mv /etc/modprobe.d/nvidia*.conf /etc/

And the following would reverse the previous


#this file switches from nouveau to an already installed nVidia driver
mv /etc/nvidia*.conf /etc/modprobe.d/

And then, if the above removal (or insertion) of the nouveau blacklisting isn’t effective immediately, then the system can be rebooted to determine its effect.

It should also be noted that the RPM package code creates an update-alternatives entry, all the discussion in this thread about creating one may be superfluous, although I don’t know how to find or access this setting.

I think it should also be noted that when you install the nVidia driver on a machine which has never before had the nvidia driver installed, there are a <great many> changes made to the machine… But, it may not matter when changing back to nouveau, either the new nVidia components might be usable by nouveau or configuration changes made when removing the nouveau blacklisting might automatically disable using the nvidia changes. This just needs to be tested.

Lastly the person who created the openSUSE RPM package might be contacted for any questions about his RPM code (sndirsh).

The RPM package I was looking at is the gfxG04 for LEAP 42.1.

TSU

Yes, the nvidia kernel module is added to the initrd (like nouveau or others depending on what card/driver you use).
That’s necessary to be able to load it before the / filesystem is mounted.

The nvidia module would be “automatically accessible without these initrd modifications”, but only at a later point during boot, when / is mounted already.
The only reason for this is plymouth, the boot splash. This is started as early as possible (i.e. before / is mounted) to get a smooth boot experience, and it loads the GPU kernel module.

After / is mounted, the initrd is not used at all any more, and kernel modules are loaded from the real /.

Disabling plymouth (either by uninstalling it, or adding plymouth.enable=0 to the boot options) should eliminate every need to have a GPU kernel module in the initrd.
So, if the script is not working as expected, this (disabling plymouth) may be worth a try, because the reason may be that the nvidia kernel module is already loaded by plymouth and blocks the use of nouveau.

But the Xorg log should show if this is the problem.

So, I then looked at the nvidia RPM package itself to see if it might actually be possible to switch between nvidia and nouveau. Of course, if you can switch GPU drivers without a reboot, then you should easily be able to also switch on boot. I didn’t see any show-stopper in the RPM package contents but there is an interesting comment in the code

[QUOTE]

Modprobe blacklist files have been created at /etc/modprobe.d to prevent Nouveau from loading. This can be reverted by deleting 
/etc/modprobe.d/nvidia-*.conf

Not really necessary.
The blacklist only prevents automatic loading by the kernel if it detects the corresponding hardware.

The kernel module can still be loaded if needed (i.e. if the Xorg graphics driver is loaded) even if it is blacklisted.

And it would be too late anyway to remove that blacklist file during boot (in that script).

It should also be noted that the RPM package code creates an update-alternatives entry, all the discussion in this thread about creating one may be superfluous, although I don’t know how to find or access this setting.

That’s for the libglx (to be able to switch between Xorg’s libglx and nvidia’s libglx). The script takes care of this.

I think it should also be noted that when you install the nVidia driver on a machine which has never before had the nvidia driver installed, there are a <great many> changes made to the machine…

Not really.
The package basically installs some files (which get removed on uninstallation again), sets the libglx link to nvidia’s, and runs mkinitrd (to remove nouveau from the initrd and add nvidia), that’s all.

Wolfi,
When you say that the nouveau or nVidia driver is loaded before / is mounted, that’s new to me.
And, I typically see the GPU compilation bootlog entries <after> GRUB has loaded and as part of the preparation to loading Plymouth(anyone can see by hitting ESC to view boot process after the GRUB menu selection).

If you’re talking about when GRUB runs, I’m sure that today it always loads a VESA driver, never a more capable video driver (It’s still in the code last I checked). If a more capable driver is loaded prior to when Plymouth is loaded, I have never seen evidence and I’d be very surprised if it’s loaded for some reason prior to GRUB only to be unloaded in favor of VESA.

The commands I proposed to remove and re-instate the nouveau blacklist might be tried anyway. To me, the code comment suggests that if the blacklist exists, then the nVidia driver is loaded… and if the blacklist does not exist, then nouveau will be loaded ahead/instead of the nVidia driver. The code comment is very brief and my interpretation of the comment may or may not be correct, so should be tested. I don’t know if something like modinstal would also need to be run to activate in a current session, in any case the blacklist change would certainly be read during a reboot.

It may be that there are less changes if the machine is already using the nouveau driver.
Since I don’t currently have a machine running an nVidia GPU, I ran a test on a non-nVidia machine and there were well over 50 proposed changes.

TSU

What do you mean with “GPU compilation bootlog entries”?
This has nothing to do with compiling anything.

If you’re talking about when GRUB runs, I’m sure that today it always loads a VESA driver, never a more capable video driver (It’s still in the code last I checked). If a more capable driver is loaded prior to when Plymouth is loaded, I have never seen evidence and I’d be very surprised if it’s loaded for some reason prior to GRUB only to be unloaded in favor of VESA.

I’m not talking about GRUB.

When the kernel loads/starts, it uses the initrd as minimal / filesystem, to be able to do the early startup and actually mount the real / (certain “drivers”/kernel modules may be needed to mount the real / in the first place).
Normally that initrd also contains plymouth and starts it (to prevent showing the text mode for a short while), and this in turn will try to load an appropriate GPU kernel module (from the initrd, as the real / is not mounted yet at that point).

The commands I proposed to remove and re-instate the nouveau blacklist might be tried anyway.

Again, when the script runs, it is much too late for that.

It may be that there are less changes if the machine is already using the nouveau driver.
Since I don’t currently have a machine running an nVidia GPU, I ran a test on a non-nVidia machine and there were well over 50 proposed changes.

And what “test” did you run this time?
Installing the nvidia driver?
The “50 proposed changes” might be recommended packages then (unrelated to the nvidia driver), and the nvidia driver will also pull in the kernel devel packages and things like gcc and make, to be able to build the kernel module on installation.
That’s unrelated to changes that the nvidia packages themselves would do to the system though.

first try.
installed nvidia drivers in leap 42.1.
rebooted twice, ok it works with nvidia drivers.
copied Xorg.0.log as Xorg.0-after-nvidia-installation-boot-ok-2016-08-15_18e11.log
inserted script in /etc/init.d/boot.local.

#Make sure we are in command of /usr/X11R6/lib
if  -e /etc/ld.so.conf.d/nvidia-gfxGO*.conf ]; then
    /bin/rm /etc/ld.so.conf.d/nvidia-gfxGO*.conf
fi  


#Check graphics mode fix symlinks
if  `grep -c "nouveau" /proc/cmdline` -gt 0 ]; then
    update-alternatives --set libglx.so /usr/lib64/xorg/modules/extensions/xorg/xorg-libglx.so
    /sbin/ldconfig /usr/lib64
    /bin/cat > /etc/X11/xorg.conf.d/20-nouveau.conf << END 
Section "Device"
Driver "nouveau"
EndSection
END
    # use Mesa's libGL
    ln -sf  /usr/lib64/libGL.so.1.2.0 /usr/lib64/libGL.so.1
fi 


if  `grep -c "nouveau" /proc/cmdline` -eq 0 ]; then
    update-alternatives --set libglx.so /usr/lib64/xorg/modules/extensions/nvidia/nvidia-libglx.so
    /sbin/ldconfig /usr/X11R6/lib64
    /bin/rm /etc/X11/xorg.conf.d/20-nouveau.conf
    # use nvidia's libGL
    ln -sf  /usr/X11R6/lib64/libGL.so.1 /usr/lib64/libGL.so.1
fi

rebooted twice leap 42.1 with plasma5 (in case the script be activated without inserting nouveau), ok it works.
entered in grub edit mode during boot of leap 42.1 pressing “e”.
activated the script, inserted nouveau after vga=791 in the line:

linux      /boot/vmlinuz-4.1.27-27-default root=UUID167d3751-360f-4d2e-b342-27f62b8b16b7 resume=/dev/disk/by-label/swap splash=silent quiet showopts \vga=791 nouveau

leap 42.1 boot but after starting nvidia drivers and nvidia graphic login window (I saw nvidia splash and I recognize the nvidia login window from the nouveau login window becouse nvidia doesn’t show the full name of the default user but only the initial and some dots and the window is bigger than nouveau).
logged in but this error pop up “Plasma is unable to start as it could not correctly use OpenGL 2. Please check that your graphic driver are set up correctly”
cannot exit from that screen wth clicks, so ctrl>backspace_twice, I get no login window at all nor graphic nor text, so ctrl>alt>f2 logged in as root, rebooted.
rebooted in opensuse 13.2 (another very useful emergency installation in another partition :)) and copied from the leap 42.1 partition /var/log/Xorg.0.log as /var/log/Xorg.0-after-nvidia-installation-and-script-activated-boot1-failed-2016-08-15_19e05.log
rebooted in leap 42.1 without inserting nouveau at boot, I get a text login window, logged in, rebooted in opensuse 13.2 and made the same as upon renaming leap 42.1/var/log/Xorg.0.log as /var/log/Xorg.0-after-nvidia-installation-and-script-activated-boot2-failed-2016-08-15_19e20.log

manythanks, ciao :), pier

I used an inexact term saying the GPU was “compiled” during boot, should have said that the initramfs is <modified> during boot.

I couldn’t find SUSE/openSUSE documentation describing the how the graphical driver(s) is loaded during the boot sequence but I found this Ubuntu article which to my eye describes all or most current Linux systems using GRUB2, and applies 100% to how I understand current openSUSE systems work

https://wiki.ubuntu.com/BootGraphicsArchitecture

This reference should be very pertinent to this overall discussion to understanding how and when display drivers start up in the boot sequence.
Special note is the section “Kernel video initialization” which discusses when two drivers(even mentions nouveau and nvidia, also mentions radeon and fglrx) are loaded simultaneously for the same hardware (ie. simply removing blacklisting. It appears that if blacklisting is the preferred method, it may be important to not just remove a blacklisting but to also impose a blacklisting for the remaining possible driver(s)).

The article also describes fully in much better details and words than myself that indeed, GRUB loads the VESA driver (from BIOS) and does not hand over to the more advanced video driver until much later when the framebuffer interface is initialized…

TSU