Fun with kexec

What is kexec?

Simply speaking kexec is a mechanism in Linux kernel which allows you to quickly boot to a new kernel from the currently running one. It’s like a reboot but it skips the entire bootloader stage. There is no hardware initialization. No system firmware. Basically we get extremely fast reboots! Believe me or not, but booting up an enterprise-class machine can take a few minutes…

First steps

First make sure that you have kexec system call enabled in your running kernel:

$ grep CONFIG_KEXEC /boot/config-`uname -r`
CONFIG_KEXEC=y
...

You also need to install kexec-tools package on your system. If you are using Debian GNU/Linux (or some derivative):

$ apt-get install kexec-tools

Alternatively you can build kexec-tools from source:

$ wget -q http://kernel.org/pub/linux/utils/kernel/kexec/kexec-tools.tar.gz
$ tar xvpfz kexec-tools.tar.gz
$ cd kexec-tools-VERSION
$ ./configure
...
configure: creating ./config.status
config.status: creating Makefile
config.status: creating include/config.h
$ make && make install

Now let’s assume that we want to test our freshly built kernel:

$ uname -a
Linux testvm 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
$ kexec --load /boot/vmlinuz-4.0.0-rc1 --initrd=/boot/initrd.img-4.0.0-rc1 --reuse-cmdline
$ kexec --exec
[...]
$ uname -a
Linux testvm 4.0.0-rc1 #1 SMP Mon Mar 2 21:21:48 CET 2015 x86_64 GNU/Linux
$ 

Voilà! We have kernel 4.0.0-rc1 up and running!

Why would I need this?

Imagine, that you need to install Debian GNU/Linux on remote server running Not You Favorite Linux Distribution and having only serial console connected to it (let’s assume, that you have kexec-tools installed):

$ export DEBIAN_VERSION="wheezy"
$ export DEBIAN_ARCH="amd64"
$ export DEBIAN_MIRROR="http://ftp.pl.debian.org"
$ export NETBOOT_URL="${DEBIAN_MIRROR}/debian/dists/${DEBIAN_VERSION}/main/installer-${DEBIAN_ARCH}/current/images"
$ wget -q "${NETBOOT_URL}/netboot/netboot.tar.gz"
$ wget -q -O - "${NETBOOT_URL}/SHA256SUMS" | grep "netboot/netboot.tar.gz"
af54dcbd0866b0093693bd62c38dbd1c9af106aed2b34a415db2a3d51856e960  ./netboot/netboot.tar.gz
$ sha256sum netboot.tar.gz # always check checksums ;)
af54dcbd0866b0093693bd62c38dbd1c9af106aed2b34a415db2a3d51856e960  netboot.tar.gz
$ tar xfz netboot.tar.gz
$ kexec --load debian-installer/amd64/linux \
		--initrd=debian-installer/amd64/initrd.gz \
		--command-line="console=ttyS0 priority=low"
$ kexec --exec
[  109.165007] kexec: Starting new kernel
...

After few seconds you should get Debian installer screen:

Debian GNU/Linux installer screen

You can also boot some ISO images using GRUB4DOS:

$ kexec --load /path/to/grub.exe \
		--initrd=/path/to/image.iso \
		--command-line="--config-file=debug on; map --mem (rd)+1 (0xff); map --hook; chainloader (0xff)"
$ kexec --exec

I’ve tested it with following ISOs: