mirror of
https://github.com/pentoo/pentoo-overlay
synced 2026-02-10 09:23:10 +01:00
359 lines
11 KiB
Text
359 lines
11 KiB
Text
#!/sbin/openrc-run
|
|
#seriously, fuck you AMD and Nvidia. Write a sane license that permits redistribution, we just want your shitty hardware to work
|
|
|
|
extra_commands="aufs_module"
|
|
|
|
depend() {
|
|
before xdm
|
|
}
|
|
|
|
start() {
|
|
BLACKLIST_FILE="/etc/modprobe.d/blacklist.conf"
|
|
|
|
blacklist() {
|
|
grep -q "${1}" "${BLACKLIST_FILE}" || \
|
|
echo "blacklist ${1}" >> "${BLACKLIST_FILE}"
|
|
}
|
|
|
|
unblacklist() {
|
|
sed -i "/${1}/d" "${BLACKLIST_FILE}"
|
|
}
|
|
|
|
handle_pax() {
|
|
if [ $(command -v paxctl-ng 2> /dev/null) ]; then
|
|
paxctl-ng -m /usr/bin/X || eerror "Unable to pax-mark /usr/bin/X"
|
|
fi
|
|
}
|
|
|
|
switch_to_nvidia() {
|
|
#remove oss
|
|
if $(lsmod | grep -iq nouveau) ; then
|
|
modprobe -r nouveau || eerror "Unable to unload nouveau driver."
|
|
fi
|
|
|
|
if [ ! -f /lib/modules/$(uname -r)/video/nvidia.ko ]; then
|
|
einfo "Building evil binary nvidia driver..."
|
|
eval ${run_merge} --nodeps nvidia-drivers
|
|
fi
|
|
|
|
modprobe nvidia || NVIDIA_FAILURE=yes
|
|
if [ "${NVIDIA_FAILURE}" = "yes" ]; then
|
|
eerror "Nvidia binary driver failed to load, something went wrong."
|
|
if $(lspci -d8086: | grep -q VGA); then
|
|
eerror "Intel detected, crossing fingers and continuing without a working nvidia driver"
|
|
else
|
|
eerror "Falling back to open source nouveau driver..."
|
|
switch_to_nouveau
|
|
fi
|
|
else
|
|
einfo "Enabling evil binary nvidia driver..."
|
|
#blacklist the open drivers
|
|
#check for nvidia in the blacklist and remove it
|
|
unblacklist nvidia
|
|
#check for nouveau in the blacklist and add it
|
|
blacklist nouveau
|
|
#fix pax flags for hardened
|
|
handle_pax
|
|
fi
|
|
|
|
#check for intel gpu
|
|
if $(lspci -d8086: | grep -q VGA); then
|
|
ewarn "nvidia and intel are both detected, using intel for video"
|
|
eend 0
|
|
elif [ "${NVIDIA_FAILURE}" != "yes" ]; then
|
|
/opt/bin/nvidia-xconfig
|
|
#eselect opengl set nvidia
|
|
[ "$(eselect opengl show)" != "xorg-x11" ] && eselect opengl set xorg-x11
|
|
eselect opencl set nvidia
|
|
einfo "Enabled evil NVIDIA binary GPU driver"
|
|
eend 0
|
|
fi
|
|
}
|
|
|
|
switch_to_nouveau() {
|
|
modprobe nouveau || NOUVEAU_FAILURE=yes
|
|
if [ "${NOUVEAU_FAILURE}" = "yes" ] && [ "${NVIDIA_FAILURE}" = "yes" ]; then
|
|
eerror "Both nvidia binary driver and open source nouveau both failed to load, something went wrong. Please report this"
|
|
eend 1
|
|
elif [ "${NOUVEAU_FAILURE}" = "yes" ]; then
|
|
eerror "Nouveau driver failed to load, something went wrong. Please try the binary nvidia driver."
|
|
eend 1
|
|
else
|
|
einfo "Enabling open source nouveau driver..."
|
|
#blacklist the binary drivers
|
|
#check for nouveau in the blacklist and remove it
|
|
unblacklist nouveau
|
|
#check for nvidia in the blacklist and add it
|
|
blacklist nvidia
|
|
eend 0
|
|
fi
|
|
}
|
|
|
|
handle_nvidia() {
|
|
einfo "Detected: nvidia gpu, please stand by..."
|
|
if [ "${NOBINDRIVERS}" = 1 ]; then
|
|
|
|
#remove the binary driver and insert oss
|
|
if $(lsmod | grep -iq nvidia) ; then
|
|
modprobe -r nvidia || eerror "Unable to unload nvidia driver."
|
|
fi
|
|
if $(lspci -d8086: | grep -q VGA); then
|
|
ewarn "Intel GPU detected, if you wish to use nouveau please disable optimus or manually setup bumblebee."
|
|
einfo "Using Intel GPU."
|
|
eend 0
|
|
else
|
|
switch_to_nouveau
|
|
fi
|
|
else
|
|
#first we detect if the nvidia binary driver can actually support the hardware
|
|
NV_TARBALL="$(FETCHCOMMAND="false" RESUMECOMMAND="false" emerge --color=n -f nvidia-drivers --nodeps 2> /dev/zero | \
|
|
grep "run BLAKE2B SHA512 size ;-) ..." | awk '{print $2}')"
|
|
|
|
if [ -n "${NV_TARBALL}" ]; then
|
|
cd $(mktemp -d -t nvidia-detectXXXX)
|
|
|
|
#stolen from unpacker.eclass
|
|
exe="tail -n +$(grep -a '^skip=' "$(portageq envvar DISTDIR)/${NV_TARBALL}" | cut -d= -f2) '$(portageq envvar DISTDIR)/${NV_TARBALL}'"
|
|
eval ${exe} | unxz -d | tar --no-same-owner -xf - --wildcards --no-anchored 'README.txt'
|
|
|
|
if [ -f README.txt ]; then
|
|
#stolen from debian's nvidia-detect rules file
|
|
#https://packages.debian.org/source/sid/nvidia-graphics-drivers
|
|
sed -e '0,/A. Supported\|APPENDIX A: SUPPORTED/d' \
|
|
-e '0,/Appendix A. Supported\|APPENDIX A: SUPPORTED/d' \
|
|
-e '0,/^Below\|APPENDIX B/{/ 0x/s/.* 0x\([0-9a-fA-F]\{4\}\).*/10de\1/p; /^.\{41\} [0-9a-fA-F]\{4\} /s/^.\{41\} \([0-9a-fA-F]\{4\}\) .*/10de\1/p};d' \
|
|
README.txt \
|
|
| tr a-f A-F | sort -u > list.txt
|
|
|
|
if [ -f list.txt ]; then
|
|
#stolen from nvidia-detect code
|
|
NVIDIA_VGA=$(sudo lspci -mmn -d 10de: | awk '{ gsub("\"",""); print $3 $4 }')
|
|
|
|
for pciid in ${NVIDIA_VGA^^}
|
|
do
|
|
if $(grep -q ${pciid} list.txt) ; then
|
|
NVIDIA_SUPPORTED=1
|
|
fi
|
|
done
|
|
if [ "${NVIDIA_SUPPORTED}" = "1" ]; then
|
|
switch_to_nvidia
|
|
else
|
|
eerror "NVIDIA binary driver requested but doesn't support this hardware, trying nouveau"
|
|
switch_to_nouveau
|
|
fi
|
|
else
|
|
eerror "Failed to extract or sort PCIIDs from NVIDIA README.txt, please report this."
|
|
eend 1
|
|
fi
|
|
else
|
|
eerror "Failed to unpack README from NVIDIA drivers, please report this."
|
|
eend 1
|
|
fi
|
|
|
|
else
|
|
eerror "Missing nvidia-drivers distfile, please download it first or run \"/etc/init.d/binary-driver-handler aufs-module\""
|
|
eerror "before making the livecd to create an aufs-module which contains the needed distfiles."
|
|
eend 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
switch_to_fglrx() {
|
|
#remove oss
|
|
if $(lsmod | grep -iq radeon) ; then
|
|
modprobe -r radeon || eerror "Unable to unload radeon"
|
|
fi
|
|
|
|
if [ ! -f /lib/modules/$(uname -r)/video/fglrx.ko ]; then
|
|
einfo "Building evil binary AMD driver..."
|
|
eval ${run_merge} --nodeps ati-drivers
|
|
fi
|
|
modprobe fglrx || FGLRX_FAILURE=yes
|
|
if [ "${FGLRX_FAILURE}" = "yes" ]; then
|
|
eerror "FGLRX binary driver failed to load, something went wrong. Falling back to open source radeon driver."
|
|
switch_to_radeon
|
|
else
|
|
einfo "Enabling evil binary ati driver..."
|
|
#blacklist the open drivers
|
|
#check for fglrx in the blacklist and remove it
|
|
unblacklist fglrx
|
|
#check for radeon in the blacklist and add it
|
|
blacklist radeon
|
|
#fix pax flags for hardened
|
|
handle_pax
|
|
|
|
/opt/bin/aticonfig --initial
|
|
#eselect opengl set ati
|
|
[ "$(eselect opengl show)" != "xorg-x11" ] && eselect opengl set xorg-x11
|
|
eselect opencl set amd
|
|
einfo "Successfully switched to AMD binary GPU driver"
|
|
eend 0
|
|
fi
|
|
}
|
|
|
|
switch_to_radeon() {
|
|
#remove binary and insert oss
|
|
if $(lsmod | grep -iq radeon) ; then
|
|
modprobe -r fglrx || eerror "Unable to unload fglrx."
|
|
fi
|
|
modprobe radeon || RADEON_FAILURE=yes
|
|
if [ "${RADEON_FAILURE}" = "yes" ] && [ "${FGLRX_FAILURE}" = "yes" ]; then
|
|
eerror "Both FGLRX binary driver and open source radeon driver failed. Please report this."
|
|
eend 1
|
|
elif [ "${RADEON_FAILURE}" = "yes" ]; then
|
|
eerror "Radeon driver failed to load, something went wrong. Please try the binary drivers."
|
|
eend 1
|
|
else
|
|
einfo "Enabling open source radeon driver..."
|
|
#blacklist the binary driver
|
|
#check for radeon in the blacklist and remove it
|
|
unblacklist radeon
|
|
#check for fglrx in the blacklist and add it
|
|
blacklist fglrx
|
|
eend 0
|
|
fi
|
|
}
|
|
|
|
handle_amd() {
|
|
einfo "Detected: amd gpu, please stand by..."
|
|
if [ "${NOBINDRIVERS}" = 1 ]; then
|
|
switch_to_radeon
|
|
else
|
|
if [ "$(uname -m)" = "x86_64" ]; then
|
|
amd_dcm="amd_dcm64"
|
|
elif [ "$(uname -m)" = "x86" ]; then
|
|
amd_dcm="amd_dcm32"
|
|
else
|
|
eerror "Unsupported arch."
|
|
fi
|
|
|
|
ATI_TARBALL="$(FETCHCOMMAND="false" RESUMECOMMAND="false" emerge --color=n -f ati-drivers --nodeps 2> /dev/zero | \
|
|
grep "BLAKE2B SHA512 size ;-) ..." | awk '{print $2}' | head -n1)"
|
|
|
|
if [ -n "${ATI_TARBALL}" ]; then
|
|
cd $(mktemp -d -t ati-detectXXXX)
|
|
|
|
unzip -p "$(portageq envvar DISTDIR)/${ATI_TARBALL}" fglrx*/amd-driver-installer-*.run > amd-driver-installer.run
|
|
chmod +x amd-driver-installer.run
|
|
./amd-driver-installer.run --extract ati-drivers
|
|
|
|
if [ -f ati-drivers/"${amd_dcm}" ]; then
|
|
cd ati-drivers
|
|
AMD_DCM_OUTPUT="$(./${amd_dcm} 2>&1)"
|
|
if [ "${AMD_DCM_OUTPUT}" = "Supported adapter detected." ]; then
|
|
switch_to_fglrx
|
|
elif [ "${AMD_DCM_OUTPUT}" = "./${amd_dcm}: No supported adapters detected" ]; then
|
|
eerror "User requested binary fglrx but there is no supported hardware present."
|
|
eerror "Falling back to OSS radeon driver."
|
|
switch_to_radeon
|
|
else
|
|
eerror "${amd_dcm} output is not as expected, please report this."
|
|
fi
|
|
else
|
|
eerror "Failed to unpack ${amd_dcm} from ati-drivers, please report this."
|
|
eend 1
|
|
fi
|
|
|
|
else
|
|
eerror "Missing ati-drivers distfile, please download it first or run \"/etc/init.d/binary-driver-handler aufs-module\""
|
|
eerror "before making the livecd to create an aufs-module which contains the needed distfiles."
|
|
eend 1
|
|
fi
|
|
|
|
fi
|
|
}
|
|
|
|
handle_broadcom() {
|
|
if [ "${NOBINDRIVERS}" = 1 ]; then
|
|
einfo "Broadcom wifi devices detected but nobindrivers on command line prevents installing firmware automatically."
|
|
return
|
|
fi
|
|
BROADCOM_READY=""
|
|
for mod in ${BROADCOM_DETECTED}; do
|
|
einfo "Detected: ${mod} hardware, please stand by..."
|
|
TEST_FILE=""
|
|
TEST_FILE="$(FETCHCOMMAND="false" RESUMECOMMAND="false" emerge --color=n -f ${mod}-firmware --nodeps 2> /dev/zero | \
|
|
grep "BLAKE2B SHA512 size ;-) ..." | awk '{print $2}' | head -n1)"
|
|
if [ -n "${TEST_FILE}" ]; then
|
|
BROADCOM_READY="${BROADCOM_READY} ${mod}-firmware"
|
|
else
|
|
eerror "Missing distfile for ${mod}-firmware"
|
|
fi
|
|
done
|
|
if eval ${run_merge} --nodeps ${BROADCOM_READY}; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
#parse kernel commandline to see what we are doing
|
|
if grep -q nobindrivers /proc/cmdline; then
|
|
NOBINDRIVERS=1
|
|
else
|
|
NOBINDRIVERS=0
|
|
fi
|
|
|
|
#check environment to see if we can make modules or not
|
|
if [ -w /mnt/cdrom/modules ] && [ -x /usr/sbin/makemo ]; then
|
|
run_merge="echo y | makemo"
|
|
else
|
|
run_merge="emerge"
|
|
fi
|
|
|
|
ebegin "Setting up broadcom firmware if needed..."
|
|
BROADCOM_DETECTED=""
|
|
for mod in b43 b43legacy; do
|
|
if grep -Eq "^${mod} " /proc/modules; then
|
|
if [ ! -d /lib/firmware/${mod} ]; then
|
|
BROADCOM_DETECTED="${BROADCOM_DETECTED} ${mod}"
|
|
else
|
|
einfo "${mod}-firmware appears to already be installed, skipping"
|
|
fi
|
|
fi
|
|
done
|
|
if [ -n "${BROADCOM_DETECTED}" ]; then
|
|
if handle_broadcom; then
|
|
eend 0
|
|
else
|
|
eend "Something went wrong"
|
|
fi
|
|
fi
|
|
|
|
if grep -q notouchyvideo /proc/cmdline; then
|
|
ebegin "Skipping video drivers by request"
|
|
eend 0
|
|
else
|
|
ebegin "Setting up GPU drivers requested by user, this may take a few minutes"
|
|
|
|
#check for nvidia GPU
|
|
#lspci | grep -iq "VGA.*NVIDIA"
|
|
if $(lspci -d10de: | grep -qE 'VGA|3D controller'); then
|
|
handle_nvidia
|
|
#check for AMD GPU
|
|
#lspci | grep -iq "VGA.*Radeon"
|
|
#elif $(lspci -d1002: | grep -q VGA); then
|
|
# handle_amd
|
|
else
|
|
[ "$(eselect opengl show)" != "xorg-x11" ] && eselect opengl set xorg-x11
|
|
fi
|
|
eend 0
|
|
fi
|
|
}
|
|
|
|
aufs_module() {
|
|
ebegin "Making aufs module with needed distfiles for binary drivers"
|
|
#temp dir
|
|
T="/dev/shm"
|
|
#target dir
|
|
DEST=/usr/src/pentoo/livecd/trunk/isoroot/modules
|
|
|
|
mkdir -p "${T}"/distfiles/rootfs/usr/portage/distfiles/
|
|
DISTDIR="${T}"/distfiles/ emerge -FO ati-drivers
|
|
DISTDIR="${T}"/dev/shm/distfiles/ emerge -FO nvidia-drivers
|
|
cp "${T}"/distfiles/{*[Ll]inux*,xvba*} "${T}"/distfiles/rootfs/usr/portage/distfiles
|
|
chown portage.portage -R "${T}"/distfiles/rootfs/usr/portage
|
|
mksquashfs "${T}"/distfiles/rootfs/ "${DEST}"/zdistfiles-`date "+%Y%m%d"`.lzm -comp xz -b 1048576 -Xdict-size 1048576 -no-recovery -noappend
|
|
|
|
eend 0
|
|
}
|