Attention les filles, c'est un post geek. Je vais expliquer comment installer le module binaire nvidia avec les noyaux Linux récents, présents dans Debian unstable.

Avant

Avant, c'était super facile: grâce à module-assistant, il suffisait d'avoir démarré sur le noyau dont on veut créer le module, et tapoter :

# module-assistant auto-install nvidia-kernel

Ou encore, en abrégé :

# m-a a-i nvidia-kernel

et voilà, c'était torché !

Mise à jour: ça fonctionne à présent parfaitement avec les paquets récents. La suite du billet est donc obsolète...

Le problème

Mais voilà, depuis les nouveaux noyaux, on tombe sur l'erreur suivante:

FATAL: modpost: GPL-incompatible module nvidia.ko uses GPL-only symbol 'paravirt_ops'

Il semble que ce soit une régression du noyau; en effet, le module nvidia utiliserait un symbole correctement exporté (udelay), mais qui, depuis peu, dépendrait d'un autre symbole seulement GPL. Ainsi, d'une version à l'autre du noyau, on ne peut plus utiliser un certain symbole. Voici ce que dit l'un des développeurs de nVidia:

The NVIDIA Linux graphics driver calls udelay(), which has traditionally been available to non-GPL licensed modules; it seems that on kernels configured with CONFIG_PARAVIRT, udelay() references the GPL-only symbol paravirt_ops, thereby becoming a GPL-only utility macro itself. This is a regression in the Linux kernel.

Comment résoudre ?

Je m'inspire d'un article de debianhelp.

Recompilation de linux-kbuild

La première partie de cet article, je n'y touche pas. Voici les opérations à faire :

# apt-get build-dep linux-kbuild-2.6.20

Les opérations suivantes peuvent être réalisées en tant qu'utilisateur sans privilèges.

$ mkdir linux-kbuild-2.6.20-build
$ cd linux-kbuild-2.6.20-build
$ apt-get source linux-kbuild-2.6.20

Les sources du paquet vont être installées et décompressées dans un sous-répertoire linux-kbuild-2.6-2.6.20/.

$ cd linux-kbuild-2.6-2.6.20/

Puis, il faut modifier scripts/mod/modpost.c et commenter les lignes 1197 et 1198:

/*              if (!mod->gpl_compatible)
                        check_for_gpl_usage(exp->export, basename, exp->name); */

Et enfin construire le paquet :

$ dpkg-buildpackage -uc -us -rfakeroot (the .deb is created)

Puis l'installer :

$ cd ..
# dpkg -i linux-kbuild-2.6.20_2.6.20-1_i386.deb
Compilation du module nvidia

Là, on va un peu s'éloigner de l'article, car nous, on veut créer un paquet Debian. Voici la marche à suivre:

# cd /usr/src
# m-a get nvidia-kernel
# tar xvzf nvidia-kernel-source

On va ensuite aller éditer le script de compilation Debian modules/nvidia-kernel/debian.rules Juste avant la target build-stamp, on rajoute une ligne :

PARAVIRT_OPS=$(shell grep "D paravirt_ops" /boot/System.map-`uname -r` | colrm 9)

Puis un peu plus bas, juste avant touch build-stamp, on rajoute :

# remove paravirt symbol
cd nv; \
$(LD) -m elf_i386 --defsym paravirt_ops=0x$(PARAVIRT_OPS) -r -o nvidia.ko nvidia.o nvidia.mod.o

On sauve, on quitte, et on lance la compilation :

# m-a -O -f build,install nvidia-kernel

L'option -O permet d'empêcher d'écraser nos modifications, et l'option -f de forcer la compilation et l'installation même si une autre version existe.

Et voilà ! Simple, non ? (ahem) Aux prochaines mises à jour, votre paquet linux-kbuild sera automatiquement écrasé par le paquet Debian officiel... C'est pas bien grave tant que vous n'avez pas besoin de recompiler un nouveau module nvidia, mais il ne faudra pas oublier cela lors de la prochaine mise à jour du module.