This commit is contained in:
Mateusz Kowalczyk 2014-09-22 01:27:00 +01:00
commit 1ffe41b34f
8 changed files with 219 additions and 153 deletions

View file

@ -73,6 +73,25 @@ hardware.opengl.driSupport32Bit = true;
</simplesect>
<simplesect><title>AMD Graphics Cards</title>
<para>AMD provides a proprietary driver for its graphics cards that
has better 3D performance than the X.org drivers. It is not enabled
by default because its not free software. You can enable it as follows:
<programlisting>
services.xserver.videoDrivers = [ "ati_unfree" ];
</programlisting>
You will need to reboot after enabling this driver to prevent a clash
with other kernel modules.</para>
<para>On 64-bit systems, if you want full acceleration for 32-bit
programs such as Wine, you should also set the following:
<programlisting>
hardware.opengl.driSupport32Bit = true;
</programlisting>
</para>
</simplesect>
<simplesect><title>Touchpads</title>

View file

@ -46,7 +46,8 @@ in
description = ''
On 64-bit systems, whether to support Direct Rendering for
32-bit applications (such as Wine). This is currently only
supported for the <literal>nvidia</literal> driver and for
supported for the <literal>nvidia</literal> and
<literal>ati_unfree</literal> drivers, as well as
<literal>Mesa</literal>.
'';
};
@ -104,22 +105,9 @@ in
environment.sessionVariables.LD_LIBRARY_PATH =
[ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ];
# FIXME: move this into card-specific modules.
hardware.opengl.package = mkDefault
(if elem "ati_unfree" videoDrivers then
kernelPackages.ati_drivers_x11
else
makePackage pkgs);
hardware.opengl.package = mkDefault (makePackage pkgs);
hardware.opengl.package32 = mkDefault (makePackage pkgs_i686);
boot.extraModulePackages =
optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions ++
optional (elem "ati_unfree" videoDrivers) kernelPackages.ati_drivers_x11;
environment.etc =
optionalAttrs (elem "ati_unfree" videoDrivers) {
"ati".source = "${kernelPackages.ati_drivers_x11}/etc/ati";
};
boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions;
};
}

View file

@ -0,0 +1,37 @@
# This module provides the proprietary ATI X11 / OpenGL drivers.
{ config, lib, pkgs, pkgs_i686, ... }:
with lib;
let
drivers = config.services.xserver.videoDrivers;
enabled = elem "ati_unfree" drivers;
ati_x11 = config.boot.kernelPackages.ati_drivers_x11;
in
{
config = mkIf enabled {
services.xserver.drivers = singleton
{ name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; };
hardware.opengl.package = ati_x11;
hardware.opengl.package32 = pkgs_i686.linuxPackages.ati_drivers_x11.override { libsOnly = true; kernel = null; };
environment.systemPackages = [ ati_x11 ];
boot.extraModulePackages = [ ati_x11 ];
boot.blacklistedKernelModules = [ "radeon" ];
environment.etc."ati".source = "${ati_x11}/etc/ati";
};
}

View file

@ -38,6 +38,7 @@
./hardware/pcmcia.nix
./hardware/video/bumblebee.nix
./hardware/video/nvidia.nix
./hardware/video/ati.nix
./installer/tools/nixos-checkout.nix
./installer/tools/tools.nix
./misc/assertions.nix

View file

@ -13,7 +13,6 @@ let
# Map video driver names to driver packages. FIXME: move into card-specific modules.
knownVideoDrivers = {
ati_unfree = { modules = [ kernelPackages.ati_drivers_x11 ]; driverName = "fglrx"; };
nouveau = { modules = [ pkgs.xf86_video_nouveau ]; };
unichrome = { modules = [ pkgs.xorgVideoUnichrome ]; };
virtualbox = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; };
@ -444,8 +443,7 @@ in
pkgs.xterm
pkgs.xdg_utils
]
++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh
++ optional (elem "ati_unfree" cfg.videoDrivers) kernelPackages.ati_drivers_x11;
++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh;
environment.pathsToLink =
[ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ];
@ -465,8 +463,6 @@ in
XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime.
LD_LIBRARY_PATH = concatStringsSep ":" (
[ "${xorg.libX11}/lib" "${xorg.libXext}/lib" ]
++ optionals (elem "ati_unfree" cfg.videoDrivers)
[ "${kernelPackages.ati_drivers_x11}/lib" "${kernelPackages.ati_drivers_x11}/X11R6/lib64/modules/linux" ]
++ concatLists (catAttrs "libPath" cfg.drivers));
} // cfg.displayManager.job.environment;

View file

@ -8,126 +8,129 @@ die(){ echo $@; exit 1; }
# custom unpack:
unzip $src
run_file=$(echo amd-catalyst-*)
run_file=$(echo fglrx-*/amd-driver-installer-*)
sh $run_file --extract .
eval "$patchPhase"
kernelVersion=$(cd ${kernel}/lib/modules && ls)
kernelBuild=$(echo ${kernel}/lib/modules/$kernelVersion/build)
linuxsources=$(echo ${kernel}/lib/modules/$kernelVersion/source)
case "$system" in
x86_64-linux)
arch=x86_64
lib_arch=lib64
DIR_DEPENDING_ON_XORG_VERSION=xpic_64a
;;
i686-linux)
arch=x86
lib_arch=lib
DIR_DEPENDING_ON_XORG_VERSION=xpic
;;
*) exit 1;;
esac
# Handle/Build the kernel module.
if test -z "$libsOnly"; then
# note: maybe the .config file should be used to determine this ?
# current kbuild infrastructure allows using CONFIG_* defines
# but ati sources don't use them yet..
# copy paste from make.sh
setSMP(){
kernelVersion=$(cd ${kernel}/lib/modules && ls)
kernelBuild=$(echo ${kernel}/lib/modules/$kernelVersion/build)
linuxsources=$(echo ${kernel}/lib/modules/$kernelVersion/source)
linuxincludes=$kernelBuild/include
# note: maybe the .config file should be used to determine this ?
# current kbuild infrastructure allows using CONFIG_* defines
# but ati sources don't use them yet..
# copy paste from make.sh
setSMP(){
# copied and stripped. source: make.sh:
linuxincludes=$kernelBuild/include
# 3
# linux/autoconf.h may contain this: #define CONFIG_SMP 1
# copied and stripped. source: make.sh:
# 3
# linux/autoconf.h may contain this: #define CONFIG_SMP 1
# Before 2.6.33 autoconf.h is under linux/.
# For 2.6.33 and later autoconf.h is under generated/.
if [ -f $linuxincludes/generated/autoconf.h ]; then
autoconf_h=$linuxincludes/generated/autoconf.h
else
autoconf_h=$linuxincludes/linux/autoconf.h
fi
src_file=$autoconf_h
# Before 2.6.33 autoconf.h is under linux/.
# For 2.6.33 and later autoconf.h is under generated/.
if [ -f $linuxincludes/generated/autoconf.h ]; then
autoconf_h=$linuxincludes/generated/autoconf.h
else
autoconf_h=$linuxincludes/linux/autoconf.h
fi
src_file=$autoconf_h
[ -e $src_file ] || die "$src_file not found"
[ -e $src_file ] || die "$src_file not found"
if [ `cat $src_file | grep "#undef" | grep "CONFIG_SMP" -c` = 0 ]; then
SMP=`cat $src_file | grep CONFIG_SMP | cut -d' ' -f3`
echo "file $src_file says: SMP=$SMP"
fi
if [ `cat $src_file | grep "#undef" | grep "CONFIG_SMP" -c` = 0 ]; then
SMP=`cat $src_file | grep CONFIG_SMP | cut -d' ' -f3`
echo "file $src_file says: SMP=$SMP"
fi
if [ "$SMP" = 0 ]; then
echo "assuming default: SMP=$SMP"
fi
if [ "$SMP" = 0 ]; then
echo "assuming default: SMP=$SMP"
fi
# act on final result
if [ ! "$SMP" = 0 ]; then
smp="-SMP"
def_smp=-D__SMP__
fi
# act on final result
if [ ! "$SMP" = 0 ]; then
smp="-SMP"
def_smp=-D__SMP__
fi
}
}
setModVersions(){
! grep CONFIG_MODVERSIONS=y $kernel/config ||
def_modversions="-DMODVERSIONS"
# make.sh contains much more code to determine this whether its enabled
}
setModVersions(){
! grep CONFIG_MODVERSIONS=y $kernelBuild/.config ||
def_modversions="-DMODVERSIONS"
# make.sh contains much more code to determine this whether its enabled
}
# ==============================================================
# resolve if we are building for a kernel with a fix for CVE-2010-3081
# On kernels with the fix, use arch_compat_alloc_user_space instead
# of compat_alloc_user_space since the latter is GPL-only
# ==============================================================
# resolve if we are building for a kernel with a fix for CVE-2010-3081
# On kernels with the fix, use arch_compat_alloc_user_space instead
# of compat_alloc_user_space since the latter is GPL-only
COMPAT_ALLOC_USER_SPACE=arch_compat_alloc_user_space
COMPAT_ALLOC_USER_SPACE=arch_compat_alloc_user_space
for src_file in \
for src_file in \
$kernelBuild/arch/x86/include/asm/compat.h \
$linuxsources/arch/x86/include/asm/compat.h \
$kernelBuild/include/asm-x86_64/compat.h \
$linuxsources/include/asm-x86_64/compat.h \
$kernelBuild/include/asm/compat.h;
do
if [ -e $src_file ];
then
break
do
if [ -e $src_file ];
then
break
fi
done
if [ ! -e $src_file ];
then
echo "Warning: x86 compat.h not found in kernel headers"
echo "neither arch/x86/include/asm/compat.h nor include/asm-x86_64/compat.h"
echo "could be found in $kernelBuild or $linuxsources"
echo ""
else
if [ `cat $src_file | grep -c arch_compat_alloc_user_space` -gt 0 ]
then
COMPAT_ALLOC_USER_SPACE=arch_compat_alloc_user_space
fi
echo "file $src_file says: COMPAT_ALLOC_USER_SPACE=$COMPAT_ALLOC_USER_SPACE"
fi
done
if [ ! -e $src_file ];
then
echo "Warning: x86 compat.h not found in kernel headers"
echo "neither arch/x86/include/asm/compat.h nor include/asm-x86_64/compat.h"
echo "could be found in $kernelBuild or $linuxsources"
echo ""
else
if [ `cat $src_file | grep -c arch_compat_alloc_user_space` -gt 0 ]
then
COMPAT_ALLOC_USER_SPACE=arch_compat_alloc_user_space
fi
echo "file $src_file says: COMPAT_ALLOC_USER_SPACE=$COMPAT_ALLOC_USER_SPACE"
fi
# make.sh contains some code figuring out whether to use these or not..
PAGE_ATTR_FIX=0
setSMP
setModVersions
CC=gcc
MODULE=fglrx
LIBIP_PREFIX=$TMP/arch/$arch/lib/modules/fglrx/build_mod
[ -d $LIBIP_PREFIX ]
GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`"
# make.sh contains some code figuring out whether to use these or not..
PAGE_ATTR_FIX=0
setSMP
setModVersions
CC=gcc
MODULE=fglrx
case "$system" in
x86_64-linux)
arch=x86_64
lib_arch=lib64
;;
i686-linux)
arch=x86
lib_arch=lib
;;
*) exit 1;;
esac
LIBIP_PREFIX=$TMP/arch/$arch/lib/modules/fglrx/build_mod
[ -d $LIBIP_PREFIX ]
GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`"
{ # build .ko module
cd ./common/lib/modules/fglrx/build_mod/2.6.x
echo .lib${MODULE}_ip.a.GCC${GCC_MAJOR}.cmd
echo 'This is a dummy file created to suppress this warning: could not find /lib/modules/fglrx/build_mod/2.6.x/.libfglrx_ip.a.GCC4.cmd for /lib/modules/fglrx/build_mod/2.6.x/libfglrx_ip.a.GCC4' > lib${MODULE}_ip.a.GCC${GCC_MAJOR}.cmd
{ # build .ko module
cd ./common/lib/modules/fglrx/build_mod/2.6.x
echo .lib${MODULE}_ip.a.GCC${GCC_MAJOR}.cmd
echo 'This is a dummy file created to suppress this warning: could not find /lib/modules/fglrx/build_mod/2.6.x/.libfglrx_ip.a.GCC4.cmd for /lib/modules/fglrx/build_mod/2.6.x/libfglrx_ip.a.GCC4' > lib${MODULE}_ip.a.GCC${GCC_MAJOR}.cmd
sed -i -e "s@COMPAT_ALLOC_USER_SPACE@$COMPAT_ALLOC_USER_SPACE@" ../kcl_ioctl.c
sed -i -e "s@COMPAT_ALLOC_USER_SPACE@$COMPAT_ALLOC_USER_SPACE@" ../kcl_ioctl.c
make CC=${CC} \
make CC=${CC} \
LIBIP_PREFIX=$(echo "$LIBIP_PREFIX" | sed -e 's|^\([^/]\)|../\1|') \
MODFLAGS="-DMODULE -DATI -DFGL -DPAGE_ATTR_FIX=$PAGE_ATTR_FIX -DCOMPAT_ALLOC_USER_SPACE=$COMPAT_ALLOC_USER_SPACE $def_smp $def_modversions" \
KVER=$kernelVersion \
@ -135,8 +138,10 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`"
PAGE_ATTR_FIX=$PAGE_ATTR_FIX \
-j4
cd $TMP
}
cd $TMP
}
fi
{ # install
@ -152,13 +157,15 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`"
# what are those files used for?
cp -r common/etc $out
DIR_DEPENDING_ON_XORG_VERSION=xpic_64a
cp -r $DIR_DEPENDING_ON_XORG_VERSION/usr/X11R6/$lib_arch/* $out/lib/xorg
t=$out/lib/modules/${kernelVersion}/kernel/drivers/misc
mkdir -p $t
# install kernel module
if test -z "$libsOnly"; then
t=$out/lib/modules/${kernelVersion}/kernel/drivers/misc
mkdir -p $t
cp ./common/lib/modules/fglrx/build_mod/2.6.x/fglrx.ko $t
cp ./common/lib/modules/fglrx/build_mod/2.6.x/fglrx.ko $t
fi
# should this be installed at all?
# its used by the example fglrx_gamma only
@ -181,10 +188,46 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`"
# make xorg use the ati version
ln -s $out/lib/xorg/modules/extensions/{fglrx/fglrx-libglx.so,libglx.so}
# Correct some paths that are hardcoded into binary libs.
if [ "$arch" == "x86_64" ]; then
for lib in \
lib/xorg/modules/extensions/fglrx/fglrx-libglx.so \
lib/xorg/modules/glesx.so \
lib/dri/fglrx_dri.so \
lib/fglrx_dri.so \
lib/fglrx-libGL.so.1.2
do
oldPaths="/usr/X11R6/lib/modules/dri"
newPaths="/run/opengl-driver/lib/dri"
sed -i -e "s|$oldPaths|$newPaths|" $out/$lib
done
else
oldPaths="/usr/X11R6/lib32/modules/dri\x00/usr/lib32/dri"
newPaths="/run/opengl-driver-32/lib/dri\x00/dev/null/dri"
sed -i -e "s|$oldPaths|$newPaths|" \
$out/lib/xorg/modules/extensions/fglrx/fglrx-libglx.so
for lib in \
lib/dri/fglrx_dri.so \
lib/fglrx_dri.so \
lib/xorg/modules/glesx.so
do
oldPaths="/usr/X11R6/lib32/modules/dri/"
newPaths="/run/opengl-driver-32/lib/dri"
sed -i -e "s|$oldPaths|$newPaths|" $out/$lib
done
oldPaths="/usr/X11R6/lib32/modules/dri\x00"
newPaths="/run/opengl-driver-32/lib/dri"
sed -i -e "s|$oldPaths|$newPaths|" $out/lib/fglrx-libGL.so.1.2
fi
# libstdc++ and gcc are needed by some libs
patchelf --set-rpath $gcc/$lib_arch $out/lib/libatiadlxx.so
}
if test -z "$libsOnly"; then
{ # build samples
mkdir -p $out/bin
@ -229,6 +272,8 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`"
}
fi
for p in $extraDRIlibs; do
for lib in $p/lib/*.so*; do
ln -s $lib $out/lib/

View file

@ -1,10 +1,16 @@
{ stdenv, fetchurl, kernel, xlibs, which, imake
{ stdenv, fetchurl, kernel ? null, xlibs, which, imake
, mesa # for fgl_glxgears
, libXxf86vm, xf86vidmodeproto # for fglrx_gamma
, xorg, makeWrapper, glibc, patchelf
, unzip
, # Whether to build the libraries only (i.e. not the kernel module or
# driver utils). Used to support 32-bit binaries on 64-bit
# Linux.
libsOnly ? false
}:
assert (!libsOnly) -> kernel != null;
# If you want to use a different Xorg version probably
# DIR_DEPENDING_ON_XORG_VERSION in builder.sh has to be adopted (?)
# make sure libglx.so of ati is used. xorg.xorgserver does provide it as well
@ -21,12 +27,10 @@
# There is one issue left:
# /usr/lib/dri/fglrx_dri.so must point to /run/opengl-driver/lib/fglrx_dri.so
# You eventually have to blacklist radeon module (?)
assert stdenv.system == "x86_64-linux";
with stdenv.lib;
stdenv.mkDerivation {
name = "ati-drivers-13.12-${kernel.version}";
name = "ati-drivers-14.4" + (optionalString (!libsOnly) "-${kernel.version}");
builder = ./builder.sh;
@ -34,8 +38,8 @@ stdenv.mkDerivation {
gcc = stdenv.gcc.gcc;
src = fetchurl {
url = http://www2.ati.com/drivers/linux/amd-catalyst-13.12-linux-x86.x86_64.zip;
sha256 = "1c3fn328340by4qn99dgfj8c2q34fxdb2alcak0vnyc6bw7l5sms";
url = http://www2.ati.com/drivers/linux/amd-catalyst-14-4-rev2-linux-x86-x86-64-may6.zip;
sha256 = "1xbhn55yifis9b0lzb3s03hc1bcq8jmy7l96m4x8d842n7ji7qlk";
curlOpts = "--referer http://support.amd.com/en-us/download/desktop?os=Linux%20x86_64";
};
@ -51,7 +55,9 @@ stdenv.mkDerivation {
mesa
];
kernel = kernel.dev;
inherit libsOnly;
kernel = if libsOnly then null else kernel.dev;
inherit glibc /* glibc only used for setting interpreter */;
@ -75,15 +81,7 @@ stdenv.mkDerivation {
homepage = http://support.amd.com/us/gpudownload/Pages/index.aspx;
license = licenses.unfree;
maintainers = with maintainers; [marcweber offline];
platforms = [ "x86_64-linux" ];
platforms = platforms.linux;
hydraPlatforms = [];
};
# moved assertions here because the name is evaluated when the NixOS manual is generated
# Don't make that fail - fail lazily when a users tries to build this derivation only
dummy =
# assert xorg.xorgserver.name == "xorg-server-1.7.5";
assert stdenv.system == "x86_64-linux"; # i686-linux should work as well - however I didn't test it.
null;
}

View file

@ -31,21 +31,3 @@ index d3ad3ce..9362b58 100755
+# endif
#endif
}
diff -urN a/common/lib/modules/fglrx/build_mod/kcl_acpi.c common/lib/modules/fglrx/build_mod/kcl_acpi.c
--- a/common/lib/modules/fglrx/build_mod/kcl_acpi.c 2013-12-27 13:32:34.734832283 +0100
+++ b/common/lib/modules/fglrx/build_mod/kcl_acpi.c 2013-12-27 13:33:31.849831765 +0100
@@ -1002,7 +1002,11 @@
#endif
{
return KCL_ACPI_ERROR;
- }
+ }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,1)
+ ((acpi_tbl_table_handler)handler)(hdr);
+#else
((acpi_table_handler)handler)(hdr);
+#endif
return KCL_ACPI_OK;
}