First off, what is kexec? - It is a system call that enables you to load and boot into another kernel from currently running kernel. That effectively means; doing reboot without going through the whole POST/Firmware load process.

To use kexec we can rely on systemd to handle process for us. The only work we need to do is to install kexec-tools package and adjust some configs

sudo apt-get update
sudo apt-get install kexec-tools

Since Ubuntu usually relies on booting from grub we can tweak some settings to default to loading default grub kernel when we run kexec. That is usually set to latest kernel we have installed and is automatically adjusted after system upgrade. Contents of my /etc/default/kexec are as follows:

# Defaults for kexec initscript
# sourced by /etc/init.d/kexec and /etc/init.d/kexec-load

# Load a kexec kernel (true/false)

# Kernel and initrd image

# If empty, use current /proc/cmdline

# Load the default kernel from grub config (true/false)

Now, in order to reboot via kexec you can simply use:

sudo systemctl start

In one article on Oracle blog I have found a script which is basically a wrapper around this and allows you to specify desired kernel version you’d like to boot into. Since script was most likely written on Oracle Linux or some kind of RedHat derivative it is not working properly on Ubuntu, so here’s my slightly updated version:

[[ "$1" != '-' ]] && kernel="$1"
if [[ "$1" == '-' ]]; then
[[ $# == 0 ]] && reuse=--reuse-cmdline
kernel="${kernel:-$(uname -r)}"
kargs="/boot/vmlinuz-$kernel --initrd=/boot/initrd.img-$kernel"
kexec -l -t bzImage $kargs $reuse --append="$*" && systemctl kexec