blob: 3fd8494c28e6c846d92c71740664e3c8d4fb6acf [file] [log] [blame]
#
# Copyright 2023 Google LLC
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
EAPI=7
FEATURES="xattr"
MODULES_OPTIONAL_USE="driver"
inherit flag-o-matic cos-linux-fw cos-linux-mod linux-mod multilib readme.gentoo-r1 \
systemd toolchain-funcs unpacker user-info cos-nvidia cos-linux-artifact
# Define GDRCopy version
GDRCOPY_PV="2.5"
GDRCOPY_P="gdrcopy-${GDRCOPY_PV}"
NV_URI="https://download.nvidia.com/XFree86"
DESCRIPTION="NVIDIA Accelerated Graphics Driver and GDRCopy Module"
HOMEPAGE="https://www.nvidia.com/download/index.aspx"
SRC_URI="${NV_URI}/NVIDIA-kernel-module-source/NVIDIA-kernel-module-source-${PV}.tar.xz
amd64? ( ${NV_URI}/Linux-x86_64/${PV}/NVIDIA-Linux-x86_64-${PV}.run )
arm64? ( ${NV_URI}Linux-aarch64/${PV}/NVIDIA-Linux-aarch64-${PV}.run )
https://github.com/NVIDIA/gdrcopy/archive/refs/tags/v${GDRCOPY_PV}.tar.gz -> ${GDRCOPY_P}.tar.gz
"
declare -A arch_map=(
[amd64]="x86_64"
[arm64]="aarch64"
)
NV_ARCH="${arch_map[$ARCH]:-x86_64}"
INSTALLER_NAME="NVIDIA-Linux-${NV_ARCH}-${PV}"
RUNFILE="${INSTALLER_NAME}.run"
S="${WORKDIR}"
LICENSE="NVIDIA-r2 BSD BSD-2 GPL-2 MIT openssl"
KEYWORDS="*"
SLOT="0/${PV%%.*}"
IUSE="+driver +clang +llvm_ias +xattr -install-nvidia-usr kernel-6_12"
REQUIRED_USE="
llvm_ias? ( clang )
"
DEPEND=""
RDEPEND="${DEPEND}"
BDEPEND="dev-libs/openssl"
QA_PREBUILT="lib/firmware/* opt/nvidia/*"
src_unpack() {
cp ${DISTDIR}/${RUNFILE} ${S}
sh "${RUNFILE}" --extract-only
unpack "NVIDIA-kernel-module-source-${PV}.tar.xz"
unpack "${GDRCOPY_P}.tar.gz"
}
pkg_setup() {
# We only list the NVIDIA modules here for the initial build.
# GDRCopy will be built separately in src_compile.
MODULE_NAMES="
nvidia(nvidia/${PV}:kernel-module-source:kernel-module-source/kernel-open)
nvidia-drm(nvidia/${PV}:kernel-module-source:kernel-module-source/kernel-open)
nvidia-modeset(nvidia/${PV}:kernel-module-source:kernel-module-source/kernel-open)
nvidia-peermem(nvidia/${PV}:kernel-module-source:kernel-module-source/kernel-open)
nvidia-uvm(nvidia/${PV}:kernel-module-source:kernel-module-source/kernel-open)"
KBUILD_OUTPUT="${KERNEL_DIR}/build"
linux-mod_pkg_setup
if [[ "$ARCH" == "arm64" ]]; then
CXX="aarch64-cros-linux-gnu-gcc" # Cross-compiler for x86->ARM64
else
CXX="${CBUILD}-gcc" # default to host compiler
fi
BUILD_PARAMS="TARGET_ARCH=${NV_ARCH} CXX=${CXX} KERNEL_SOURCES=${KV_DIR} KBUILD_OUTPUT=${KBUILD_OUTPUT} NV_VERBOSE=1 IGNORE_CC_MISMATCH=yes SYSSRC=${KV_DIR} SYSOUT=${KV_OUT_DIR}"
BUILD_TARGETS="modules"
}
src_prepare() {
# Prepare NVIDIA sources
mv NVIDIA-kernel-module-source-${PV} kernel-module-source || die
eapply "${FILESDIR}"/arm-enable-bti-535.104.05.patch
eapply "${FILESDIR}"/nvidia-drivers-525.60.13-utils.patch
eapply "${FILESDIR}"/nvidia-drivers-525.60.13-ld.patch
if use kernel-6_12; then
eapply "${FILESDIR}"/nvidia-drivers-535.104.05-nv_follow_pfn-compile-fix.patch
eapply "${FILESDIR}"/nvidia-drivers-535.104.05-output_poll_changed-compile-fix.patch
eapply "${FILESDIR}"/nvidia-drivers-535.104.05-crypto_shash_ctx_aligned-compile-fix.patch
eapply "${FILESDIR}"/nvidia-drivers-535.104.05-PageSwapCache-compile-fix.patch
fi
# Prepare GDRCopy sources in its own directory
pushd "${GDRCOPY_P}" || die "Failed to enter GDRCopy source directory"
eapply "${FILESDIR}"/0001-gdrcopy-KERNELDIR-Location.patch
popd || die
use clang || cros_use_gcc
default
}
src_compile() {
tc-export AR CC CXX LD OBJCOPY OBJDUMP
if use llvm_ias; then
export LLVM_IAS=1
fi
cros_allow_gnu_build_tools
# 1. Compile NVIDIA Kernel Modules
einfo "Compiling NVIDIA kernel modules..."
BUILD_FIXES="CFLAGS_MODULE='-Wno-error=strict-prototypes'" linux-mod_src_compile
# 2. Compile GDRCopy Kernel Module
einfo "Compiling GDRCopy kernel modules..."
cos-nvidia_compile_gdrcopy "${GDRCOPY_P}" "${PV}"
}
install_nvidia_usr_components() {
local libdir=$(get_libdir)
local skip_types=(
SYSTEMD_UNIT_SYMLINK
NVIDIA_MODPROBE.\*
MANPAGE
INTERNAL_UTILITY.\*
XMODULE_SHARED_LIB
UTILITY_BIN_SYMLINK
)
# mimic nvidia-installer by reading .manifest to install files
# 0:file 1:perms 2:type 3+:subtype/arguments -:module
local m into
while IFS=' ' read -ra m; do
! [[ ${#m[@]} -ge 2 && ${m[-1]} =~ MODULE: ]] ||
[[ " ${m[2]}" =~ ^(\ ${skip_types[*]/%/|\\} )$ ]] ||
[[ ${m[0]} =~ nvngx.dll ]] && continue
case ${m[2]} in
GBM_BACKEND_LIB_SYMLINK) m[4]=../${m[4]};; # missing ../
VDPAU_SYMLINK) m[4]=vdpau/; m[5]=${m[5]#vdpau/};; # .so to vdpau/
GLX_MODULE_SYMLINK) m[4]=../${m[4]};; # missing ../
esac
if [[ ${m[3]} == COMPAT32 ]]; then
continue
elif [[ ${m[2]} =~ GBM_BACKEND_LIB_SYMLINK ]]; then
into=/opt/nvidia/${PV}/${libdir}/gbm
elif [[ ${m[2]} =~ _BINARY ]]; then
into=/opt/nvidia/${PV}/bin
elif [[ ${m[2]} =~ _LIB$|_SYMLINK$ ]]; then
into=/opt/nvidia/${PV}/${libdir}
else
continue
fi
[[ ${m[3]: -2} == ?/ ]] && into+=/${m[3]%/}
[[ ${m[4]: -2} == ?/ ]] && into+=/${m[4]%/}
if [[ ${m[2]} =~ _SYMLINK$ ]]; then
[[ ${m[4]: -1} == / ]] && m[4]=${m[5]}
dosym ${m[4]} ${into}/${m[0]}
continue
fi
[[ ${m[0]} =~ ^libnvidia-ngx.so|^libnvidia-egl-gbm.so ]] &&
dosym ${m[0]} ${into}/${m[0]%.so*}.so.1 # soname not in .manifest
printf -v m[1] %o $((m[1] | 0200)) # 444->644
insopts -m${m[1]}
insinto ${into}
doins ${m[0]}
done < .manifest || die
dosym nvidia-installer /opt/nvidia/${PV}/bin/nvidia-uninstall
insopts -m4755
insinto /opt/nvidia/${PV}/bin/
doins nvidia-modprobe
# Add Nvidia library path to /etc/ld.so.conf
echo "/opt/nvidia/${PV}/lib64" > nvidia.conf
insinto /etc/ld.so.conf.d
doins nvidia.conf
}
src_install() {
if use install-nvidia-usr; then
install_nvidia_usr_components
fi
if use module_sign ; then
TMP_DIR=$(mktemp -d)
DRIVERS_DIR="${TMP_DIR}/drivers"
FIRMWARE_DIR="${TMP_DIR}/firmware/nvidia/${PV}"
mkdir -p "${DRIVERS_DIR}"
mkdir -p "${FIRMWARE_DIR}"
# Sign and install NVIDIA Kernel Modules
local nvidia_module_objects=(
nvidia.ko
nvidia-drm.ko
nvidia-modeset.ko
nvidia-peermem.ko
nvidia-uvm.ko
)
cos-linux-artifact-sign_and_install \
"NVIDIA modules" \
"kernel-module-source/kernel-open" \
"${DRIVERS_DIR}" \
"module" \
"${nvidia_module_objects[@]}"
# Sign and install GDRCopy Kernel Module
local gdr_build_dir="${GDRCOPY_P}/src/gdrdrv"
local gdrcopy_module_objects=(
gdrdrv.ko
nv-p2p-dummy.ko
)
cos-linux-artifact-sign_and_install \
"GDRCopy modules" \
"${gdr_build_dir}" \
"${DRIVERS_DIR}" \
"module" \
"${gdrcopy_module_objects[@]}"
# Sign and install NVIDIA Firmware
local firmware_objects=(
gsp_tu10x.bin
gsp_ga10x.bin
)
cos-linux-artifact-sign_and_install \
"NVIDIA GSP firmware" \
"${INSTALLER_NAME}/firmware" \
"${FIRMWARE_DIR}" \
"firmware" \
"${firmware_objects[@]}"
# Create the final unified artifact
einfo "Creating final driver and firmware tarball..."
local source_dir=opt/google/drivers
dodir ${source_dir}
tar --xattrs --xattrs-include=* -czf "${D}/${source_dir}/nvidia-drivers-${PV}.tgz" -C "${TMP_DIR}"/ . || die "Tarball creation failed"
rm -rf "${TMP_DIR}"
fi
}