# Switching nv and  nvidia video driver at boot time [solved]

## Dominique_71

I have an SIS motherboard and an Nvidia graphic card. Audio apps are really important to me and I use a realtime kernel most of the time. 

When using the nvidia 3D driver, the system is still sharing an interrupt between the graphic card and a PCI device, that even when using the APIC interface. Realtime kernel are very sensitive with irq sharing, they don't like it and the system just hang sometime. It is why I use the nv driver with this realtime kernel, it use no irq, i get no shared irq and the system just work fast and rock solid.

But sometime I need to use 3D functionnalities and it is very slow with the nv driver.

So, is it possible to tell X at boot time which driver to use depending of the kernel in use?

Or better, tell the nvidia driver to not use a shared irq, but I have not figured out how it can be possible if it is possible.

EDIT: I solved the IRQ problem be adding acpi=off in grub. I get one more free IRQ and have been able with it to setup my hardware correctly. So I can use both drivers without problem now.Last edited by Dominique_71 on Tue Sep 05, 2006 12:30 pm; edited 2 times in total

----------

## Corona688

You can specify multiple ServerLayout's in your /etc/X11/xorg.conf file, then pass the name of which one you want as a paramater to startx ala -layout yournamehere.  Where this would be done in Gentoo, I'm not precisely sure.  I'm looking.

----------

## Corona688

OK, so that option isn't really too useful.   :Sad:   None of the startup scripts even use startx, and the startx that ships with gentoo doesn't appear to even understand -layout.

What I would do instead, would be to pass a kernel option like XDRIVER=nv or XDRIVER=nvidia in the bootloader.  The kernel, not understanding this option, will pass it as an environment variable to init.  Then, have a startup "service" under /etc/init.d that creates a symbolic link from /etc/X11/xorg-${XDRIVER}.conf to /etc/X11/xorg.conf.  You could even have it modprobe nvidia or not depending on what ${XDRIVER} is.  Make /etc/init.d/xdm depend on this new startup script, to guarantee it runs first.  That will let you choose which driver to use right in the bootloader.

----------

## Dominique_71

Thank you for the suggestion, I was thinking to use "uname -r" to do a test somewhere, but your solution is easier to implement and need no maintenance when uppgrading the kernel. And I have learned at I can pass environment variable to init with the bootloader.

I will try it and write about the result under. I have to wait to be abble to prove it because I am doing an "emerge -eav world" just now.

----------

## Dominique_71

Well, it was a long time ago. I have been very buzy.

First, it is neccesary to add the name of the environment variable in /etc/conf.d/env_whitelist, otherwise init will not accept the variable.

Here is my script:

```
#!/sbin/runscript

depend() {

        need bootmisc localmount

        after modules isapnp coldplug hotplug

        before xdm

}

start() {

        ebegin "Loading: ${X_DRIVER} X infrastructure"

       if [[ ${X_DRIVER} != "nv" && ${X_DRIVER} != "nvidia" ]] ; then

            eerror "We failed to switch to ${X_DRIVER}"

            return 1

        else

            if [[ ! -f /etc/X11/xorg.${X_DRIVER}.conf ]] ; then

                eerror "We failed to find /etc/X11/xorg.${X_DRIVER}.conf"

                return 1

            else

                rm /etc/X11/xorg.conf

                ln -s /etc/X11/xorg.${X_DRIVER}.conf /etc/X11/xorg.conf

                    if [[ ${X_DRIVER} == "nv" ]] ; then

                        if [[ $(eselect opengl show) == "nvidia" ]] ; then

                        eselect opengl set xorg-x11

                        fi

                    else

                        modprobe -q ${X_DRIVER} &>/dev/null

                        if [[ $(eselect opengl show) == "xorg-x11" ]] ; then

                            eselect opengl set nvidia

                        fi

                    fi

            fi

        fi

        eend $?

}

```

I have done 2 kernels, one with the nv driver and the other with the nvidia driver (they are incompatible). It is 2 configurations in grub, one with X_DRIVER=nv, the other with X_DRIVER=nvidia in the kernel line.

It must be 2 xorg config files: /etc/X11/xorg.nv.conf and /etc/X11/xorg.nvidia.conf. Any xorg.conf file will be erased and replaced by a symlink to one of the 2 xorg.n*.conf file.

I added a conditional test before eselect because it is very time consuming. I must take a look in how eselect work. It is maybe a config file that I can change or sed in order to get faster operation.

EDIT: I added a X_DRIVER test, otherwise a non valid symlink will be created.

EDIT 2: Added /etc/X11/xorg.${X_DRIVER}.conf test so at xorg.conf will not be erased by mistake.Last edited by Dominique_71 on Tue Sep 05, 2006 1:12 pm; edited 2 times in total

----------

## compimatiker

Another way is to do the following: (i did something similar to decide at boottime wheter to use xgl or not. To change only between nv and nvidia driver should be easier and doesnt need varios environments i think  :Wink:  )

this is the short version, if you need more detailed help, just tell me:

Add a parameter for your kernel commandline in grub.conf for example: videocard=nv

copy the whole section in grub conf and create a second bootentry with parameter: videocard=nvidia

write to different xorg.conf files - one uses nv driver and the other one nvidia: save them for example as xorg.conf.nv and xorg.conf.nvidia

write a runscript which looks for your kernelparameter which can be found after boot in /proc/cmdline and decides whetehr to create a symlink as xorg.conf to xorgs nv or nvidia version

Save the script under /etc/inid.d/ for example as: "xdm-setup" and make it executable

Add the script to your runlevels: rc-update add xdm-setup default ...

the script could be something like this

```

#!sbin/runscript

depend(){

     before xdm

}

start(){

     #maybe this can be done a bit better, im not yet very familar with shellscripts ,-)

     if grep -q nvidia /proc/cmdline; then

          ebegin "Setting XServer to nvidia..."

          cd /etc/X11/

          rm -f xorg.conf

          ln -s xorg.conf.nvidia xorg.conf

          eselect opengl set nvidia

     else

          ebegin "Setting XServer to nv..."

          cd /etc/X11/

          rm -f xorg.conf

          ln -s xorg.conf.nv xorg.conf

          eselect opengl set xorg-x11

     fi

     return 0

}

#restart and stop methods not necessary, maybe you can call start in restart again

```

i hope this will help you and fit your needs.

Of course you could make some improvements to check if nvidia or nv driver is already set via eselect like in the post above.

Edit: Im not sure if my dependencies are enough, so just take them from Dominique, he seems to be more experienced in shellscripting;-)

----------

## Dominique_71

Beside the test for eselect, the only difference is at you are using /proc when I pass directly the env var to init. Both are valide because I don't see who, with a nVidia card, would not use the proc system.

But one more test must be added, because this script will get confused if X_DRIVER is not nv or nvidia. It will just make an invalid symlink in this case. 

EDIT: Test done.

EDIT2: It is still a case of possible failure: when xorg.nv.conf or xorg.nvidia.conf don't exist. Be awareLast edited by Dominique_71 on Tue Sep 05, 2006 9:36 am; edited 1 time in total

----------

## Dominique_71

I have done a Tip in the wiki: Swithing between the nv free driver and the 3D nVidia driver

----------

## Dominique_71

Added the /etc/X11/xorg.${X_DRIVER}.conf test, so xorg.conf will not be erased by mistake and this script is safe to use.

----------

## mikegpitt

Interesting stuff...  I didn't realize that you could pass on env variables though the kernel parameters.

----------

