Keeping your kernel up to date on Gentoo can be a bit daunting, especially when you are running the “keyworded” kernel, meaning not the stable version, but the “always latest” version by keyword ~amd64
. There’s a new version almost every week and updating it manually can be quite annoying over time. At least it felt for me …
make
make modules
make modules_install
make install
Then after that, updating the grub
config … And what was the command to update the kernel-dependent modules again? Oh ya …
emerge @module-rebuild
For some reason, I can never remember that one … Don’t ask me why.
So, I came up with a little helper in form of a bash script that does pretty much all the work for me, all I have to do is tell it which kernel version I want to have and it does all the magic for me. All I need to do from time to time is clean up old kernel installations.
#!/usr/bin/env bash
# Update script for sys-kernel/gentoo-sources
selected_kernel=""
kernel_base_directory="/usr/src/"
kernel_directory=""
use_latest_kernel=False
run_eclean_kernel=False
number_of_kernel_to_keep=1
# Check for installed programs
declare -A is_installed=(
['eclean-kernel']=False
)
for key in ${!is_installed[@]}
do
if command -v ${key} > /dev/null
then
is_installed["${key}"]=True
fi
done
usage() {
printf "Usage:\n"
printf "\t$0 [OPTION]\n"
printf "\nExample:\n"
printf "\t$0 --latest\t\t\t\tTo compile the latest kernel\n"
printf "\t$0 --eclean-kernel=2\t\tTo keep the latest 2 kernels in /boot/ for grub to detect\n"
printf "\t$0 --kernel=linux-5.17.7-gentoo\tTo compile a specific kernel version. (See available kernel versions below)\n"
printf "\nOptions:\n"
printf "\t-k, --kernel\t\tThe kernel version you want to compile, see available kernel versions (Example: -k=linux-5.17.7-gentoo)\n"
printf "\t-e, --eclean-kernel\tThe number of kernels to keep in /boot/ for grub to detect (Example: -e=2 to keep the latest 2)\n"
printf "\t\t\t\tThis parameter is only considered if 'eclean-kernel' is installed.\n"
printf "\t-l, --latest\t\tCompile the latest available kernel\n"
printf "\nAvailable kernel versions (current active version is marked with an asterisk):\n`eselect kernel list`\n" 1>&2;
exit 1;
}
for i in "$@"
do
case $i in
-k=* | --kernel=*)
selected_kernel="${i#*=}"
shift
;;
-e=* | --eclean-kernel=*)
program_to_check="eclean-kernel"
if [ ${is_installed["${program_to_check}"]} == True ]
then
re='^[0-9]+$'
if ! [[ ${i#*=} =~ ${re} ]]
then
echo "Error: Not a number" >&2; exit 1
fi
run_eclean_kernel=True
number_of_kernel_to_keep=${i#*=}
else
printf "Program 'eclean-kernel' is NOT installed. Ignoring parameter ...\n"
printf "To use this feature, install 'eclean-kernel' via 'emerge eclean-kernel'\n"
fi
;;
-l | --latest)
use_latest_kernel=True
;;
-* | --*)
echo "Unknown option $i"
exit 1
;;
*)
usage
;;
esac
done
# If the latest available kernel should be compiled, make sure -k, --kernel are ignored
if [ ${use_latest_kernel} == True ]
then
selected_kernel=$(eselect kernel list | tail -1 | awk '{print $2}' | sed 's/[][]//g')
fi
# If no kernel is selected, show help text
if [ -z "${selected_kernel}" ]
then
usage
fi
# Set the new kernel directory
kernel_directory="${kernel_base_directory}${selected_kernel}"
# Compiling new kernel
compile_new_kernel() {
echo "New Kernel Version: ${selected_kernel}"
echo "Entering kernel directory: ${kernel_directory}";
cd ${kernel_directory}
echo "Copying kernel configuration";
cp /usr/src/linux/.config .
echo "Switching symlink to new kernel";
eselect kernel set ${selected_kernel}
echo "Applying config via 'make olddefconfig'";
make olddefconfig
echo "Building new kernel";
make -j12
echo "Building modules";
make modules
echo "Installing modules";
make modules_install
echo "Installing new kernel";
make install
echo "Configuring grub2";
export GRUB_USE_LINUX_LABEL=true
cp /boot/grub/grub.cfg /boot/grub/grub.cfg.bak
if [ ${run_eclean_kernel} == True ]
then
echo "Cleaning up old kernel files but keeping the latest ${number_of_kernel_to_keep}";
eclean-kernel -n ${number_of_kernel_to_keep}
else
grub-mkconfig -o /boot/grub/grub.cfg
fi
echo "Re-compile kernel dependant modules";
emerge @module-rebuild
echo "Kernel update complete. You may restart your computer now."
if [ ${run_eclean_kernel} == False ]
then
echo "Feel free to run 'eclean-kernel -n 2' to cleanup old kernel files but keep the latest 2."
fi
}
if [ -d ${kernel_directory} ]
then
current_kernel_version=$(uname -r)
if [ ${selected_kernel} == "linux-${current_kernel_version}" ]
then
echo "You are currently running this kernel version."
echo "Exiting!";
exit;
else
compile_new_kernel
fi
else
echo "Error: Directory ${kernel_directory} does not exist."
echo "Exiting!";
exit;
fi
Save this as e.g. /usr/bin/kernel-update
, make sure it is executable via chmod +x /usr/bin/kernel-update
and all you have to do to switch to your desired kernel version is (Example: latest installed kernel):
kernel-update --latest
If you want a specific version, first check which versions are available via eselect kernel list
and take the version string for a kernel as the argument. For example to build linux-5.17.7-gentoo
:
kernel-update -k=linux-5.17.7-gentoo
If you like this script, let me know. I am always open to improvements, so feel free to suggest them!