Thursday, June 01, 2006

Nvidia driver hack for Xen kernel - SUSE 10.1

I've been wrestling with Xen for a week or so now but before I post some articles about Xen itself I'd like to share this quick hack to get the Nvidia binary driver working with the SUSE 10.1 Xen kernel.

While the 'nv' driver is excellent it's nice to have all the features of my hardware available, even if unfortunately it means using a blob driver from Nvidia. Also the nv driver doesn't seem to probe my monitor using EDID and seems to use more generic modes. This means that while overall image quality is excellent, the DPI is wrong for my hardware and so I have to tweak font sizes and such things. It may be possible to fix this by using custom modelines in my xorg.conf, or to force the nv to probe my screen using EDID but for that amount of effort I may as well get the Nvidia driver working.

Anyway, here's the hack to get the latest Nvidia driver ( 8762 as I write this ) working with the Xen kernel. It should work for x86_64 also but I only tested it for x86. Props to JaXXon on the nvnews.net forums for the original FC patch.


Instructions
Run this shell script as root from the same location as the Nvidia driver package.

#!/bin/bash
# Quick n' dirty nvidia hack for kernel-xen
# REF: http://www.nvnews.net/vbulletin/showthread.php?t=68648
# Tested for kernel-xen 2.6.16.13-4 ( SUSE 10.1 - x86 ) using nvidia 1.0-8762
# cenuij@gmail.com

REQUIRED_PACKAGES="kernel-source kernel-xen gcc make glibc-devel module-init-tools gzip wget binutils"
KERNEL_XEN_VERSION=`uname -r`
SYMBOL_MAP="/boot/System.map-$KERNEL_XEN_VERSION"
NV_VERSION="8762"
SYSTEM_ARCH=`uname -m`

function error_die {
echo -e "ERROR: $*" >&2;
exit 1;
}

# Check for root, architecture and runlevel
[ "$UID" = "0" ] || error_die "Please run this script as root"
ps -C X &>/dev/null && die "Your X server is currently running, please run this script from runlevel 3"
case $(uname -m) in
x86_64) NV_ARCH=x86_64 ;;
i?86) NV_ARCH=x86 ;;
*) error_die "Architecture not supported: $SYSTEM_ARCH"
esac

# Check user has basic packages installed
echo -n "Checking installed packages"
missing=""
for package in $REQUIRED_PACKAGES; do
rpm -q "$package" &>/dev/null || missing="$missing $package"
echo -n "."
done
if [ -n "$missing" ]; then
echo -e "ERROR:\nThe following package(s) is/are missing:" >&2
for m in $missing; do
echo " $m" >&2
done
echo >&2
echo "Please install these packages then run this script again" >&2
exit 1
fi

# Extract the driver package, assuming it exists
./NVIDIA-Linux-$NV_ARCH-1.0-$NV_VERSION-pkg1.run --extract-only --target /tmp/NV-$NV_VERSION || error_die "Failed to extract the driver package NVIDIA-Linux-$NV_ARCH-1.0-$NV_VERSION-pkg1.run, please check this file exists and try again"

# Fetch the patch and apply
echo -e "Retrieving nvidia patch..."
wget "http://www.nvnews.net/vbulletin/attachment.php?attachmentid=17583&d=1145325458" &>/dev/null || error_die "Failed to download the nvidia driver patch"
mv "attachment.php?attachmentid=17583&d=1145325458" /tmp/NV-$NV_VERSION/patch-nv-8762.diff
cd /tmp/NV-$NV_VERSION/usr/src/nv
patch -p1 < /tmp/NV-$NV_VERSION/patch-nv-8762.diff

# Build precompiled module
make nv-linux.o mkprecompiled --interface=nv-linux.o --output=nv-linux.o-1.0-$NV_VERSION.suse-10.1-$KERNEL_XEN_VERSION \
--description="Quick n dirty for kernel-xen" \
--proc-version="`cat /proc/version`" \
--major=1 --minor=0 --patch=$NV_VERSION
mv nv-linux.o-1.0-$NV_VERSION.suse-10.1-$KERNEL_XEN_VERSION precompiled/

# Insert missing symbols
for sym in xen_tlb_flush force_evtchn_callback xen_features; do
export $sym=$(egrep " $sym\$" $SYMBOL_MAP | colrm 9)
done
ld -m elf_i386 --defsym xen_tlb_flush=0x$xen_tlb_flush \
--defsym force_evtchn_callback=0x$force_evtchn_callback \
--defsym xen_features=0x$xen_features \
-r -o nvidia.ko nvidia.o nvidia.mod.o

# Install other required NVIDIA binaries
echo "Installing NVIDIA driver support binaries"
cd /tmp/NV-$NV_VERSION
./nvidia-installer --silent --no-kernel-module

# Install and load the module
cp usr/src/nv/nvidia.ko "/lib/modules/$KERNEL_XEN_VERSION/kernel/drivers/video"
depmod -a $KERNEL_XEN_VERSION
echo "Installing NVIDIA driver kernel module"
modprobe nvidia || die "ERROR: Failed to load the NVIDIA kernel module"
rm -Rf /tmp/NV-$NV_VERSION
switch2nvidia
echo "Success!"

Additional Help

Additional help for SUSE Linux 10.1 can be found on the mailing lists or alternatively you can drop by the IRC chat channel #suse on freenode IRC network. If you are using KDE in SUSE Linux 10.1 then the IRC chat client Konversation is already configured to connect to the #suse channel on freenode IRC network.

14 comments:

Anonymous said...

To run this script, what kernel must be running, "normal" or "xen"?

Excuse my poor english. Thanks.

Anonymous said...

First, many thanks for this work.

Second, it doesn't seem to work on x86_64 (SMP, I didn't try it UP).

Here's a few issues with the script:

A few of the die lines should be error_die.

There should be a line break between the
make nv-linux.o and the mkprecompiled ... lines

mv into the precompiled/ directory won't work - it doesn't exist. Not that this seems to do anything.

ld -m elf_i386 ... is i386 specific, needs to be elf_x86_64 for x86_64.

Unfortunately, even with all of those corrected, I end up with a module that loads into the kernel, but pagefaults (and prevents further use of the console) as soon as you try to start X. It fails in an open call right at the start.

Anonymous said...

Further to the last message. The problem is that rmcols 9 is too short for x86_64, it should be rmcols 17. I've posted a new version of this at nvnews. It now works for me. YMMV

Anonymous said...

Genius - I had dual head setup running on my GeForce 5200 until Xen came along and then it was a choice of one or the other. Thanks to your post and a couple of tweaks to the script as posted ;-) I'm now looking at dual head displays under Xen.
Great blog - keep it up!

Anonymous said...

Thanks fof the tips. I had some fonts problem with the open source nv drivers I used with Xen, I had to switch to the nvidia module, your tip showed me the way ! ( Although I had to make every step by hand, as the script seems a bit buggy )

Hiney said...

I needed to join all the lines that end with a \ as they didn't appear to work properly otherwise, but things still seg faulted (and i don't have 64 bit suse).

so i'm at a loss. tried changing the line with rmcol 9 to 17 also and then the machine just hung during the script at the inserting module.

Skin Care said...
This comment has been removed by a blog administrator.
Anonymous said...

Who knows where to download XRumer 5.0 Palladium?
Help, please. All recommend this program to effectively advertise on the Internet, this is the best program!

College Term Papers said...

Great info, i glad to see this blog, such an informative article, Thanks for share this.

alina said...

Barrister Global Services Scam

Lindasy Rosenwald said...

Nice blogging, My review is very good example.
Lindsay Rosenwald http://www.lindsayrosenwald.info/ Dr. Lindsay Rosenwald is one of the re-known venture capitalists and the hedge fund managers in the world.

John said...

Nice Blogging,
UTAH : Utah Web Design http://www.adaptivitypro.com/utah-web-design/

John said...

Very good blogging,
Utah SEO http://www.adaptivitypro.com/utah-web-design/

David said...

Buck Reed Achievements and his vision and success http://www.buckreed.org/buckreedvision.html