Galère avec les drivers NVidia sous Linux?

Retour à la page Systèmes

Motivation Prérequis Le principe

Exemple

Motivation

NVidia met quelques jours (et parfois beaucoup plus) pour publier des versions de ses drivers qui soient compatibles avec les derniers noyaux Linux.

Les adaptations d'une version de noyau à l'autre ne concernent cependant que quelques appels système, que l'on peut adapter manuellement.

Cet article a été entamé le 20/10/2013 sur une distribution Fedora 18 avec un bureau GNOME 3.6.
L'auteur l'a fait (une fois de plus) pour résoudre rapidement son propre problème, et n'exclut nullement qu'il existe des solutions plus élégantes.

Les pistes proposées ici sont directement inspirées des discussions du forum NVidia/Linux (NVIDIA/DevZone/Forums/GPU Unix/Linux)

Prérequis

Afin d'éviter les malentendus, voici ce qui est supposé à propos du lecteur:

  • Familier avec l'installation standard de drivers NVidia sous Linux (à partir du .run)
  • Avec une connaissance minimale des outils courants du monde GNU/Linux: git, patch, diff ...
  • Avec quelques connaissances en programmation C (utile pour comprendre les messages d'erreur).

Le principe

Prendre un driver de base

Télécharger le driver drvversion.runqui fonctionnait sur le noyau le plus récent: c'est lui que l'on va essayer de patcher.

Puis extraire les sources (eh oui il y a une option pour ça)

% ./drvversion.run -x
% cd drvversion

Suivre les changements de code

On peut utiliser git pour suivre les changements de code (une autre méthode consisterait à ré-extraire les sources ailleurs à partir du .run, puis à faire un diff)

% git init .
% cd kernel/
% git add *.c *.h
% git commit -a

Changer ou Patcher le code

% who -r
         run-level 3  2013-03-10 14:18                   last=3
% cd drvversion
% ./nvidia-installer
% #Si ça marche passer à la section qui suit ...
% #Sinon:
% #  Chercher 'error:' dans /var/log/nvidia-installer.log
% # corriger les erreurs mentionnées dans /var/log/nvidia-installer.log
% # --* patch -p1 <telechargement_forum>
% # --* ou bien bricolage manuel

Archiver le patch

% git commit -a
% git diff <initial> HEAD > mon-patch.txt

Donner un nom raisonnable au patch, comme NVidia_drvversion_noyau.patch

Exemple

Voici ce que j'ai fait pour faire fonctionner le driver 319.17 sur un noyau 3.11.4

Essai naïf

% ./NVIDIA-Linux-x86-319.17.run -x
% cd NVIDIA-Linux-x86-319.17
% ./nvidia-installer

Après échec de l'installation, nvidia-installer.log contient:

NVIDIA-Linux-x86_64-325.08/kernel/nv-i2c.c:252:14: error: void value not ignored as it ought to be

Recherche d'une solution prète à consommer

Une recherche Google sur le message d'erreur envoie rapidement à la page de forum où l'intervenant du 7/2/2013 à 5h36 propose un patch (adapté de 319.23) pour compiler le driver 319.17 sur un noyau 3.10.

nvidia-drivers-linux-3.10.patch.txt

Le noyau 3.10 n'est évidemment pas 3.11.4, mais on s'en rapproche.
On commence donc par essayer d'appliquer le patch:
patch --dry-run -p1 < nvidia-drivers-linux-3.10.patch.txt
patching file kernel/nv-i2c.c
patching file kernel/nv-procfs.c
Hunk #9 FAILED at 424.
1 out of 15 hunks FAILED -- saving rejects to file kernel/nv-procfs.c.rej

Qu'est-ce que ça veut dire?

  • nv-i2c.c a été modifié comme il faut.
  • Dans nv-procfs.c, 14 modifications ont bien été faites, sauf une
  • La modification qui n'a pas pu être appliquée est décrite dans nv-procfs.c.rej
git commit -a -m 'patch1-fail9'

On édite "à la main" nv-procfs.c selon les indications de nv-procfs.c.rej, puis on contrôle que les modifications n'ont pas été oubliées

% git diff >modifs.txt
% diff modifs.txt nv-procfs.c.rej
1,5c1,3
< diff --git a/kernel/nv-procfs.c b/kernel/nv-procfs.c
< index 8a16c8d..e754e9f 100644
< --- a/kernel/nv-procfs.c
< +++ b/kernel/nv-procfs.c
< @@ -424,122 +424,81 @@ done:
---
> --- kernel/nv-procfs.c 2013-04-26 00:22:30.000000000 -0400
> +++ kernel/nv-procfs.c 2013-05-22 04:52:45.229495748 -0400
> @@ -424,121 +502,80 @@
47d44
<
104a102,103
> -
> -    bytes_left = (NV_PROC_WRITE_BUFFER_SIZE - nvfp->off - 1);
107,108d105
< -    bytes_left = (NV_PROC_WRITE_BUFFER_SIZE - nvfp->off - 1);
< -

Il semble vraiment que la différence ne tenait qu'à de malheureux espaces blancs. On peut retenir ce changement:

% git commit -a 'patch1-ok'

Et on reessaye:

% cd drvversion
% ./nvidia-installer

Enfer et damnation! Il y a cette fois-ci une erreur dans os-interface.c, où num_physpages n'est pas défini.

Bricolage manuel

  • Les patches récents trouvés çà et là sur le net suggèrent que num_physpages doit être remplacé par get_num_physpages() dans nv-linux.h.
  • On edite donc le fichier manuellement, et on regarde la différence à la fin: