View Categories

How to Install a Different Ubuntu Kernel

4 min read

If you need to install either a newer or older Ubuntu kernel, the easiest method is to use the Ubuntu Mainline Kernel install script from pimlie. You will then need to reconfigure grub and reboot. The difficulty on a scale of 1 to 10 is about a 2. Maybe a 3 if you don’t like the command line. The process takes just a few minutes.

Note: If you are a Mailborder user on a server that was upgraded from 22.04 to 24.04 and are having issues, the version we have found that works well is v5.15.75. 

Looking for Errors
Regarding Mailborder users, you may not need to change your kernel if there are no errors. To check for errors, run this:

cat /var/log/syslog|grep -i 'hogged'

If nothing is returned, you should be ok to keep using your installed kernel. If you see anything like the below output, you should roll back to an older version. 

mx2 kernel: workqueue: vmstat_update hogged CPU, consider switching to WQ_UNBOUND
mx2 kernel: workqueue: drm_fb_helper_damage_work hogged, consider switching to WQ_UNBOUND
mx2 kernel: workqueue: drain_vmap_area_work hogged, consider switching to WQ_UNBOUND

 

Take a Snapshot
Don’t skip this step. While this is a relatively easy change, it is also easy to make a mistake and not be able to get into your server. Take a backup or snapshot. If you cannot, proceed with extreme caution making sure you get this right. 

Get the Script
First, we need to download the script and install it on your Ubuntu system. This will download it and put it in the /usr/local/bin directory.

cd /tmp
wget https://raw.githubusercontent.com/pimlie/ubuntu-mainline-kernel.sh/master/ubuntu-mainline-kernel.sh
chmod +x ubuntu-mainline-kernel.sh
sudo mv ubuntu-mainline-kernel.sh /usr/local/bin/

Options
To see all of the available options with the script, run with the -h flag.

ubuntu-mainline-kernel.sh -h

List the Available Kernels
Next, we need to get a list of available kernels. The list will be large, but you also have the option of filtering it. To simply get the entire list, run this command:

 ubuntu-mainline-kernel.sh -r

To filter the list, just add it at the end:

 ubuntu-mainline-kernel.sh -r v5.15

Install a Kernel
Once you have decided on which kernel to install, run with the -i command. If you do not specify anything with the -i command, it will find the absolute latest kernel. Otherwise, put which one you want after the -i flag.

sudo ubuntu-mainline-kernel.sh -i v5.15.75

If you run into an error where it was not installed, create a directory in /tmp and tell the script to use that directory for download. Otherwise, you can skip this step.

cd /tmp
mkdir kernel_install
ubuntu-mainline-kernel.sh -i v5.15.75 -p /tmp/kernel_install

Note: Not every kernel is guaranteed to work with your system. You may have to try a few different ones. If it won’t work, you will get an error message like this: Abort, the amd64 build has not succeeded If that happens, just try a different kernel. 

List the Local Kernels
Once installed, you will need to get a list of available kernels currently installed for the next step. 

ls /boot/vmlinuz-*

Update Grub
To use the kernel, you are going to update /etc/default/grub so that it can use the kernel we just installed. For this example we will be using the kernel we found on our server in the boot directory named /boot/vmlinuz-5.15.75-051575-generic

Note: Make sure you pick the right kernel from your server. Don’t just copy and paste this line!

vi /etc/default/grub

Add or replace the GRUB_DEFAULT value with something like this:

GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 5.15.75-051575-generic"

Make sure the text in bold matches your kernel. Save the file and run the grub updater. Once you have double checked that the entry is correct, reboot.

update-grub
reboot

Once the system is back up, you can check to see which kernel is running.

uname -a

Preventing Automatic Upgrades
Once you have the kernel installed, you will probably want to prevent it from being automatically upgraded. To do that we are going to put a hold on it. 

First, get a list of your Linux images, headers, and modules:

dpkg --list | grep linux-

It will output something like this:

ii linux-headers-5.15.45-051545 5.15.45-051545.202206060743
hi linux-headers-5.15.45-051545-generic 5.15.45-051545.202206060743
ii linux-headers-5.15.75-051575 5.15.75-051575.202210261152
hi linux-headers-5.15.75-051575-generic 5.15.75-051575.202210261152
hi linux-image-unsigned-5.15.45-051545-generic 5.15.45-051545.202206060743
hi linux-image-unsigned-5.15.75-051575-generic 5.15.75-051575.202210261152
ii linux-libc-dev:amd64 6.8.0-52.53
hi linux-modules-5.15.45-051545-generic 5.15.45-051545.202206060743
ii linux-modules-5.15.75-051575-generic 5.15.75-051575.202210261152

In this example we will put the bold items on hold.

apt-mark hold linux-image-unsigned-5.15.75-051575-generic
apt-mark hold linux-headers-5.15.75-051575-generic
apt-mark hold linux-modules-5.15.75-051575-generic

To check what packages are on hold:

apt-mark showhold

Removing Old Kernels
If you have a server that has been around a while, it probably has a bunch of old kernels and files on it you do not want anymore. You can pick through them by listing your installed packages and remove them one by one, or you can use this bash script to remove them all at once. You will be given a confirmation option when you run the script. 

cd /tmp
vi remove_old.sh

Paste these contents:

#!/bin/bash -e
# Run this script without any arguments for a dry run
# Run the script with root and with exec arguments for removing old kernels and modules after checking
# the list printed in the dry run

uname -a
IN_USE=$(uname -a | awk '{ print $3 }')
echo "Your in use kernel is $IN_USE"

OLD_KERNELS=$(
  dpkg --get-selections |
  grep -v "linux-headers-generic" |
  grep -v "linux-image-generic" |
  grep -v "linux-image-generic" |
  grep -v "${IN_USE%%-generic}" |
  grep -Ei 'linux-image|linux-headers|linux-modules' |
  awk '{ print $1 }'
)
echo "Old Kernels to be removed:"
echo "$OLD_KERNELS"

OLD_MODULES=$(
  ls /lib/modules |
  grep -v "${IN_USE%%-generic}" |
  grep -v "${IN_USE}"
)
echo "Old Modules to be removed:"
echo "$OLD_MODULES"

if [ "$1" = "exec" ]; then
  apt-get purge $OLD_KERNELS
  for module in $OLD_MODULES ; do
    rm -rf /lib/modules/$module/
  done
fi

Dry Run
Run the script to just check what would be removed:

sh remove.sh

Execute
Run the script with the “exec” option to perform the removal of old kernels. 

sh remove.sh exec

 

Done!