#!/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