Wednesday, July 14, 2010

How To Build the ATI Fglrx kernel modules for a new CentOS 5 kernel

RHEL5 / CentOS5 kernel update time can be troublesome with regards to workstation video cards.

Especially if you are dealing with 10's of 100's of workstations, a simple 'yum update' can result in a large number of support calls stating, "I rebooted my workstation, and now it reports that X can't start!"

Workstations with nVidia based cards can use the kmod RPMs provided by the ELRepo repository (is that redundant?).

Unfortunately, there aren't kmod RPMs for ATI Radeon cards (fglrx). Until I get around to rolling my own kmod RPM, here's the solution I use (I originally posted this script on this blog post):

  1. Many kernels ago, I had built an RPM using the ati-driver installation package and installed the RPM
  2. 
    $ sh ati-driver-installer-9-3-x86.x86_64.run --buildpkg RedHat/RHEL5_64a
    $ sudo rpm -Uvh fglrx64_7_1_0-8.593-1.x86_64.rpm
    
  3. Create a script that will build a new kernel module based on the currently loaded kernel: /root/fglrx_build_kernel_module.sh
  4. 
    #!/bin/sh
    # Builds updated kernel module (based on currently loaded kernel)
    # 
    # This driver was installed via RPM, built using:
    # sh ati-driver-installer-9-3-x86.x86_64.run --buildpkg RedHat/RHEL5_64a
    
    # fix the source code to work with CVE-2010-3081
    /usr/bin/perl -pi -e 's/return compat_alloc_user_space/return arch_compat_alloc_user_space/g;' /lib/modules/fglrx/build_mod/kcl_ioctl.c
    
    cd /lib/modules/fglrx/build_mod
    ./make.sh
    
    cd /lib/modules/fglrx
    ./make_install.sh
    
    echo "To complete the process you must 'init 3' and 'init 5'"
    echo "lsmod | grep fglrx"
    
  5. Update the kernel followed by a reboot and you'll notice that X fails to start and that the fglrx module is not loaded. Enter runlevel 3, and run the script
  6. 
    # lsmod | grep fglrx
    
    # init 3
    # sh ./fglrx_build_kernel_module.sh
    
    
    AMD kernel module generator version 2.1
    doing Makefile based build for kernel 2.6.x and higher
    rm -rf *.c *.h *.o *.ko *.GCC* .??* *.symvers
    make -C /lib/modules/2.6.18-194.8.1.el5/build SUBDIRS=/lib/modules/fglrx/build_mod/2.6.x modules
    make[1]: Entering directory `/usr/src/kernels/2.6.18-194.8.1.el5-x86_64'
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/firegl_public.o
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/kcl_acpi.o
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/kcl_agp.o
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/kcl_debug.o
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/kcl_ioctl.o
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/kcl_io.o
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/kcl_pci.o
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/kcl_str.o
      CC [M]  /lib/modules/fglrx/build_mod/2.6.x/kcl_wait.o
      LD [M]  /lib/modules/fglrx/build_mod/2.6.x/fglrx.o
      Building modules, stage 2.
      MODPOST
      CC      /lib/modules/fglrx/build_mod/2.6.x/fglrx.mod.o
      LD [M]  /lib/modules/fglrx/build_mod/2.6.x/fglrx.ko
    make[1]: Leaving directory `/usr/src/kernels/2.6.18-194.8.1.el5-x86_64'
    build succeeded with return value 0
    duplicating results into driver repository...
    done.
    You must change your working directory to /lib/modules/fglrx
    and then call ./make_install.sh in order to install the built module.
    - recreating module dependency list
    - trying a sample load of the kernel modules
    done.
    To complete the process you must 'init 3' and 'init 5'
    
  7. Once the script finishes, enter runlevel 5 and verify that the fglrx module is loaded
  8. 
    # init 5
    
    # lsmod | grep fglrx
    fglrx                2389736  3 
    

To Do: Rewrite the script to build the kernel module for whichever kernel you specify instead of only the currently loaded kernel. nVidia provides support for this, for example to build the module for the latest EL5 kernel:

# sh NVIDIA-Linux-x86_64-190.42-pkg2.run -a -K -k 2.6.18-194.8.1.el5

4 comments:

FlakRat said...

I performed these steps after updating workstations from CentOS 5.4 to CentOS 5.5.

Users reported that one particular application, Fieldview, kept hanging when launched.

After some troubleshooting, I found that building a new rpm, removing the old, and installing the new got things working:

# sh ati-driver-installer-9-3-x86.x86_64.run --buildpkg RedHat/RHEL5_64a

Copy the rpm to each workstation

# rpm -e fglrx64_7_1_0

# rpm -ivh fglrx64_7_1_0-8.593-1.x86_64.rpm

I guess you could do that in a single step, telling rpm to reinstall the package, but I figured erasing it was cleaner.

Anonymous said...

thanks, flakrat--this page saved my a$$!

FlakRat said...

Your welcome, glad to help. Video drivers are near the top when it comes to Linux workstation issues reported by my users.

FlakRat said...

Update, following the kernel critical update, CVE-2010-3081:

This blog entry, along with a comment from Alan Bartlet on the CentOS boards, provided the solution:
http://www.kwokinator.com/blog/20100927/fglrx-patched-linux-kernels

$ sudo perl -pi -e 's/return compat_alloc_user_space/return arch_compat_alloc_user_space/g;' /lib/modules/fglrx/build_mod/kcl_ioctl.c

After which, run the following to build the kernel module

# cd /lib/modules/fglrx/build_mod
# ./make.sh

# cd /lib/modules/fglrx
# ./make_install.sh