Update: This specific approach works only for certain major kernel versions; in particular, 5.4.0-xx. (it might be possible with fancier
apt-mark hold rules to stay on e.g 5.8.0-xx kernels)
I frequently came to this question when trying a few times over the last while to figure out how to do a slightly modified version of the original question:
How do I freeze the Ubuntu kernel at (e.g., specifically for Ubuntu 20.04) the 5.4.0-x version, so that I still get minor upgrades, but do not get upgraded to another "major" version like 5.8.0-x
The trick in this specific case was to do the following:
# This prevents installation of, or further upgrades of the package that results in a 5.8 kernel being installed
sudo apt-mark hold linux-generic-hwe-20.04
# This will pull in the latest 5.4 Ubuntu kernel, and receive subsequent 5.4.0-x patches too
sudo apt install linux-generic-hwe-18.04
I'm not sure if this is entirely universally applicable, but this worked for Ubuntu 20.04 at least as of January 2021. (The triggering event in my case was that my 5.4 machines started getting updated to 5.8 automatically during the first week of January, 2021). Also note, I'm not an expert but have tested this a fair bit. There may be some significant nuances I have incorrect...
But if you already have a newer major-version kernel installed (e.g. via unattended-upgrades), you'll probably want to uninstall it too. I have not had any issues with the following command/regex to identify what packages would get remove by the command after this one:
dpkg -l | grep -o -P "^ii\s+linux-[\S]*-5.(8|11|13).0[\d\S]+"
And the removal command is very similar:
sudo apt remove -y $(dpkg -l | grep -o -P "linux-[\S]*-5.(8|11|13).0[\d\S]+")
Finally, you'll want to reboot before you do much else, including doing any
apt upgrade. Particularly if you've uninstalled the currently running kernel's packages, post-install scripts for other packages might not be happy if run before a reboot!
For more information on the kernel choices for Ubuntu, aka to know roughly what's coming, this page is pretty informative: https://ubuntu.com/about/release-cycle
n.b. For good measure, you can put the
apt-mark hold on all three of
linux-generic-hwe-20.04 linux-headers-generic-hwe-20.04 linux-image-generic-hwe-20.04 but in practice holding just that first one seemed sufficient.
n.b. In my situation, while in most cases you should not need to do what this post describes, I needed to stick to an older major kernel version in order for some hardware to work properly.
n.b.2: With Ubuntu 20.04, this "remove 5.8 kernels approach" later broke for 5.11 kernels, and would likely also happen with the 5.13 kernels. I've updated the regex above accordingly.