diff --git a/package/nvidia-driver/0001-use-LDFLAGS.patch b/package/nvidia-driver/0001-use-LDFLAGS.patch new file mode 100644 index 0000000000..7b7df80988 --- /dev/null +++ b/package/nvidia-driver/0001-use-LDFLAGS.patch @@ -0,0 +1,48 @@ +kernel: use LDFLAGS when linking modules + +Currently, linking module objects is simply using $(LD), assuming that +the default emulation is correct for the current architecture. + +However, that might not be the case when the toolchain default is not +the same as the current arch. For example, if the toolchain defaults to +i386 and is capable of x86_64, and we're targetting x86_64 (or the +opposite), the link would fail because the ld emulation is incorrect: + + .../i686-pc-linux-gnu-ld: Relocatable linking with relocations from + format elf64-x86-64 (.../nvidia-driver-370.23/kernel/nvidia/nv-frontend.o) + to format elf32-i386 (.../nvidia-driver-370.23/kernel/nvidia/nv-interface.o) + is not supported + +Add use of $(LDFLAGS) when doing the link, as the kernel provides the +proper emulation in those. + +Signed-off-by: "Yann E. MORIN" + +--- +Issue reported upstream: + https://devtalk.nvidia.com/default/topic/958653/ + +diff -durN nvidia-driver-370.23.orig/kernel/nvidia/nvidia.Kbuild nvidia-driver-370.23/kernel/nvidia/nvidia.Kbuild +--- nvidia-driver-370.23.orig/kernel/nvidia/nvidia.Kbuild 2016-08-09 01:57:50.000000000 +0200 ++++ nvidia-driver-370.23/kernel/nvidia/nvidia.Kbuild 2016-08-20 12:25:02.780233423 +0200 +@@ -87,7 +87,7 @@ + always += $(NVIDIA_INTERFACE) + + $(obj)/$(NVIDIA_INTERFACE): $(addprefix $(obj)/,$(NVIDIA_OBJECTS)) +- $(LD) -r -o $@ $^ ++ $(LD) $(LDFLAGS) -r -o $@ $^ + + + # +diff -durN nvidia-driver-370.23.orig/kernel/nvidia-modeset/nvidia-modeset.Kbuild nvidia-driver-370.23/kernel/nvidia-modeset/nvidia-modeset.Kbuild +--- nvidia-driver-370.23.orig/kernel/nvidia-modeset/nvidia-modeset.Kbuild 2016-08-09 01:43:19.000000000 +0200 ++++ nvidia-driver-370.23/kernel/nvidia-modeset/nvidia-modeset.Kbuild 2016-08-20 12:25:39.596772662 +0200 +@@ -70,7 +70,7 @@ + always += $(NVIDIA_MODESET_INTERFACE) + + $(obj)/$(NVIDIA_MODESET_INTERFACE): $(addprefix $(obj)/,$(NVIDIA_MODESET_OBJECTS)) +- $(LD) -r -o $@ $^ ++ $(LD) $(LDFLAGS) -r -o $@ $^ + + # + # Register the conftests needed by nvidia-modeset.ko diff --git a/package/nvidia-driver/Config.in b/package/nvidia-driver/Config.in index 04499f6334..1105ec63b6 100644 --- a/package/nvidia-driver/Config.in +++ b/package/nvidia-driver/Config.in @@ -22,10 +22,11 @@ config BR2_PACKAGE_NVIDIA_DRIVER_XORG default y depends on BR2_PACKAGE_XSERVER_XORG_SERVER_MODULAR select BR2_PACKAGE_MESA3D_HEADERS - select BR2_PACKAGE_XLIB_LIBX11 - select BR2_PACKAGE_XLIB_LIBXEXT + select BR2_PACKAGE_XLIB_LIBX11 # runtime + select BR2_PACKAGE_XLIB_LIBXEXT # runtime select BR2_PACKAGE_HAS_LIBGL select BR2_PACKAGE_HAS_LIBEGL + select BR2_PACKAGE_HAS_LIBEGL_WAYLAND select BR2_PACKAGE_HAS_LIBGLES if BR2_PACKAGE_NVIDIA_DRIVER_XORG @@ -62,7 +63,6 @@ config BR2_PACKAGE_NVIDIA_DRIVER_OPENCL config BR2_PACKAGE_NVIDIA_DRIVER_CUDA_PROGS bool "CUDA MPS server and control" - depends on BR2_x86_64 help Say 'y' here if you need to run more than one program doing CUDA at the same time. The MPS server will be diff --git a/package/nvidia-driver/nvidia-driver.hash b/package/nvidia-driver/nvidia-driver.hash index ba2f5554bf..9427ffba44 100644 --- a/package/nvidia-driver/nvidia-driver.hash +++ b/package/nvidia-driver/nvidia-driver.hash @@ -1,3 +1,3 @@ # Locally computed -sha256 d3a2842cbfb1163e20c658fbfaf5a235d5c9f035cd2d657f15df8a14b3fe80b1 NVIDIA-Linux-x86-358.16.run -sha256 a942cdb29ed715ff1ce25beb06b6c2490126b98ef8bee5d9973967b557596bf2 NVIDIA-Linux-x86_64-358.16.run +sha256 38cb22fa85ef74ea960d3e5d644838cd961984ffc32bb0d052414cc7fa32e315 NVIDIA-Linux-x86-367.35.run +sha256 d2df3fcb1a145984b9de4f2f38a90e353469e9d12279cf5e2c67c553b112d075 NVIDIA-Linux-x86_64-367.35.run diff --git a/package/nvidia-driver/nvidia-driver.mk b/package/nvidia-driver/nvidia-driver.mk index 7e670206e0..c1fc9863bb 100644 --- a/package/nvidia-driver/nvidia-driver.mk +++ b/package/nvidia-driver/nvidia-driver.mk @@ -4,7 +4,7 @@ # ################################################################################ -NVIDIA_DRIVER_VERSION = 358.16 +NVIDIA_DRIVER_VERSION = 367.35 NVIDIA_DRIVER_SUFFIX = $(if $(BR2_x86_64),_64) NVIDIA_DRIVER_SITE = ftp://download.nvidia.com/XFree86/Linux-x86$(NVIDIA_DRIVER_SUFFIX)/$(NVIDIA_DRIVER_VERSION) NVIDIA_DRIVER_SOURCE = NVIDIA-Linux-x86$(NVIDIA_DRIVER_SUFFIX)-$(NVIDIA_DRIVER_VERSION).run @@ -20,25 +20,56 @@ ifeq ($(BR2_PACKAGE_NVIDIA_DRIVER_XORG),y) # are build dependencies of packages that depend on nvidia-driver, so # they should be built prior to those packages, and the only simple # way to do so is to make nvidia-driver depend on them. -NVIDIA_DRIVER_DEPENDENCIES = mesa3d-headers xlib_libX11 xlib_libXext +NVIDIA_DRIVER_DEPENDENCIES = mesa3d-headers NVIDIA_DRIVER_PROVIDES = libgl libegl libgles -# We have two variables that contains a list of libraries to install: -# NVIDIA_DRIVER_LIBS -# contains the libraries whose filename end up in .so.$(VERSION); rather -# than duplicate the version string for all of them, we just store their -# basename, and append the version string below. -# NVIDIA_DRIVER_LIBS_NO_VERSION -# contains all libraries the do not use the NVidia version; since there -# is currently only one such library, we store its full name. +# libGL.so.$(NVIDIA_DRIVER_VERSION) is the legacy libGL.so library; it +# has been replaced with libGL.so.1.0.0. Installing both is technically +# possible, but great care must be taken to ensure they do not conflict, +# so that EGL still works. The legacy library exposes an NVidia-specific +# API, so it should not be needed, except for legacy, binary-only +# applications (in other words: we don't care). +# +# libGL.so.1.0.0 is the new vendor-neutral library, aimed at replacing +# the old libGL.so.$(NVIDIA_DRIVER_VERSION) library. The latter contains +# NVidia extensions (which is deemed bad now), while the former follows +# the newly-introduced vendor-neutral "dispatching" API/ABI: +# https://github.com/aritger/linux-opengl-abi-proposal/blob/master/linux-opengl-abi-proposal.txt +# However, this is not very usefull to us, as we don't support multiple +# GL providers at the same time on the system, which this proposal is +# aimed at supporting. +# +# So we only install the legacy library for now. +NVIDIA_DRIVER_LIBS_GL = \ + libGLX.so.0 \ + libGL.so.$(NVIDIA_DRIVER_VERSION) \ + libGLX_nvidia.so.$(NVIDIA_DRIVER_VERSION) \ + +NVIDIA_DRIVER_LIBS_EGL = \ + libEGL.so.1 \ + libGLdispatch.so.0 \ + libEGL_nvidia.so.$(NVIDIA_DRIVER_VERSION) \ + +NVIDIA_DRIVER_LIBS_GLES = \ + libGLESv1_CM.so.1 \ + libGLESv2.so.2 \ + libGLESv1_CM_nvidia.so.$(NVIDIA_DRIVER_VERSION) \ + libGLESv2_nvidia.so.$(NVIDIA_DRIVER_VERSION) \ + +NVIDIA_DRIVER_LIBS_MISC = \ + libnvidia-eglcore.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-egl-wayland.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-glcore.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-glsi.so.$(NVIDIA_DRIVER_VERSION) \ + tls/libnvidia-tls.so.$(NVIDIA_DRIVER_VERSION) \ + libvdpau_nvidia.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-ml.so.$(NVIDIA_DRIVER_VERSION) \ -# Each line corresponds to a specific set of libraries NVIDIA_DRIVER_LIBS = \ - libEGL libGLESv1_CM libGLESv2 libGL \ - libnvidia-glcore libnvidia-eglcore libnvidia-glsi \ - tls/libnvidia-tls \ - libvdpau libvdpau_nvidia \ - libnvidia-ml + $(NVIDIA_DRIVER_LIBS_GL) \ + $(NVIDIA_DRIVER_LIBS_EGL) \ + $(NVIDIA_DRIVER_LIBS_GLES) \ + $(NVIDIA_DRIVER_LIBS_MISC) \ # Install the gl.pc file define NVIDIA_DRIVER_INSTALL_GL_DEV @@ -54,110 +85,91 @@ endef # on using those libraries (e.g. if the user has such an agreement, or # wants to run a third-party program developped under such an agreement). ifeq ($(BR2_PACKAGE_NVIDIA_DRIVER_PRIVATE_LIBS),y) -NVIDIA_DRIVER_LIBS += libnvidia-ifr libnvidia-fbc +NVIDIA_DRIVER_LIBS += \ + libnvidia-ifr.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-fbc.so.$(NVIDIA_DRIVER_VERSION) endif # We refer to the destination path; the origin file has no directory component -NVIDIA_DRIVER_X_MODS = drivers/nvidia_drv.so \ +NVIDIA_DRIVER_X_MODS = \ + drivers/nvidia_drv.so \ extensions/libglx.so.$(NVIDIA_DRIVER_VERSION) \ libnvidia-wfb.so.$(NVIDIA_DRIVER_VERSION) endif # X drivers ifeq ($(BR2_PACKAGE_NVIDIA_DRIVER_CUDA),y) -NVIDIA_DRIVER_LIBS += libcuda libnvidia-compiler libnvcuvid libnvidia-encode +NVIDIA_DRIVER_LIBS += \ + libcuda.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-compiler.so.$(NVIDIA_DRIVER_VERSION) \ + libnvcuvid.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-fatbinaryloader.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-ptxjitcompiler.so.$(NVIDIA_DRIVER_VERSION) \ + libnvidia-encode.so.$(NVIDIA_DRIVER_VERSION) ifeq ($(BR2_PACKAGE_NVIDIA_DRIVER_CUDA_PROGS),y) NVIDIA_DRIVER_PROGS = nvidia-cuda-mps-control nvidia-cuda-mps-server endif endif ifeq ($(BR2_PACKAGE_NVIDIA_DRIVER_OPENCL),y) -NVIDIA_DRIVER_LIBS_NO_VERSION += libOpenCL.so.1.0.0 -NVIDIA_DRIVER_LIBS += libnvidia-opencl +NVIDIA_DRIVER_LIBS += \ + libOpenCL.so.1.0.0 \ + libnvidia-opencl.so.$(NVIDIA_DRIVER_VERSION) endif +# Build and install the kernel modules if needed +ifeq ($(BR2_PACKAGE_NVIDIA_DRIVER_MODULE),y) + +NVIDIA_DRIVER_MODULES = nvidia nvidia-modeset nvidia-drm +ifeq ($(BR2_x86_64),y) +NVIDIA_DRIVER_MODULES += nvidia-uvm +endif + +# They can't do everything like everyone. They need those variables, +# because they don't recognise the usual variables set by the kernel +# build system. We also need to tell them what modules to build. +NVIDIA_DRIVER_MODULE_MAKE_OPTS = \ + NV_KERNEL_SOURCES="$(LINUX_DIR)" \ + NV_KERNEL_OUTPUT="$(LINUX_DIR)" \ + NV_KERNEL_MODULES="$(NVIDIA_DRIVER_MODULES)" + +NVIDIA_DRIVER_MODULE_SUBDIRS = kernel + +$(eval $(kernel-module)) + +endif # BR2_PACKAGE_NVIDIA_DRIVER_MODULE == y + # The downloaded archive is in fact an auto-extract script. So, it can run # virtually everywhere, and it is fine enough to provide useful options. # Except it can't extract into an existing (even empty) directory. define NVIDIA_DRIVER_EXTRACT_CMDS $(SHELL) $(DL_DIR)/$(NVIDIA_DRIVER_SOURCE) --extract-only --target \ $(@D)/tmp-extract + chmod u+w -R $(@D) mv $(@D)/tmp-extract/* $(@D)/tmp-extract/.manifest $(@D) rm -rf $(@D)/tmp-extract endef -# Build and install the kernel modules if needed -ifeq ($(BR2_PACKAGE_NVIDIA_DRIVER_MODULE),y) - -NVIDIA_DRIVER_DEPENDENCIES += linux - -# NVidia uses the legacy naming scheme for the x86 architecture, when i386 -# and x86_64 were still considered two separate architectures in the Linux -# kernel. -NVIDIA_DRIVER_ARCH = $(if $(BR2_i386),i386,$(BR2_ARCH)) - -NVIDIA_DRIVER_MOD_DIRS = kernel -NVIDIA_DRIVER_MOD_FILES = kernel/nvidia.ko -# nvidia-uvm.ko only available for x86_64 -ifeq ($(BR2_x86_64)$(BR2_PACKAGE_NVIDIA_DRIVER_CUDA),yy) -NVIDIA_DRIVER_MOD_DIRS += kernel/uvm -NVIDIA_DRIVER_MOD_FILES += kernel/uvm/nvidia-uvm.ko -endif - -# We can not use '$(MAKE) -C $(@D)/$${dir}' because NVidia's uses its own -# Makefile to build a kernel module, which includes a lot of assumptions -# on where to find its own sub-Makefile fragments, and fails if make is -# not run from the directory where the module's source files are. Hence -# our little trick to cd in there first. -# That's also the reason why we do not use LINUX_MAKE_FLAGS or the other -# linux-specific variables, since NVidia's Makefile does not understand -# them. -define NVIDIA_DRIVER_BUILD_CMDS - for dir in $(NVIDIA_DRIVER_MOD_DIRS); do \ - (cd $(@D)/$${dir} && \ - $(MAKE) SYSSRC="$(LINUX_DIR)" SYSOUT="$(LINUX_DIR)" \ - CC="$(TARGET_CC)" LD="$(TARGET_LD)" HOSTCC="$(HOSTCC)" \ - ARCH=$(NVIDIA_DRIVER_ARCH) module) || exit 1; \ - done -endef - -# We do not use module-install because NVidia's Makefile requires root. -# Also, we do not install it in the expected location (in nvidia/ rather -# than in kernel/drivers/video/) -define NVIDIA_DRIVER_INSTALL_KERNEL_MODULE - for mod in $(NVIDIA_DRIVER_MOD_FILES); do \ - $(INSTALL) -D -m 0644 $(@D)/$${mod} \ - $(TARGET_DIR)/lib/modules/$(LINUX_VERSION_PROBED)/nvidia/$${mod##*/} \ - || exit 1; \ - done - $(HOST_DIR)/sbin/depmod -a -b $(TARGET_DIR) $(LINUX_VERSION_PROBED) -endef - -endif # BR2_PACKAGE_NVIDIA_DRIVER_MODULE == y - # Helper to install libraries # $1: destination directory (target or staging) # -# For all libraries that need it, we append the NVidia version string. -# Then for all libraries, we install them and create a symlink using -# their SONAME, so we can link to them at runtime; we also create the -# no-version symlink, so we can link to them at build time. +# For all libraries, we install them and create a symlink using +# their SONAME, so we can link to them at runtime; we also create +# the no-version symlink, so we can link to them at build time. define NVIDIA_DRIVER_INSTALL_LIBS - for libpath in $(addsuffix .so.$(NVIDIA_DRIVER_VERSION),$(NVIDIA_DRIVER_LIBS)) \ - $(NVIDIA_DRIVER_LIBS_NO_VERSION); \ - do \ - libname="$${libpath##*/}"; \ - $(INSTALL) -D -m 0644 $(@D)/$${libpath} $(1)/usr/lib/$${libname}; \ - libsoname="$$( $(TARGET_READELF) -d "$(@D)/$${libpath}" \ + $(foreach lib,$(NVIDIA_DRIVER_LIBS),\ + $(INSTALL) -D -m 0644 $(@D)/$(lib) $(1)/usr/lib/$(notdir $(lib)) + libsoname="$$( $(TARGET_READELF) -d "$(@D)/$(lib)" \ |sed -r -e '/.*\(SONAME\).*\[(.*)\]$$/!d; s//\1/;' )"; \ - if [ -n "$${libsoname}" -a "$${libsoname}" != "$${libname}" ]; then \ - ln -sf $${libname} $(1)/usr/lib/$${libsoname}; \ - fi; \ - baseso="$${libname/.so*}.so"; \ - if [ -n "$${baseso}" -a "$${baseso}" != "$${libname}" ]; then \ - ln -sf $${libname} $(1)/usr/lib/$${baseso}; \ - fi; \ - done + if [ -n "$${libsoname}" -a "$${libsoname}" != "$(notdir $(lib))" ]; then \ + ln -sf $(notdir $(lib)) \ + $(1)/usr/lib/$${libsoname}; \ + fi + baseso=$(firstword $(subst .,$(space),$(notdir $(lib)))).so; \ + if [ -n "$${baseso}" -a "$${baseso}" != "$(notdir $(lib))" ]; then \ + ln -sf $(notdir $(lib)) $(1)/usr/lib/$${baseso}; \ + fi + ) endef # For staging, install libraries and development files @@ -169,14 +181,14 @@ endef # For target, install libraries and X.org modules define NVIDIA_DRIVER_INSTALL_TARGET_CMDS $(call NVIDIA_DRIVER_INSTALL_LIBS,$(TARGET_DIR)) - for m in $(NVIDIA_DRIVER_X_MODS); do \ - $(INSTALL) -D -m 0644 $(@D)/$${m##*/} \ - $(TARGET_DIR)/usr/lib/xorg/modules/$${m}; \ - done - for p in $(NVIDIA_DRIVER_PROGS); do \ - $(INSTALL) -D -m 0755 $(@D)/$${p} \ - $(TARGET_DIR)/usr/bin/$${p}; \ - done + $(foreach m,$(NVIDIA_DRIVER_X_MODS), \ + $(INSTALL) -D -m 0644 $(@D)/$(notdir $(m)) \ + $(TARGET_DIR)/usr/lib/xorg/modules/$(m) + ) + $(foreach p,$(NVIDIA_DRIVER_PROGS), \ + $(INSTALL) -D -m 0755 $(@D)/$(p) \ + $(TARGET_DIR)/usr/bin/$(p) + ) $(NVIDIA_DRIVER_INSTALL_KERNEL_MODULE) endef