distribution/packages/sysutils/busybox/scripts/getedid
2022-02-05 09:23:32 -05:00

256 lines
6.9 KiB
Bash
Executable file

#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
#
# exit 1 = unsupported GPU
# exit 2 = dual boot system
# exit 3 = no backup for syslinux.cfg or extlinux.conf
# exit 4 = extlinux.conf and syslinux.cfg are available
# exit 5 = changes are already made either to extlinux.conf or syslinux.cfg
# exit 6 = xorg.conf already exists in /storage/.config
# exit 7 = more than a single device detected
# Help message and usage explanation
help() {
echo "This script generates a custom EDID depending on your GPU"
echo ""
echo "To check which GPU you are using, use: getedid gpu"
echo ""
echo "To create a custom EDID, just use this script like: getedid create"
echo ""
echo "If you don't want to use the created EDID file anymore use: getedid delete"
echo ""
echo "If your hardware or kernel has changed and you want to have a custom EDID again, then you have to delete the old EDID first."
echo "For this use: getedid delete "
echo "And then use: getedid create"
}
# check for GPU and store string
check_gpu() {
if lspci | grep -i vga | grep -i -q -E 'intel|amd' ; then
gpu="intel/amd"
elif lspci | grep -i vga | grep -i -q nvidia; then
gpu="nvidia"
else
echo "GPU is not supported"
exit 1
fi
}
# run this first if the user already has a custom EDID but want to create a new one (TV or AVR change)
del_edid() {
if [ "$gpu" = "intel/amd" ]; then
check_file
if [ -f "$file".old ]; then
mount_rw
rm "$file"
mv "$file".old "$file"
rm -f /flash/edid.cpio
mount_ro
sys_reboot
else
echo "You don't have a backup file for $file. You did not use this script to create the custom EDID"
echo "Therefore we can't be sure the script is working properly. Exiting"
exit 3
fi
else
rm -f /storage/.config/xorg.conf
rm -f /storage/.config/xorg.le.backup
systemctl restart xorg.service
fi
}
# run main script depending on the GPU
run() {
if [ "$gpu" = "intel/amd" ]; then
intel_amd
elif [ "$gpu" = "nvidia" ]; then
nvidia
fi
}
# mounting /flash to rw
mount_rw() {
mount -o remount,rw /flash
}
# mounting /flash to ro
mount_ro() {
mount -o remount,ro /flash
}
# remount /flash to ro and reboot
sys_reboot() {
mount_ro
echo "The system is rebooting in 15 seconds"
sleep 15
reboot
}
# check syslinux.cfg and/or extlinux.conf
check_file() {
# check boot system
if [ -d /sys/firmware/efi -a -f /flash/EFI/BOOT/syslinux.cfg ] ; then
sys_boot="UEFI"
sys_path="/flash/EFI/BOOT"
else
sys_boot="BIOS"
sys_path="/flash"
fi
# check which file is available
if [ -f "$sys_path/syslinux.cfg" -a -f "$sys_path/extlinux.conf" ]; then
echo "Your system contains both a /flash/syslinux.cfg and a /flash/extlinux.conf file"
echo "Something is wrong on your system. Exiting"
exit 4
elif [ -f "$sys_path/extlinux.conf" ]; then
file="$sys_path/extlinux.conf"
elif [ -f "$sys_path/syslinux.cfg" ]; then
file="$sys_path/syslinux.cfg"
else
echo "You neither have a extlinux.conf nor do you have a syslinux.cfg."
echo "Dual boot systems aren't supported"
exit 2
fi
}
check_content() {
# check if changes are already made to $file and exit if yes
if grep -q "initrd=/edid.cpio" $file ; then
echo "$file has been modified. Please run 'getedid delete' first if you want to modify it again. Exiting."
exit 5
fi
}
check_kernel() {
# determine which kernel is in use and store it in a compareable format. This will probably be deprecated for LE10
kernel="$(uname -r | sed 's/[^0-9\.].*//g' | awk -F. '{ printf "%d%02d%03d\n",int($1),int($2),int($3) }')"
}
create_edid() {
# create edid
mkdir -p /tmp/cpio/lib/firmware/edid
cat "/sys/class/drm/$card/edid" > /tmp/cpio/lib/firmware/edid/edid.bin
mkdir -p /storage/.config/firmware/edid
cp /tmp/cpio/lib/firmware/edid/edid.bin /storage/.config/firmware/edid
# create cpio archive
cd /tmp/cpio/
find . -print | cpio -ov -H newc > /storage/edid.cpio
}
intel_amd() {
# check which output is connnected:
counter=0
for i in /sys/class/drm/*; do
if [ "$(cat "$i"/status 2>/dev/null)" = "connected" ]; then
counter=$((counter + 1))
if [ $counter -gt 0 -a $counter -lt 2 ]; then
card="$(echo "$i" | cut -d / -f 5)"
hdmi="$(echo "$i" | cut -d / -f 5 | sed 's/card[0-9]-//g')"
else
echo "More than a single device connected. Probably enable \"Disable all other monitors\" at Kodi settings. Aborting!"
exit 7
fi
fi
done
# create the edid
create_edid
# check extlinux.conf and syslinux.cfg
check_file
check_content
# remount /flash to rw
mount_rw
mv /storage/edid.cpio /flash
# make a backup of $file
cp "$file" "$file".old
#check kernel version
check_kernel
# add boot parameters to $file
sed -i "/ APPEND/s/$/ initrd=\/edid.cpio drm.edid_firmware=edid\/edid.bin video=$hdmi:D/" "$file"
# reboot
sys_reboot
}
nvidia() {
# check if xorg.conf already exists
if [ -f /storage/.config/xorg.conf -o -f /storage/.config/xorg-nvidia.conf ]; then
echo "Existing /storage/.config/xorg.conf detected. Aborting!"
exit 6
fi
# check for multi-montior setup
monitors="$(grep -i -w "connected" /var/log/Xorg.0.log | grep -i -o "dfp-[0-9]" | sort -u | wc -l)"
if [ "$monitors" -gt "1" ]; then
echo "You have more than a single monitor connected. The script doesn't support a multi-monitor setup. Aborting!"
exit 7
fi
# set debug and restart Xorg
cp /etc/X11/xorg-nvidia.conf /storage/.config/xorg.conf
sed -i 's/"ModeDebug" "false"/"ModeDebug" "true"/g' /storage/.config/xorg.conf
systemctl restart xorg.service
# get port
nv_port="$(grep -i -w connected /var/log/Xorg.0.log | grep -i -o "dfp-[0-9]" | sort -u)"
nvidia-xconfig --extract-edids-from-file=/var/log/Xorg.0.log --extract-edids-output-file=/storage/.config/edid.bin 1>/dev/null
# set mode debug back to false
sed -i 's/"ModeDebug" "true"/"ModeDebug" "false"/g' /storage/.config/xorg.conf
# set port and uncomment lines
sed -i "s/# Option \"ConnectedMonitor\" \"DFP-0\"/ Option \"ConnectedMonitor\" \"$nv_port\"/g" /storage/.config/xorg.conf
sed -i "s/# Option \"CustomEDID\" \"DFP-0:\/storage\/.config\/edid.bin\"/ Option \"CustomEDID\" \"$nv_port:\/storage\/.config\/edid.bin\"/g" /storage/.config/xorg.conf
sed -i "s/# Option \"IgnoreEDID\" \"false\"/ Option \"IgnoreEDID\" \"false\"/g" /storage/.config/xorg.conf
sed -i "s/# Option \"UseEDID\" \"true\"/ Option \"UseEDID\" \"true\"/g" /storage/.config/xorg.conf
# restart xorg.service
systemctl restart xorg.service
}
# start script from here
case "$1" in
'create')
check_gpu
run
;;
'gpu')
check_gpu
echo "$gpu"
;;
'delete')
check_gpu
del_edid
;;
'help')
help
;;
*)
echo "Usage $0 { create | gpu | delete | help }"
;;
esac