#!/bin/bash function install_dependencies() { echo "Installing dependencies..." sudo apt -qq update sudo apt -qq install -y curl git wget sudo apt -qq install -y bison flex kernel-package libelf-dev libssl-dev } function init() { echo "Initializing..." kernel_config=$(ls /boot/config-* | grep generic | sort -Vr | head -n 1) grub_config="/etc/default/grub" current_dir=$(pwd) working_dir=$(mktemp -d) cd "${working_dir}" || exit install_dependencies } function get_newest_versions() { echo "Retrieving newest version information..." stable_releases_3x_url="https://mirrors.edge.kernel.org/pub/linux/kernel/v3.x/" stable_releases_4x_url="https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/" stable_releases_5x_url="https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/" stable_releases_3x_html=$(curl -s "${stable_releases_3x_url}") stable_releases_4x_html=$(curl -s "${stable_releases_4x_url}") stable_releases_5x_html=$(curl -s "${stable_releases_5x_url}") stable_releases_combined_html="${stable_releases_3x_html}${stable_releases_4x_html}${stable_releases_5x_html}" stable_version=$(echo "${stable_releases_combined_html}" | grep -E -o 'linux-([0-9]{1,}\.)+[0-9]{1,}' | sort -Vru | head -n 1 | cut -d '-' -f 2) mainline_link=$(curl -s https://www.kernel.org/ | grep https://git.kernel.org/torvalds/t/linux- | grep -Po '(?<=href=")[^"]*') if ! [ -z "${mainline_link}" ] then mainline_version=$(echo "${mainline_link}" | cut -d '-' -f 2,3 | cut -d '.' -f 1,2) else mainline_version="unavailable" fi repo_pkg=$(apt search 'linux-source-' | grep 'linux-source' | cut -d '/' -f 1 | awk -F- 'NF<=3' | sort -Vr | head -n 1) #repo_version=$(echo "${repo_pkg}" | cut -d '-' -f 3) repo_version=$(apt search 'linux-source-' | grep 'linux-source' | sort -Vr | head -n 1 | cut -d ' ' -f 2) } function stable_or_mainline_or_repo() { get_newest_versions echo "Newest stable version is: ${stable_version}" echo "Mainline version is: ${mainline_version}" echo "Repository version is: ${repo_version}" echo -n "Do you want to get a [s]table, the newest [m]ainline release candidate or the newest kernel from your [r]epositories? [S/m/r] " read -r s_or_m_or_r echo -n "Do you want to apply the acs override patch? Kernels below 4.10 are not supported. [Y/n] " read -r acso echo -n "Do you want to apply the experimental AMD AGESA patch to fix VFIO setups on AGESA 0.0.7.2 and newer? [y/N] " read -r agesa echo -n "Do you want to apply the experimental AMD Vega PCI reset patch? [y/N] " read -r vega echo -n "Do you want to install the kernel and its headers after compilation? [Y/n] " read -r install if [ -z "${install}" ] || [ "${install}" == "y" ] then echo -n "Do you want to make this kernel the new default? [Y/n] " read -r default fi if [ -z "${s_or_m_or_r}" ] || [ "${s_or_m_or_r}" == "s" ] then stable_preparations else if [ "${s_or_m_or_r}" == "m" ] then if [ "${mainline_version}" == "unavailable" ] then echo "Mainline version currently unavailable. Exiting." exit else mainline_preparations fi else if [ "${s_or_m_or_r}" == "r" ] then repo_preparations else echo "Not a valid option. Exiting." exit fi fi fi } function try_acso_patch() { acso_patch_5_6_12="https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/5.6.12/acso.patch" acso_patch_5_4="https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/5.4/acso.patch" acso_patch_4_18="https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/4.18/acso.patch" acso_patch_4_17="https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/4.17/acso.patch" acso_patch_4_14="https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/4.14/acso.patch" acso_patch_4_10="https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/4.10/acso.patch" acso_patch_4_18_ubuntu="https://gist.github.com/mdPlusPlus/bb3df6248ffc7c6b3772ae0901659966/raw/acso_4_18_ubuntu.patch" echo "Trying to apply acs override patch for 5.6.12+." wget -O ../acso_5_6_12.patch "${acso_patch_5_6_12}" if $(git apply --check ../acso_5_6_12.patch) then echo "Applying acs override patch for 5.6_12+." git apply ../acso_5_4.patch else echo "Trying to apply acs override patch for 5.4+." wget -O ../acso_5_4.patch "${acso_patch_5_4}" if $(git apply --check ../acso_5_4.patch) then echo "Applying acs override patch for 5.4+." git apply ../acso_5_4.patch else echo "Trying to apply acs override patch for 4.18+." wget -O ../acso_4_18.patch "${acso_patch_4_18}" if $(git apply --check ../acso_4_18.patch) then echo "Applying acs override patch for 4.18+." git apply ../acso_4_18.patch else echo "Trying to apply acs override patch for 4.17+." wget -O ../acso_4_17.patch "${acso_patch_4_17}" if $(git apply --check ../acso_4_17.patch) then echo "Applying acs override patch for 4.17+." git apply ../acso_4_17.patch else echo "Trying to apply acs override patch for 4.14+." wget -O ../acso_4_14.patch "${acso_patch_4_14}" if $(git apply --check ../acso_4_14.patch) then echo "Applying acs override patch for 4.14+." git apply ../acso_4_14.patch else echo "Trying to apply acs override patch for 4.10+." wget -O ../acso_4_10.patch "${acso_patch_4_10}" if $(git apply --check ../acso_4_10.patch) then echo "Applying acs override patch for 4.10+." git apply ../acso_4_10.patch else echo "Last resort: Trying to apply acs override patch for Ubuntu repository kernel source." wget -O ../acso_4_18_ubuntu.patch "${acso_patch_4_18_ubuntu}" if $(git apply --check ../acso_4_18_ubuntu.patch) then echo "Applying acs override patch for Ubuntu repository kernel source." git apply ../acso_4_18_ubuntu.patch else echo "[ERROR]: Failed to apply acs override patch. Exiting." exit fi rm -f ../acso_4_18_ubuntu.patch fi rm -f ../acso_4_10.patch fi rm -f ../acso_4_14.patch fi rm -f ../acso_4_17.patch fi rm -f ../acso_4_18.patch fi rm -f ../acso_5_4.patch fi rm -f ../acso_5_6_12.patch kernel_localversion+="-acso" } function try_agesa_patch() { ##by reddit user https://www.reddit.com/user/hansmoman/ ##https://www.reddit.com/r/VFIO/comments/bqeixd/apparently_the_latest_bios_on_asrockmsi_boards/eo4neta agesa_patch="https://clbin.com/VCiYJ" agesa_patch_filename="agesa.patch" echo "Trying to apply AMD AGESA patch." wget -O ../${agesa_patch_filename} "${agesa_patch}" if $(git apply --check ../${agesa_patch_filename}) then echo "Applying AMD AGESA patch." git apply ../${agesa_patch_filename} else echo "[ERROR]: Failed to apply AMD AGESA patch. Exiting." exit fi rm -f ../${agesa_patch_filename} kernel_localversion+="-agesa" } function try_vega_patch() { ##Original by github user https://gist.github.com/numinit vega_patch_new="https://gist.github.com/mdPlusPlus/1754d82b53269ead770133829874fbfd/raw/" vega_patch="https://gist.github.com/numinit/1bbabff521e0451e5470d740e0eb82fd/raw" vega_patch_filename="fix-vega-reset.patch" echo "Trying to apply AMD Vega reset patch." wget -O ../${vega_patch_filename} "${vega_patch_new}" if $(git apply --check ../${vega_patch_filename}) then echo "Applying AMD Vega reset patch." git apply ../${vega_patch_filename} else rm -f ../${vega_patch_filename} wget -O ../${vega_patch_filename} "${vega_patch}" if $(git apply --check ../${vega_patch_filename}) then echo "Applying AMD Vega reset patch." git apply ../${vega_patch_filename} else echo "[ERROR]: Failed to apply AMD Vega reset patch. Exiting." exit fi fi rm -f ../${vega_patch_filename} kernel_localversion+="-vega" } function stable_preparations() { echo "The newest available stable kernel version is ${stable_version}. Kernels below 4.10 are not supported." echo -n "Which version do you want to download? [${stable_version}] " read -r user_version if ! [ -z "${user_version}" ] then stable_version="${user_version}" fi kernel_version="${stable_version}" kernel_name="linux-${kernel_version}" ##Test whether the version string starts with 3, 4, or 5 and sets the URL accordingly if [[ $stable_version == 5* ]] then stable_link="${stable_releases_5x_url}linux-${stable_version}.tar.xz" else if [[ $stable_version == 4* ]] then stable_link="${stable_releases_4x_url}linux-${stable_version}.tar.xz" else if [[ $stable_version == 3* ]] then stable_link="${stable_releases_3x_url}linux-${stable_version}.tar.xz" else echo "${stable_version} is not a vaild version number. Exiting." exit fi fi fi wget "${stable_link}" tar xf "${kernel_name}.tar.xz" cd "${kernel_name}" || exit independent_code } function mainline_preparations() { kernel_version="${mainline_version}" kernel_name="linux-${kernel_version}" wget "${mainline_link}" tar xf "${kernel_name}.tar.gz" cd "${kernel_name}" || exit independent_code } function repo_preparations() { kernel_name="${repo_pkg}" sudo apt install "${repo_pkg}" tar xf "/usr/src/${kernel_name}.tar.bz2" cd "${kernel_name}" || exit makefile_version=$(grep "^VERSION" Makefile | tr -d '[:space:]' | cut -d '=' -f 2) makefile_patchlevel=$(grep "^PATCHLEVEL" Makefile| tr -d '[:space:]' | cut -d '=' -f 2) makefile_sublevel=$(grep "^SUBLEVEL" Makefile | tr -d '[:space:]' | cut -d '=' -f 2) #makefile_extraversion=$(grep "^EXTRAVERSION" Makefile| tr -d '[:space:]' | cut -d '=' -f 2) if ! [ -z "${makefile_version}" ] then kernel_version="${makefile_version}" if ! [ -z "${makefile_patchlevel}" ] then kernel_version="${makefile_version}.${makefile_patchlevel}" if ! [ -z "${makefile_sublevel}" ] then kernel_version="${makefile_version}.${makefile_patchlevel}.${makefile_sublevel}" fi fi fi ##linux-hwe (5.0.0-25.26~18.04.1) bionic; urgency=medium ##-> ##5.0.0-25.26~18.04.1 #kernel_version=$(head -n 1 debian/changelog | cut -d '(' -f 2 | cut -d ')' -f 1) ##This somehow comes out empty when run in the script, but is successful when issued manually independent_code } function independent_code() { kernel_localversion="" if [ -z "${acso}" ] || [ "${acso}" != "n" ] then try_acso_patch fi if [ "${agesa}" == "y" ] then try_agesa_patch fi if [ "${vega}" == "y" ] then try_vega_patch fi ##temporary #fix_steam cp "${kernel_config}" .config yes '' | make oldconfig ##set xhci_hcd to load as a module instead of including it directly into the kernel ##results in vfio_pci being able to grab usb controllers before xhci_hcd is able to sed -i -e 's/^CONFIG_USB_XHCI_HCD=y/CONFIG_USB_XHCI_HCD=m/g' .config ##Enable AMD's HSA driver for ROCm support. Thanks at https://github.com/jfturcot sed -i -e 's/^#\ CONFIG_HSA_AMD\ is\ not\ set/CONFIG_HSA_AMD=y/g' .config ##Disable debug builds sed -i -e 's/^CONFIG_DEBUG_INFO=y/CONFIG_DEBUG_INFO=n/g' .config sed -i -e 's/^CONFIG_DEBUG_KERNEL=y/CONFIG_DEBUG_KERNEL=n/g' .config ##check for versions containing only a single dot instead of two ##but only when not choosing the repo source if [ "${s_or_m_or_r}" != "r" ] then dots=$(echo "${kernel_version}" | awk -F "." '{print NF-1}') dashes=$(echo "${kernel_version}" | awk -F "-" '{print NF-1}') if [ "${dots}" -lt 2 ] then if [ "${dashes}" -lt 1 ] then ##5.1 -> 5.1.0 kernel_version="${kernel_version}.0" else ##5.1-rc1 -> 5.1.0-rc1 kernel_version="$(echo "${kernel_version}" | sed 's/-/.0-/')" fi kernel_name="linux-${kernel_version}" fi fi make clean make -j "$(nproc)" bindeb-pkg LOCALVERSION="${kernel_localversion}" || exit if [ -z "${install}" ] || [ "${install}" == "y" ] then sudo dpkg -i ../linux-image-${kernel_version}${kernel_localversion}*.deb ../linux-headers-${kernel_version}${kernel_localversion}*.deb if [ -z "${default}" ] || [ "${default}" == "y" ] then if [ "$(lsb_release -s -d | cut -d ' ' -f 1)" == "Ubuntu" ] then ##removing previous commented line sudo sed -i -e 's/^#GRUB_DEFAULT=.*//g' "${grub_config}" ##commenting current line sudo sed -i 's/^GRUB_DEFAULT=/#GRUB_DEFAULT=/' "${grub_config}" ##adding line ## TODO multilanguage! only works for en-US (and other en-*) right now! grub_line="GRUB_DEFAULT=\"Advanced options for Ubuntu>Ubuntu, with Linux ${kernel_version}${kernel_localversion}\"" sudo sed -i -e "s/^#GRUB_DEFAULT=.*/\0\n${grub_line}/" "${grub_config}" sudo update-grub fi fi fi cd "${current_dir}" || exit rm -rf "${working_dir}" } ##actual logic init stable_or_mainline_or_repo