View previous topic :: View next topic |
Author |
Message |
netfab Veteran
Joined: 03 Mar 2005 Posts: 1896 Location: 127.0.0.1
|
Posted: Thu Jan 27, 2011 12:06 pm Post subject: [script init] choix pilote nvidia/nouveau à chaque boot |
|
|
À l'origine cette astuce découle du sujet suivant : [nvidia] le nouveaux choix du libre.
Historique :
- 05/03/2013 : réécriture complète de la technique et du script d'initialisation, permettant ainsi de n'utiliser (et de maintenir) qu'un seul kernel avec des paramètres différents, merci à GentooUser@Clubic plus loin dans le topic pour l'inspiration.
Choix entre nouveau/KMS ou nvidia/uvesafb à chaque boot
J'utilise grub2. Le framebuffer uvesafb est activé si le pilote nvidia est choisi, sinon il est désactivé avec le pilote nouveau.
Si vous préférez utiliser vesafb (qui doit être compatible avec KMS), voyez le post de GentooUser@Clubic plus bas. Je n'ai pas encore essayé avec, j'essaierai à l'occasion et mettrai à jour cette astuce si besoin.
Configuration kernel :
Tout ce qui suit se fait avec un kernel relativement récent configuré de la manière suivante :
Code: |
Device Drivers --->
Graphics support --->
<*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) --->
<*> Nouveau (nVidia) cards
<*> Support for frame buffer devices --->
-*- Enable Video Mode Handling Helpers
<*> Userspace VESA VGA graphics support
|
Au moment de la compilation du kernel il est possible que vous ayez ces avertissements (c'est le cas avec un kernel vanilla-3.4.34) :
Quote: |
warning: (DRM_NOUVEAU) selects ACPI_WMI which has unmet direct dependencies (X86 && X86_PLATFORM_DEVICES && ACPI)
warning: (DRM_NOUVEAU) selects MXM_WMI which has unmet direct dependencies (X86 && X86_PLATFORM_DEVICES && ACPI_WMI)
|
Petit problème de dépendance du pilote nouveau, à rectifier en activant cette option :
Code: |
Device Drivers --->
[*] X86 Platform Specific Device Drivers --->
|
Configuration Xorg :
Pour xorg je crée deux fichiers de configuration indépendants. Lors de l'éxécution du script d'initialisation, je crée un lien symbolique vers l'un de ces fichiers dans le répertoire xorg.conf.d.
Code: |
$ ls -l /etc/X11 | grep xorg
-rw-r--r-- 1 root root 235 23 janv. 14:53 xorg-nouveau.conf
-rw-r--r-- 1 root root 322 25 janv. 18:51 xorg-nvidia.conf
drwxr-xr-x 2 root root 4096 25 janv. 23:52 xorg.conf.d
|
Dans le fichier xorg-nvidia.conf, en plus de ma configuration habituelle pour le driver propriétaire, j'ai ceci, afin d'éviter le chargement automatique du driver nouveau :
Code: |
Section "Module"
Disable "nouveau"
EndSection
|
Le fichier xorg-nouveau.conf contient quant à lui :
Code: |
Section "Module"
Disable "nvidia"
EndSection
Section "Device"
Identifier "Card0"
Driver "nouveau"
EndSection
|
Script d'initialisation :
À modifier selon vos besoins (xvmc par exemple) et à lancer au runlevel default :
Code: |
#!/sbin/runscript
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
depend() {
need localmount
before xdm
}
_switch_to() {
local DRIVER=$1 OPENGL=${2:-$1}
ebegin "Setting up X environment for ${DRIVER} driver"
ln -snf /etc/X11/xorg-${DRIVER}.conf /etc/X11/xorg.conf.d/99-videocard.conf
eend $? || return 1
if [ ! ${OPENGL} = `eselect opengl show` ]; then
ebegin "Switching to ${OPENGL} OpenGL implementation"
eselect opengl set "${OPENGL}" >/dev/null 2>&1
eend $? "Failed to set ${OPENGL} OpenGL interface" || return 1
fi
return 0
}
_switch_to_nvidia() {
_switch_to nvidia
exit $?
}
_switch_to_nouveau() {
_switch_to nouveau xorg-x11
exit $?
}
start() {
for i in `cat /proc/cmdline` ; do
case $i in
nouveau|nvidia) eval _switch_to_$i ;;
esac
done
# default driver if nothing found on kernel command line
local default=nvidia
einfo "No X driver asked on kernel command line. Using default : $default"
eval _switch_to_$default
}
|
Configuration de grub2 :
Dans la configuration de grub2, je choisis d'activer par défaut nvidia/uvesafb.
Dans le menu de grub, j'ajoute ensuite une entrée supplémentaire avec des paramètres kernel différents pour désactiver uvesafb et activer nouveau.
Dans /etc/default/grub, j'ajoute à la variable GRUB_CMDLINE_LINUX_DEFAULT les paramètres suivants :
Code: | nomodeset nvidia video=uvesafb:mtrr:3,ywrap,1680x1050-32@60 |
Ainsi, tous les kernels détectés par grub2 booteront avec ces paramètres.
Ensuite je génère la configuration de grub2 :
Code: |
# grub2-mkconfig -o /boot/grub2/grub.cfg
|
Enfin, depuis le fichier de configuration de grub fraîchement généré, je copie la première entrée du menu, qui ressemble à ceci (environ une quinzaine de lignes, dépend de votre configuration grub) :
Code: |
menuentry 'Gentoo GNU/Linux' --class gentoo --class gnu-linux [...] {
[...]
echo 'Chargement de Linux 3.4.34…'
linux /boot/kernel-3.4.34 [...] nomodeset nvidia video=uvesafb:mtrr:3,ywrap,1680x1050-32@60 [...]
[...]
}
|
Je colle donc cette entrée dans le fichier /etc/grub.d/40_custom en modifiant le nom de l'entrée et les paramètres kernel pour désactiver uvesafb et utiliser nouveau :
Code: |
menuentry 'Gentoo GNU/Linux -- nouveau' --class gentoo --class gnu-linux [...] {
[...]
echo 'Chargement de Linux 3.4.34…'
linux /boot/kernel-3.4.34 [...] video=uvesafb:off nouveau [...]
[...]
}
|
Et je régénère la configuration de grub2 pour prendre en compte l'entrée du menu pour nouveau.
Code: |
# grub2-mkconfig -o /boot/grub2/grub.cfg
|
Last edited by netfab on Tue Mar 05, 2013 3:32 pm; edited 4 times in total |
|
Back to top |
|
|
Leander256 l33t
Joined: 05 Jul 2003 Posts: 910 Location: Singapour
|
Posted: Sun Jan 30, 2011 10:05 pm Post subject: |
|
|
Merci beaucoup pour cette astuce (que j'ai mise en oeuvre chez moi), je trouve ceci dit un peu dommage de devoir créer 2 runlevels qu'il va falloir garder synchrones avec default. Du coup je me demande si il ne serait pas plus pratique de compiler le noyau avec l'option pour stocker son fichier config dans /proc/config.gz, puis de faire simplement un grep dans le script (qui serait donc dans default) pour déterminer de quel type de noyau il s'agit. |
|
Back to top |
|
|
netfab Veteran
Joined: 03 Mar 2005 Posts: 1896 Location: 127.0.0.1
|
Posted: Mon Jan 31, 2011 9:01 am Post subject: |
|
|
Alors là, je dois avouer que je n'avais pas pensé une seule seconde à greper la configuration du kernel, j'etais parti directement sur l'option des runlevels, et je dois dire que cela me gênait un peu aussi. J'ai modifié le script et le post original, effectivement çà simplifie tout, merci |
|
Back to top |
|
|
Leander256 l33t
Joined: 05 Jul 2003 Posts: 910 Location: Singapour
|
Posted: Tue Feb 01, 2011 5:45 pm Post subject: |
|
|
Merci pour la modif, j'ai fait les changements sur mon système mais je n'ai pas encore redémarré l'ordi (puisqu'il a arrêté de planter maintenant que je suis repassé au pilote nvidia ). |
|
Back to top |
|
|
mazes80 n00b
Joined: 24 Feb 2011 Posts: 13 Location: toulouse - france
|
Posted: Tue May 10, 2011 4:40 pm Post subject: |
|
|
Peut être faudrait-il aussi fixer l'implémentation de xvmc (si utilisé):
Code: | eval eselect xvmc "${impl}" |
Une alternative au zgrep sur /proc/config.gz peut être utilisé grâce à CONFIG_LOCALVERSION
On peut ainsi récupérer l'implémentation à utiliser avec:
Code: | uname -r | sed 's/^.*_//' |
Après à chacun d'adapter ce script en fonction de ses besoins et de ses préférences.
Merci pour l'idée.
P.S.: quel est l'intérêt de l'utilisation systématique de eval ? |
|
Back to top |
|
|
netfab Veteran
Joined: 03 Mar 2005 Posts: 1896 Location: 127.0.0.1
|
Posted: Mon May 16, 2011 7:38 am Post subject: |
|
|
Oui, chacun peut adapter en fonction de ses préférences, j'essaierai avec CONFIG_LOCALVERSION dès que j'aurai 2 minutes.
J'ai ajouté l'eselect pour XvMC, merci.
Quote: | P.S.: quel est l'intérêt de l'utilisation systématique de eval ? |
Simple question d'habitude, je t'avouerai que je n'avais même pas remarqué. |
|
Back to top |
|
|
GentooUser@Clubic l33t
Joined: 01 Nov 2004 Posts: 829
|
Posted: Sun Oct 09, 2011 12:58 am Post subject: |
|
|
Up pour dire merci pour ce script
Par contre je sait pas si c'est chez moi mais je trouve "eselect opengl set xxx" est assez lent à rendre la main :
Quote: |
eselect opengl set nvidia 0,40s user 0,12s system 51% cpu 0,997 total
eselect opengl set xorg-x11 0,44s user 0,07s system 52% cpu 0,982 total
|
J'ai donc un peu modifié le script pour rajouter un test et n’exécuter la commande que si c’est nécessaire :
Code: |
if [ ! "$(eselect opengl show)" = "${impl}" ]; then
ebegin "Switching to ${impl} OpenGL implementation"
eval eselect opengl set "${impl}" >/dev/null 2>&1
eend $? "Failed to set ${impl} OpenGL interface" || return 1
fi
|
Si aucun changement n'est nécessaire, c'est tout benef :
Quote: | eselect opengl show 0,01s user 0,01s system 42% cpu 0,032 total |
|
|
Back to top |
|
|
GentooUser@Clubic l33t
Joined: 01 Nov 2004 Posts: 829
|
Posted: Sat Mar 02, 2013 11:04 pm Post subject: |
|
|
Bon si ça intéresse toujours du monde y'a une nouvelle recette maintenant, avec un seul noyau
- Activez nouveau dans le noyau, en dur ou module suivant votre préférence (perso je préfère en dur, pour profiter de la console hd le plus tôt possible)
- Activez vesafb dans le noyau, si vous voulez profiter du framebuffer avec les drivers nvidia (pas uvesafb, j'ai pas testé mais c’est marqué incompatible) et de toute façon :
Quote: |
You may have read people use uvesafb over vesafb, as it had better performance. This WAS generally true, but not in a modern distro with modern Hardware. If your Graphics Hardware supports protected mode VESA (VESA >= 2.0 ), and you have a somewhat recent kernel vesafb is now a better choice.
|
- Bien sûr installez les drivers nvidia et nouveau, mais ça vous savez le faire
- Pour booter avec nouveau rien à faire : voici ma ligne de commande grub : Code: |
# (0) Gentoo Linux (vmlinuz-3.8.1) (nouveau driver)
menuentry "Gentoo Linux (vmlinuz-3.8.1) (nouveau driver)" {
linux /vmlinuz-3.8.1 root=UUID=6540fc3c-d0cf-4301-b5c5-e4e8cfb20700 rootfstype=ext4 quiet splash nouveau init=/bin/systemd
initrd /initramfs-generic.img
}
|
- Pour booter avec nvidia rajoutez nomodeset à la ligne de commande (ça désactivera nouveau) et si vous voulez vesafb, utilisez set gfxpayload=<resolution> dans grub2 (vga=xxx n'est plus supporté) ou référez vous à la documentation de votre bootloader.
Code: |
# (1) Gentoo Linux (vmlinuz-3.8.1) (nvidia-driver)
menuentry "Gentoo Linux (vmlinuz-3.8.1) (nvidia-driver)" {
set gfxpayload=1920x1200-32
linux /vmlinuz-3.8.1 root=UUID=6540fc3c-d0cf-4301-b5c5-e4e8cfb20700 rootfstype=ext4 quiet splash nomodeset nvidia init=/bin/systemd
initrd /initramfs-generic.img
}
|
Bon comme nouveau est activé même dans le noyau nvidia les scripts qu'on trouves plus haut dans ce topic ne marchent plus, j'en ai fait un nouveau qui cherche "nvidia" ou "nouveau" dans la ligne de commande du noyau et active l’implémentation correspondante :
Code: |
#!/bin/sh
set_x11_drv() {
local _drv=$1
ln -snf ../xorg-${_drv}.conf /etc/X11/xorg.conf.d/99-device.conf
}
set_gl_impl() {
local _impl=$1
local _curr=`eselect opengl show`
[ ! $_curr = $_impl ] && eselect opengl set $_impl >/dev/null 2>&1
}
x11_drv="nouveau"
gl_impl="xorg-x11"
found=0
for i in `cat /proc/cmdline` ; do
case $i in
nouveau)
x11_drv="nouveau"
gl_impl="xorg-x11"
found=1
;;
nvidia)
x11_drv="nvidia"
gl_impl="nvidia"
found=1
;;
esac
done
[ $found -eq 0 ] && echo "no driver specified in kernel cmdline, using default"
echo "configure system to use $x11_drv driver"
set_x11_drv $x11_drv
set_gl_impl $gl_impl
exit 0
|
Bon par contre c'est pas un rc-script faudra donc en ajouter un (ou un service systemd) pour l’exécuter à chaque boot.
Il faut toujours un /etc/X11/xorg-nouveau.conf et un /etc/X11/xorg-nvidia.conf (voir premier post du topic)
Aussi je change pas l’implémentation d'OpenCL ou vdpau pour des raisons de temps de démarrage, mais vous pouvez le rajouter.
J'ai fait une version C (pour gagner 0,01s à chaque boot ), ça compile avec gcc -std=gnu99 -O3 -Wall
Code: |
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define SUCCESS 0
#define ERROR 1
int set_x11_drv(const char *drv)
{
const char fmt[] = "/etc/X11/xorg-%s.conf";
const char dst[] = "/etc/X11/xorg.conf.d/99-device.conf";
char src[sizeof(fmt) + strlen(drv) + 1];
snprintf(src, sizeof(src), fmt, drv);
/* first try to unlink dst if exist */
unlink(dst);
/* make new symlink */
printf("Symlink %s to %s\n", src, dst);
return symlink(src, dst);
}
int get_gl_impl(char *buffer, size_t size)
{
const char cmd[] = "eselect opengl show";
FILE *pipe = NULL;
pipe = popen(cmd, "r");
if(!pipe) {
fprintf(stderr, "ERROR: Failed to execute %s", cmd);
return ERROR;
}
if(!fgets(buffer, size, pipe)) {
pclose(pipe);
return ERROR;
}
/* remove new line */
buffer[strcspn(buffer, "\n")] = '\0';
return pclose(pipe);
}
int set_gl_impl(const char *impl)
{
const char fmt[] = "eselect opengl set %s &>/dev/null 2>&1";
char cmd[sizeof(fmt) + strlen(impl) + 1];
char curr[10];
get_gl_impl(curr, sizeof(curr));
/* switch implementation if needed */
if(strcmp(impl, curr) == 0 ){
return SUCCESS;
}
printf("Switch to %s OpenGL implementation\n", impl);
snprintf(cmd, sizeof(cmd), fmt, impl);
return system(cmd);
}
int main(int argc, char **argv)
{
char *x11_drv = "nouveau";
char *gl_impl = "xorg-x11";
FILE *fhandle = NULL;
char *fbuffer = NULL;
int rcode = 0;
int found = 0;
fhandle = fopen("/proc/cmdline", "r");
if(fhandle == NULL) {
perror("ERROR: Unable to open /proc/cmdline");
}
else {
while(fscanf(fhandle, "%ms", &fbuffer) == 1) {
if(strcmp(fbuffer, "nouveau") == 0) {
x11_drv = "nouveau";
gl_impl = "xorg-x11";
found = 1;
} else if(strcmp(fbuffer, "nvidia") == 0){
x11_drv = "nvidia";
gl_impl = "nvidia";
found = 1;
}
free(fbuffer);
}
fclose(fhandle);
}
if(found == 0) {
printf("No driver specified in kernel cmdline, using default\n");
}
printf("Configure system to use %s X11 video driver\n", x11_drv);
if(set_x11_drv(x11_drv) != SUCCESS) {
perror("ERROR: Unable to set X11 video driver");
rcode = 1;
}
if(set_gl_impl(gl_impl) != SUCCESS) {
fprintf(stderr, "ERROR: Unable to switch OpenGL implementation\n");
rcode = 1;
}
return rcode;
}
|
Perso je suis très soulagé de n'avoir, enfin, plus besoin de maintenir deux noyaux avec des options différentes (pour nouveau et nvidia) |
|
Back to top |
|
|
netfab Veteran
Joined: 03 Mar 2005 Posts: 1896 Location: 127.0.0.1
|
Posted: Sun Mar 03, 2013 12:03 pm Post subject: |
|
|
GentooUser@Clubic wrote: | Bon si ça intéresse toujours du monde y'a une nouvelle recette maintenant, avec un seul noyau
Perso je suis très soulagé de n'avoir, enfin, plus besoin de maintenir deux noyaux avec des options différentes (pour nouveau et nvidia) |
Je suis justement en train de concevoir une nouvelle procédure pour n'avoir qu'un seul noyau, je viens ici pour revoir un truc, et je découvre ton post
GentooUser@Clubic wrote: | - Activez vesafb dans le noyau, si vous voulez profiter du framebuffer avec les drivers nvidia (pas uvesafb, j'ai pas testé mais c’est marqué incompatible) |
J'utilise justement uvesafb, je vais voir pour faire avec
En revanche, ce que je cherche à faire, c'est de pouvoir switcher entre nvidia et nouveau sans avoir à rebooter. Je donnerai des nouvelles si j'y parviens. |
|
Back to top |
|
|
GentooUser@Clubic l33t
Joined: 01 Nov 2004 Posts: 829
|
Posted: Sun Mar 03, 2013 3:47 pm Post subject: |
|
|
uvesafb en dur en tout cas je vient de tester, ça marche pas, il se charge inconditionnellement et empêche nouveau de se lancer, même avec video=none. Après en module ça doit pouvoir être jouable avec modprobe.blacklist=.
Pour switcher juste en relançant X j'ai vu un tuto pour Ubuntu y'a quelques temps, faut compiler nouveau en module et jouer avec modprobe -r, perso je suis pas intéressé quitte à relancer X, avec systemd, kexec et un SSD autant relancer le système. |
|
Back to top |
|
|
netfab Veteran
Joined: 03 Mar 2005 Posts: 1896 Location: 127.0.0.1
|
Posted: Mon Mar 04, 2013 7:00 pm Post subject: |
|
|
GentooUser@Clubic wrote: | uvesafb en dur en tout cas je vient de tester, ça marche pas, il se charge inconditionnellement et empêche nouveau de se lancer, même avec video=none. Après en module ça doit pouvoir être jouable avec modprobe.blacklist=.
|
Le paramètre pour désactiver uvesafb sur la ligne de commande du kernel est le suivant : video=uvesafb:off
GentooUser@Clubic wrote: |
Pour switcher juste en relançant X j'ai vu un tuto pour Ubuntu y'a quelques temps, faut compiler nouveau en module et jouer avec modprobe -r |
Bon, j'ai effectué diverses expériences. J'arrive sans problème à passer de nouveau/kms à nvidia/uvesafb, mais lors de l'opération inverse, çà coince.
En fait, une fois que le pilote nvidia a été chargé puis déchargé, plus moyen de relancer nouveau, çà se termine invariablement par :
Code: |
nouveau: probe of 0000:01:00.0 failed with error -16
|
Et à partir de là, si j'essaie de persévérer en jouant à l'apprenti-sorcier, au bout d'un moment l'écran passe au noir (plus de signal) et les ventilos de la carte graphique se mettent à turbiner au max
Alors pour le moment je me contenterai d'un reboot pour passer de nvidia/uvesafb vers nouveau/kms et vice-versa: en m'inspirant de ta technique et de ton code ci-dessus, j'ai recompilé mon kernel avec les options adéquat et réécrit le service à lancer, çà fonctionne parfaitement, je posterai tout çà un peu plus tard et en profiterai pour éditer le premier post du topic. |
|
Back to top |
|
|
GentooUser@Clubic l33t
Joined: 01 Nov 2004 Posts: 829
|
Posted: Fri Mar 29, 2013 10:12 pm Post subject: |
|
|
netfab wrote: |
Le paramètre pour désactiver uvesafb sur la ligne de commande du kernel est le suivant : video=uvesafb:off
|
Merci ! Je suis passé de Grub à Syslinux et n'ayant pas trouver comment passer le "gfxpayload" au noyau avec Syslinux j'en suis revenu à uvesab. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|