Fedora 10 Dual Head Graphics Card

This post details how to install and configure two monitors on a single EVGA GeForce 9500 GT graphics (video) card under Fedora 10.

When I was researching dual head graphics cards for use with Fedora, I came across a lot of forum and blog entries on the subject but most of them contained obsolete or incorrect information - especially about TwinView, Xinerama and the X Window System configuration file. Hopefully this post will provide readers with some useful up-to-date information on the subject.

This particular graphics card (EVGA P/N 01G-P3-N959-TR) was of interest to me for a number of reasons but primarly because the card contains two heads each with DVI-I connectors which would allow me to move away from VGA cabling altogether since my two HP w1907 19" LCD monitors also have DVI-I connectors. In addition two heads on one graphics card enabled me to free up a PCI slot by eliminating the need for a second graphics card in my workstation.

Using TwinView was also of interest to me because it uses a single X screen, i.e. the driver conceals all information about the two separate monitors from the X server, and both monitors share the same frame buffer. This means that I can continue to use functionality such as accelerated OpenGL without a problem.

There are many graphics cards available which contain the nVidia 9500GT GPU but, to date, few of these cards come with dual DVI-I heads. In addition nVidia fully supports their graphics cards on GNU/Linux and Solaris platforms. Another feature of modern nVidia GPUs which is of great interest to me is their support for the CUDA (Compute Unified Device Architecture) architecture which I wish to experiment with a part of a project which I am currently working on for a customer.

You can use a single monitor with this card out-of-the-box using the default nv driver which comes standard with Fedora. However, to use two monitors with this card, you need to download and install the correct package for your specific kernel, i.e.
kmod-nvidia-2.6.27.19-170.2.35.fc10.x86_64-180.29-1.fc10.1.x86_64

in my particular case as my present kernel is 2.6.27.19-170.2.35. Selecting this package will cause three other packages to be also downloaded and installed on your system unless they already exist. These packages are livna-config-display-*, xorg-x11-drv-nvidia-*, and xorg-x11-drv-nvidia-libs-*.

These packages not not available in the regular Fedora repositories. You need to add the rpmfusion repositories to /etc/yum.conf or to the /etc/yum.repos.d subdirectory. Here is one way of installed the repository configuration files into /etc/yum.repos.d.
rpm -ivh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm
rpm -ivh http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-*
Before you actually download these packages, make a copy of your X Server configuration file i.e. /etc/X11/xorg.conf if one exists. On Fedora 10, it may not if you have a very simple setup. Don't say that you were not warned!

You then should reboot your system and use the nVidia configuration utility either from the command line (/usr/bin/nvidia-settings) or via the /Applications/System Tools/nVidia Display Settings menu option to configure the dual monitor setup.

The following is a screenshot of the nVidia configuration utility after invocation.
and here is a screenshot of the utility showing the X Server display Configuration panel.


There are limits to how you can configure your setup. You can have only one virtual screen per graphics card. Thus zaphod mode, i.e. the ability to assign each monitor on a device to a different screen, is not supported nor can you combine monitors from multiple graphic cards into a single screen.

Unless you modify your X Server configuration file all settings will be lost upon the next reboot or restart of the X Server. For this reason the utility has options to create a new X Server configuration file (in my case /etc/X11/xorg.conf) or to merge with your existing configuration file.

For completeness, here is a copy of the /etc/X11/xorg.conf which I currently use with this configuration.
#
# FPMurphy 3/28/2009 Twinview EVGA 9500 GT
#

Section "ServerLayout"
Identifier "Layout0"
Screen 0 "Screen0" 0 0
InputDevice "Keyboard0" "CoreKeyboard"
InputDevice "Mouse0" "CorePointer"
EndSection

Section "Files"
FontPath "/usr/share/fonts/default/Type1"
ModulePath "/usr/lib64/xorg/modules/extensions/nvidia"
ModulePath "/usr/lib64/xorg/modules"

EndSection

Section "Module"
Load "dbe"
Load "extmod"
Load "type1"
Load "freetype"
Load "glx"
EndSection

Section "ServerFlags"
Option "Xinerama" "0"
EndSection

Section "InputDevice"
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/input/mice"
Option "ZAxisMapping" "4 5 6 7"
EndSection

Section "InputDevice"
Identifier "Keyboard0"
Driver "kbd"
Option "XkbLayout" "us"
Option "XkbModel" "pc105"
EndSection

Section "Monitor"
Identifier "Monitor0"
VendorName "HP"
ModelName "w1907"
HorizSync 24.0 - 83.0
VertRefresh 50.0 - 76.0
Option "DPMS"
EndSection

Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "GeForce 9500 GT"
EndSection

Section "Screen"
Identifier "Screen0"
Device "Device0"
Monitor "Monitor0"
DefaultDepth 24
Option "TwinView" "1"
Option "TwinViewXineramaInfoOrder" "DFP-1"
Option "metamodes" "DFP-0: nvidia-auto-select +1440+0, DFP-1: nvidia-auto-select +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
If the nVidia GLX module loaded correctly, you should able to run /usr/bin/glxgears successfully. If it fails to run, check your /var/log/Xorg.O.log file to see if the nVidia libglx library is being loaded or not. You should see something like the following
(II) Loading /usr/lib64/xorg/modules/extensions/nvidia//libglx.so
(II) Module glx: vendor="NVIDIA Corporation"
compiled for 4.0.2, module version = 1.0.0
Module class: X.Org Server Extension
(II) NVIDIA GLX Module 173.14.18 Mon Mar 2 15:55:02 PST 2009
(II) Loading extension GLX
If you do not see that specific path for the nVidia libglx.so you need to go back and fix up the ModulePath lines in your xorg.conf. Note that the order of the ModulePath lines is important as each path is searched in turn from first to last.

With this configuration the output from the xrandr utility should be something to this:
#xrandr -q
Screen 0: minimum 2880 x 900, current 2880 x 900, maximum 2880 x 900
default connected 2880x900+0+0 0mm x 0mm
2880x900 50.0*
#
If you are unfamiliar with xrandr which is the command line interface to the X Server RandR extension, I recommend that you become familar with it as it is one of the more useful extensions in the X Window System when you have more than one head on a graphics card.

The following is a list of the nvidia-related kernel modules.
# modprobe -l | grep nvidia
/lib/modules/2.6.27.19-170.2.35.fc10.x86_64/extra/nvidia/nvidia.ko
/lib/modules/2.6.27.19-170.2.35.fc10.x86_64/kernel/drivers/video/nvidia/nvidiafb.ko
/lib/modules/2.6.27.19-170.2.35.fc10.x86_64/kernel/drivers/video/backlight/mbp_nvidia_bl.ko
# lsmod | grep nv
nvidia 8117992 20
i2c_core 29216 2 nvidia,i2c_i801
#
One thing to watch out for is the nvidia system service can change your /etc/X11/xorg.conf file without informing you. To eliminate this possibility, I strongly recommend that you turn the service off.
# chkconfig --list  nvidia
nvidia 0:off 1:off 2:on 3:on 4:on 5:on 6:off
# chkconfig nvidia off
#
Note that these instructions may not apply to Fedora 11 (aka Leonidas) as it is getting a new default driver for nVidia grahics chipsets called nouveau. The nv driver will still be installed by default and will be used as a fall-back where nouveau fails to work for whatever reason.

Because the nVidia kernel module is built specifically for each kernel release, you need to download and install a new nVidia kernel module each time your kernel is updated.  If you suddenly are confronted with a non-responsive blank screen after a reboot, this is probably what has happened.  The easiest fix in this case is to log in to one of the virtual consoles, downgrade the system to runlevel 2, remove the old kmod-nvidia-173* package, and install the new kmod-nvidia-173* package followed by a reboot.

[ Updated Apr 28 2009] Alternatively you can let your system always automatically download and install the latest nVidia kernel module whenever a new kernel is downloaded by simply installing a meta-package called kmod-nvidia-173xx-173.14.18-1.fc10.1.x86_64 instead of the kernel specific package.



Here is the relevant portion of /var/log/yum.log which shows the packages which were installed as a result of installing this meta-package
Apr 23 15:36:59 Installed: system-config-display-1.1.1-1.fc10.noarch
Apr 23 15:36:59 Installed: livna-config-display-0.0.22-1.fc10.noarch
Apr 23 15:37:00 Installed: xorg-x11-drv-nvidia-173xx-libs-173.14.18-1.fc10.x86_64
Apr 23 15:37:06 Installed: xorg-x11-drv-nvidia-173xx-173.14.18-1.fc10.x86_64
Apr 23 15:37:09 Installed: kmod-nvidia-173xx-2.6.27.21-170.2.56.fc10.x86_64-173.14.18-1.fc10.1.x86_64
Apr 23 15:37:09 Installed: kmod-nvidia-173xx-173.14.18-1.fc10.1.x86_64
As usual, I hope that this information has been of help to you. If you are a software developer, I strongly encourage you to upgrade to a dual head system as studies have consistently shown that your productivity can increase by as much as 20% with such a configuration.

Bootable DVD/CDROM

Have you ever wanted to determine whether a DVD or CDROM is a bootable CDROM or DVD from within a shell script?  If you use GNU/Linux you could parse the output from the isoinfo utility which is part of the CDRecord tools suite.

What if the isoinfo utility is not available on your operating system?  In this case you have to resort to rolling you own compiled langauge utility or shell script.  To do this you need to understand where to find the specific bytes on a CDROM/DVD which indicate whether it is a bootable CDROM/DVD or not.  The relevant specification covering bootable CDROMs (and by extension bootable DVDs) is the El Torito specification which is an extension to the ISO 9660 specification.

Our first shell script uses the dd utility to read in the required bytes which are then sliced and diced using the xxd and cut utilities..  Sector 17 (hexadecimal 11, the Boot Record Volume) contains two bytes at a specific offset which are an absolute pointer to the Booting Catalog which in turn contains a specific byte which indicates whether a CDROM/DVD is bootable or not.
#!/bin/bash
#
# use dd to read in the required bytes
#

DEVICE="/dev/sr0"
VERBOSE=1

# get 2 bytes at absolute offset 34887
bchex=`dd if=${DEVICE} skip=$(( 0x800 * 0x11 + 0x47)) bs=1 count=2 conv=swab 2>/dev/null | xxd | cut -d" " -f2`

# get one byte
bcdec=`printf "%d" 0x${bchex}`
bootable=`dd if=${DEVICE} bs=1 skip=$(( 0x800 * bcdec + 0x20)) count=1 2>/dev/null | xxd | cut -d" " -f2`

if [[ $bootable = 88 ]]; then
[ $VERBOSE ] && printf "Bootable CDROM\n"
exit 0
else
[ $VERBOSE ] && printf "Not a bootable CDROM\n"
exit 1
fi
The previous shell script is classical in its approach to the problem in that it uses a number of small specialized utilities to achieve the desired result.

Another way of achieving the same result is to use the extended I/O features of ksh93 as shown in the following shell script.
#!/bin/ksh93
#
# Cannot open DVD/CDROM for read/write - hence cannot seek
# forward on file descriptor. Workaround is to close and
# reopen the file descriptor.
#

DEVICE="/dev/sr0"
VERBOSE=1

# read 2 bytes
redirect 3< $DEVICE || exit 3
3<#(( 0x800 * 0x11 + 0x47 ))
read -u3 -N 1 bchex1
read -u3 -N 1 bchex2
redirect 3<&-

# calculate absolute offset
integer bcdec=$(printf "%d" 0x$(printf "%x%x\n" "'$bchex2" "'$bchex1"))

# read 1 byte
redirect 3< $DEVICE || exit 3
3<#(( 0x800 * bcdec + 0x20 ))
read -u3 -N 1 bootable
redirect 3<&-

if [[ $(printf "%x" "'$bootable") = 88 ]]; then
[ $VERBOSE ] && printf "Bootable CDROM\n"
exit 0
else
[ $VERBOSE ] && printf "Not a bootable CDROM\n"
exit 1
fi
The advantage of this approach is that all operations are done within the existing shell process without the overhead of fork/execs to invoke external utilities such as dd etc.

Note that both of the above shell scripts assume that the CDROM or DVD being checked is either non-bootable or contains a single boot-image configuration.  They can easily be extended to check for a multiple boot-image configuration.  That is left as an exercise for you the reader.

For the record, these two shell scripts were tested on Fedora 10 using version M of ksh93.