Installer les pilotes nvidia sous Linux Debian

mamiemando Messages postés 34194 Date d'inscription   Statut Modérateur Dernière intervention   -  

Sommaire

  • I. Préliminaires : secure boot
  • II. Installer le pilote propriétaire NVIDIA
    • Méthode 1 (recommandée) : via les paquets Debian
    • Méthode 2 (déconseillée) : Installation avec le script NVIDIA
  • III. Tests
  • IV. En cas de problème
    1. Module nvidia inexistant
    2. Impossible de charger le module nvidia
      1. Création de la paire de clés
      2. Signature du module
    3. nvidia-smi et nvidia-settings ne se lancent pas
    4. Écran noir
    5. Écran noir au démarrage, mais pas quand on relance le mode graphique
    6.  Le mode graphique charge, puis l'ordinateur reste bloqué.
  • IV. Alternative : Installer sur le pilote libre (nouveau)
  • Liens utiles
  • Annexe : signature manuelle d'un module

I. Préliminaire : secure boot

1) Installer les paquets suivantes :

sudo apt install mokutil sbsigntool

2) Vérifier si le Secure boot est actif :

sudo mokutil --sb-state

Si oui, il faudra être vigilant à ce que le module que l'on s'apprête à installer soit correctement signé, sans quoi le noyau Linux refusera de la charger tant que le Secure boot sera activé.

Pour résoudre ce problème, deux méthodes sont possibles.

Méthode 1 : désactiver le secure boot

Cette méthode n'est pas envisageable si un Windows est installé en dual boot, car Windows refusera de démarrer si le secure boot est désactivé.

sudo mokutil --disable-validation

L'outil proposera de choisir un mot de passe. Au redémarrage, UEFI posera des question sur ce mot de passe pour effectivement désactiver le Secure boot.

Méthode 2 : signer le module nvidia

Ces étapes sont inspirées de la page Wiki Debian: SecureBoot

1) Si les fichiers /var/lib/shim-signed/mok/MOK.priv et /var/lib/shim-signed/mok/MOK.der n'existent pas, il va falloir les créer. Dans la dernière commande remplacer "Prénom Nom" par une chaîne arbitraire.

sudo apt install openssl
sudo mkdir -p /var/lib/shim-signed/mok
sudo openssl req -nodes -new -x509 -newkey rsa:2048 -outform DER -keyout /var/lib/shim-signed/mok/MOK.priv -out /var/lib/shim-signed/mok/MOK.der -days 3650 -subj "/CN=mando@velvet/"
sudo chmod 600 /var/lib/shim-signed/mok/MOK.*

Quelques explications :

  • -nodes : Pas de chiffrement DES, i.e., les clés générées ne sont pas protégées par un mot de passe. Ceci est nécessaire en vue de les exploiter dans DKMS aisément.
  • -outform DER : Génère la clé publique au format DER (Distinguished Encoding Rules). C'est ce qui est attendu par le système de management MOK Machine Owner Key) propre au Secure boot.
  • "/CN=mando@velvet/" : remplacer par un nom arbitraire sans / (par exemple, votre nom et prénom), c'est l'identifiant de signature qui permettra par la suite de reconnaître cette clé.

Si la commande suivante fonctionne, c'est que la clé est au bon format :

sudo openssl x509 -inform DER -in /var/lib/shim-signed/mok/MOK.der -text -noout

Puis on enregistrer la clé publique dans le système de management MOK.

sudo mokutil --import /var/lib/shim-signed/mok/MOK.der

Au redémarrage, on peut vérifier que le certificat X509 que l'on vient de générer est bien chargé avec la commande

sudo dmesg | grep cert

 Il sera alors possible de signer des modules à l'aide DKMS.

2) Il faut à présenter configurer les clés propres à DKMS  :

sudo dkms generate_mok
sudo mokutil --import /var/lib/dkms/mok.pub
sudo mokutil --list-new

Quelques explications :

  • La commande "dkms generate_mok" génère une paire de clé (/var/lib/mok.pub et /var/lib/mok.key), utilisée par DKMS (Dynamic Kernel Module Support) pour signer les modules (fichiers *.ko) qu'il compilera.
  • La commande "mokutil --import ..." demande un mot de passe à usage unique sur lequel le système MOK posera une question au redémarrage pour que cette clé soit enregistrée (enroll).
  • La commande "mokutil --list-new" permet de vérifier que la clé nouvellement générée fera partie des clés à enregistrer (enroll) au prochain redémarrage.

Cela devrait créer une paire de clé MOK (Machine Owner Keys):

  • /var/lib/dkms/mok.key (clé privée)
  • /var/lib/dkms/mok.pub (clé publique)

DKMS utilise par défaut ces chemins (comme stipulé dans /etc/dkms/framework.conf) pour signer les modules qu'il compile, et donc en particulier tous les modules fourni par un paquet debian dont le suffixe est "...-dkms". Cela concerne en particulier les modules propriétaires empaquetés par Debian, dont le paquet nvidia-kernel-dkms, en charge de construire le module nvidia.

Remarque : il est aussi possible de générer ses propres clés, voir en annexe.

II. Installer le pilote propriétaire nvidia

Ce tutoriel présente comment installer les drivers propriétaires nvidia sous Debian. De nos jours il existe deux grandes méthodes :

  • Méthode 1 : via les paquets debian : c'est la méthode la plus simple et la plus propre. Le pilote est mis à jour avec le reste du système. C'est donc naturellement l'approche recommandée.
  • Méthode 2 : via le script d'installation nvidia. Cette méthode permet parfois d'avoir un driver plus récent, mais doit être refaite chaque fois que le noyau (paquet linux-image) est mis à jour.
  • Méthodes obsolètes : dans des temps reculés on pouvait utiliser envy, module-assistant, make-kpkg. Toutes ces méthodes sont aujourd'hui obsolètes.

Méthode 1 (recommandée) : via les paquets debian

1) Par défaut, Debian ne propose que des paquets libres. Or le pilote nvidia est propriétaire, donc pas disponible par défaut. Pour remédier à ce problème il faut activer les dépôts contrib, non-free. Comme expliqué ici, pour les debian bookworm (debian 12) et plus récentes, un nouveau dépôt, non-free-firmware est apparu, et c'est une bonne idée de l'ajouter notamment pour prendre en charge sa carte wifi !

Pour corriger les dépôts Debian utilisés par APT, on corrige le fichier /etc/apt/sources.list par exemple avec gedit :

sudo gedit /etc/apt/sources.list &

Ajouter à côté de main les mots-clés contrib, non-free, et éventuellement non-free-firmware.

Exemple :

deb http://ftp.fr.debian.org/debian/ testing main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security/ testing/updates main contrib non-free non-free-firmware
deb http://ftp.fr.debian.org/debian/ testing-updates main contrib non-free non-free-firmware

2) Installer le paquet xserver-xorg-video-nvidia (qui installera en cascade notamment nvidia-kernel-dkms)

sudo apt update
sudo apt upgrade
sudo apt install xserver-xorg-video-nvidia

Remarque : il existe d'autres pilotes, qui peuvent être plus indiqué selon le modèle de la carte. Pour voir la liste complète :

apt search xserver-xorg-video-nvidia

On peut aussi installer et lancer nvidia-detect pour déterminer le paquet adéquat :

sudo apt install nvidia-detect
nvidia-detect

Remarque : si vous utilisez le secure boot et qu'il y a une erreur de certificat, vous êtes potentiellement affecté par ce bug.

3) Redémarrer.

sudo reboot

Méthode 2 (déconseillée) : Installation avec le script nvidia

1) Installer les paquets nécessaires :

sudo apt install linux-headers-$(uname -r) build-essential

2) Télécharger le script nvidia, par exemple dans /tmp (si vous choisissez un autre dossier, pensez à adapter les commandes suivantes en conséquence).

3) Passer en mode texte (ctrl alt f2, s'identifier en root) et stopper gestionnaire de connexion (typiquement lightdm, sddm, etc.) :

sudo /etc/init.d/*dm stop

4) Lancer le script d'installation :

sudo sh /tmp/NVIDIA-Linux-*.run

5) Redémarrer :

sudo reboot

Tests

Test 1 : vérifier que le module nvidia est chargé

Vérifier que le module est chargé avec la commande :

lsmod | grep nvidia

Exemple :

nvidia_drm            126976  3
drm_ttm_helper         16384  1 nvidia_drm
nvidia_modeset       1605632  2 nvidia_drm
nvidia              60710912  26 nvidia_drm,nvidia_modeset
drm_client_lib         12288  2 nvidia_drm,i915
drm_kms_helper        258048  5 drm_display_helper,drm_ttm_helper,nvidia_drm,drm_client_lib,i915
drm                   835584  35 i2c_hid,drm_kms_helper,drm_display_helper,nvidia,drm_buddy,drm_ttm_helper,nvidia_drm,drm_client_lib,i915,ttm
video                  81920  4 asus_wmi,asus_nb_wmi,i915,nvidia_modeset

Test 2 : vérifier que les utilitaires nvidia fonctionnent

1) Installer le paquet nvidia-smi :

sudo apt install nvidia-smi

2) Vérifier que la carte est bien reconnue avec la commande suivante :

nvidia-smi

Exemple :

(mando@aldur) (~) $ nvidia-smi
Mon May  4 22:38:46 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.82       Driver Version: 440.82       CUDA Version: N/A      |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce MX150       On   | 00000000:02:00.0 Off |                  N/A |
| N/A   49C    P8    N/A /  N/A |     14MiB /  2002MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0       750      G   /usr/lib/xorg/Xorg                            14MiB |
+-----------------------------------------------------------------------------+

III. En cas de problème

De manière générale, il faut commencer par regarder les erreurs reportées par les commandes suivantes :

lsmod | grep nvidia
grep EE /var/log/Xorg.0.log
  • La première liste les modules nvidia chargés (s'ils sont chargés). S'ils ne le sont pas il faut comprendre pourquoi.
    1. Vérifier que le module  nvidia a été compilé et installé pour le noyau actuel. En effet, chaque noyau Linux utilise son propre jeu de module (voir /lib/modules).
    2. Contrôler que le module nvidia se charge pour le noyau courant. Si ça n'est pas le cas c'est sans doute un problème lié au secure boot. Soit le module nvidia n'a pas signé, soit il a été signé avec une signature non enregistrée dans le système MOK, soit il y a un problème de certificat.
    3. Si le module est correctement chargé (voir lsmod), le problème peut être propre au serveur graphique (= serveur X) (typiquement wayland ou Xorg), au gestionnaire de connexion, ou autre.

1) Module nvidia inexistant

Vérifier qu'il existe bien des modules nvidia*.ko dans le dossier propre au noyau en cours de démarrage :

ls -1 /lib/modules/$(uname -r)/updates/dkms/

Exemple : 

nvidia-current-drm.ko.xz
nvidia-current.ko.xz
nvidia-current-modeset.ko.xz
nvidia-current-peermem.ko.xz
nvidia-current-uvm.ko.xz

Si la commande en question ne retourne aucun fichier nvidia*.ko*, c'est qu'il faut réinstaller les pilotes pour le noyau en cours de démarrage.

  • Ils devraient toujours exister si vous êtes passé par les paquets Debian et DKMS. 
  • Si ces fichiers sont absents et que vous avez utilisé le script NVIDIA, vous devez le relancer pour que les noyaux qui ont été installés depuis son dernier lancement aient leur propre pilote.

2) Impossible de charger le module nvidia

1) Récupérer le nom du module (de nos jours, généralement nvidia-current.ko)

ls /lib/modules/$(uname -r)/updates/dkms/nvidia*

2) Le charger à la main (sans l'extension ".ko") :

sudo modprobe nvidia-current

3) Si une modprobe apparaît, par exemple :

modprobe: ERROR: could not insert 'nvidia': Operation not permitted

... c'est que la machine probablement protégée par un secure boot qui empêche à ce stade de charger le module nvidia.

La commande modinfo permet de voir avec quelle clé un module a été signé. Normalement, on retrouve le nom renseigné au moment de généré /var/lib/shim-signed/mok/MOK.der (voir la section Préliminaires) :

sudo modinfo /lib/modules/$(uname -r)/updates/dkms/nvidia* | grep signer

Exemple : Dans ce tutoriel, on a choisi la signature mando@velvet que l'on retrouve bien. 

signer:         mando@velvet
signer:         mando@velvet
signer:         mando@velvet
signer:         mando@velvet
signer:         mando@velvet

Si aucune signature n'apparaît, le plus simple est de reprendre le tutoriel depuis le début (il faut que les clés existent avant de compiler le module nvidia).

Il faut bien entendu que le fichier ".der" correspondant ait été "enrôlé" pour que cette signature soit valide pour le noyau.

sudo mokutil --import /var/lib/shim-signed/mok/MOK.der

3) nvidia-smi et nvidia-settings ne se lancent pas

Il peut arriver que, bien que le module nvidia soit chargé (voir section précédente), mais que malgré tout, les utilitaires NVIDIA ne marchent pas.

1) Dans ce cas, lancer la commande :

grep EE /var/log/Xorg.0.log

2) Si ce genre d'erreur apparaît :

[   324.584] (EE) Failed to load module "nv" (module does not exist, 0)
[   324.670] (EE) NVIDIA(G0): GPU screens are not yet supported by the NVIDIA driver
[   324.670] (EE) NVIDIA(G0): Failing initialization of X screen

... comme indiqué dans cette discussion, il faut alors créer le fichier /etc/X11/xorg.conf.d/nvidia.conf :

sudo gedit /etc/X11/xorg.conf.d/nvidia.conf &

... et copier coller dans ce fichier le contenu suivant :

Section "ServerLayout"
    Identifier "layout"
    Option "AllowNVIDIAGPUScreens"
EndSection

3) Relancer le serveur graphique

sudo /etc/init.d/*dm restart

(ou redémarrer l'ordinateur).

4) Écran noir

Deux explications sont possibles. Dans les deux cas, il faudra la résoudre en passant en mode texte (ctrl alt f2):

  • le module nvidia est absent (voir cas A, ci-dessous)
  • le PC a plusieurs cartes graphiques et la carte nvidia n'est pas activée (voir cas B)

Cas A : le module nvidia est absent

  • Solution 1 : réinstaller le pilote propriétaire nvidia (se reporter à la section "Installer le pilote propriétaire nvidia")
  • Solution 2 : Installer le pilote libre nouveau (se reporter à la section "Alternative : installer le pilote libre nouveau")

Cas B : le PC a plusieurs cartes graphiques et la carte nvidia n'est pas activée.

1) Vérifier si la carte est activée de deux façons.

  • Méthode 1 : la carte nvidia est sensée apparaître dans les résultats de la commande :
lspci

Vérifier que la carte est toujours active une fois le mode graphique démarré :

grep EE /var/log/Xorg.0.log

Si l'erreur suivante apparaît :

Cannot access secondary GPU - error: [XORG] (EE) /dev/dri/card0: failed to set DRM interface version 1.4: Permission denied

.... la carte 3D est sans doute désactivée dans le BIOS.

  • Méthode 2 : installer le pilote via le script nvidia. Si ce dernier ne trouve pas la carte, alors peut-être que la carte est probablement désactivée au niveau du BIOS.

Solution : Redémarrer le PC, entrer dans le BIOS, et vérifier que la carte NVIDIA est bien activée (quitte à réinitialiser le BIOS avec les paramètres d'usine en cas de doute), puis réinstaller le pilote.

5) Écran noir au démarrage, mais pas quand on relance le mode graphique

Il peut arriver qu'au lancement de la machine, tout se charge correctement (le module nvidia, le mode graphique commence à se lancer) mais planter car il démarre trop lentement (typiquement plus de 20s). Or si on relance le mode graphique, celui-ci se lance correctement :

sudo /etc/init.d/*dm restart

Dans ce cas, l'erreur est inscrite dans /var/log/syslog (et non dans /var/log/Xorg.0.log). Elle a lieu si le serveur graphique a abandonné, car le chargement du pilote nvidia était trop long. Cela peut arriver sur des ordinateurs anciens. Il suffit alors d'augmenter ce délai dans le fichier de configuration de votre gestionnaire de connexion graphique (e.g., sddm ou lightdm)/ La commande suivante permet de voir quel gestionnaire de connexion est utilisé (il suffit alors de se référer à la documentation dudit gestionnaire de connexion pour paramétrer le délai de chargement)

ls /etc/init.d/*dm

6) Le mode graphique se charge, puis l'ordinateur reste bloqué

Si la machine ne réagit même pas à des raccourcis comme ctrl+alt+suppr ou un ctrl+alt+f1 alors c'est peut être une erreur noyau.

Dans ce cas deux solutions sont possibles :

  • soit installer une version plus récente du pilote nvidia
  • soit désinstaller le pilote propriétaire nvidia et installer le pilote libre nouveau à la place (voir partie suivante). Il faut alors désinstaller le pilote nvidia, car si les deux pilotes sont installés, le serveur X charge en priorité le nvidia qui prendra le pas.

Alternative : Installer sur le pilote libre (nouveau)

1) Installer le pilote nouveau

sudo apt update
sudo apt upgrade
sudo apt install xerver-xorg-video-nouveau

2) Purger le pilote nvidia

  • S'il a été installé via apt :
sudo apt purge $(dpkg -l | grep ^ii | cut -d" " -f3 | grep ^nvidia)
  • S'il a été installé par le script NVIDIA :
sudo /tmp/NVIDIA-Linux-*.run --uninstall

3) Renommer l'éventuel fichier /etc/X11/xorg.conf afin qu'il ne soit plus pris en compte et que le mode graphique démarre avec les paramètres par défaut :

sudo mv /etc/X11/xorg.conf /etc/X11/xorg.conf.old

4) Redémarrer :

sudo reboot

IV. Liens utiles

V. Annexe : signature manuelle d'un module

Cette étape doit être refaite à chaque mise à jour du noyau (paquet linux-image-*). Comme que vous serez amené à refaire cette étape régulièrement, on peut créer un script nommé /root/sigh.sh pour faciliter la signature :

sudo gedit /root/sign.sh &

On suppose dans le script suivant que les clés sont /root/MOK.der et /root/MOK.priv

#!/bin/bash
PRIV=/root/MOK.priv
DER=/root/MOK.der

for filename in $PRIV $DER
do
  (test -f $filename && echo "$filename found :-)") || (echo "$filename not found" && exit 1)
done

KBUILD_VER=$(uname -r | cut -d"." -f1,2)
echo "Kbuild version $KBUILD_VER"
cd /lib/modules/$(uname -r)/updates/dkms
for ko in $(ls -1 *.ko)
do
  echo "Signing $ko"
  /usr/lib/linux-kbuild-$KBUILD_VER/scripts/sign-file sha256 $PRIV $DER $ko
done

exit 0

Ensuite, on donne les droits en exécution à ce fichier et on l'exécute :

chmod a+x /root/sign.sh
/root/sign.sh

On peut vérifier que le module se charge désormais correctement :

sudo modprobe nvidia
sudo dmesg | tail
lsmod | grep nvidia