How to build your own kernel on Slackware Linux

With all the noise lately about Dirty COW (CVE-2016-5195) and the lack of patched kernels from Slackware’s “Benevolent Dictator for Life”, I decided it was time to roll up the sleeves and get it done. Since Slackware doesn’t have a “sophisticated” build system and all that grease, it’s a trivial matter to step up to the plate and take responsibility for your own system. I’ll be using “vanilla-kernelversion” as my tag for the kernel and initrd. Also notice that I build my kernels as a normal user.

Download and verify the kernel source

Create a directory for building the new kernel:

mkdir ~/kernel; cd ~/kernel

Download the kernel source and signature from kernel.org:

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.27.tar.xz
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.27.tar.sign

Decompress the archive:

unxz linux-4.4.27.tar.xz

Verify the .tar archive against the signature (this will fail as I don’t have the public key yet):

gpg2 --verify linux-4.4.27.tar.sign

Notice the “key ID” from the output of the previous step and download it from a key server:

gpg2 --keyserver hkp://keys.gnupg.net --recv-keys 6092693E

Verify the .tar archive against the signature again and look for the “Good signature” message:

gpg2 --verify linux-4.4.27.tar.sign

Extract the tarball if everything checked out:

tar -xvf linux-4.4.27.tar

Enter the kernel source directory and clean the kernel tree:

cd linux-4.4.27
make clean && make mrproper

Configuring and compiling the kernel

There is obviously no reason to configure a brand new kernel from scratch when already running a generic stock Slackware kernel. Make sure you’re still in the kernel source directory and issue the following command to copy the running kernel configuration:

zcat /proc/config.gz > .config

For simplicity, I want all new configuration options to be set to their defaults. By using “olddefconfig” you’ll automatically chose the defaults without any manual handling:

make olddefconfig

To speed up the compiling, make sure to run make with the “-j” option (number of cores+1):

make -j9

Compiling kernel modules and installation

Everything from this point and onward is done as root. Switch to the root user and reenter the kernel source directory.
Proceed to install the kernel modules:

make modules_install

Copy the kernel to the boot directory and rename it (the location of the kernel image is the same for x86_64 and x86):

***** arch/x86/boot/bzImage /boot/vmlinuz-vanilla-4.4.27

Copy the System.map to the boot directory and rename it:

***** System.map /boot/System.map-vanilla-4.4.27

Copy the kernel .config to the boot directory and rename it:

***** .config /boot/config-vanilla-4.4.27

Enter the boot directory:

cd /boot

Delete the old System.map link:

rm System.map

Create a new System.map link:

ln -s System.map-vanilla-4.4.27 System.map

Initrd and LILO

I need to create an initial ramdisk to boot my kernel so I’ll use the mkinitrd command to create one. I’ll leave it to Slackware to identify which modules are needed by running mkinitrd_command_generator.sh with the “-k” parameter to specify the new kernel version. To avoid wiping my existing initrd I’ll name it initrd-vanilla-4.4.27. I’ll use the output from the generator to create the initrd (remember to modify the initrd name):

/usr/share/mkinitrd/mkinitrd_command_generator.sh -k 4.4.27
# Don't go copying the next line, that's an example.  
mkinitrd -c -k 4.4.27 -f ext4 -r /dev/sda2 -m jbd2:mbcache:ext4 -u -o /boot/initrd-vanilla-4.4.27.gz

To boot the new kernel, it needs to be added to LILO. Make sure to not remove the entry specifying your running Slackware kernel. If the new kernel doesn’t run, it’s practical to boot into a working one.

nano /etc/lilo.conf

Create a new entry for the new kernel (I’m using mine as default but that’s optional):

/******************************************
#etc/lilo.conf
default = Vanilla  

image = /boot/vmlinuz-vanilla-4.4.27
  root = /dev/sda2
  read-only
  initrd = /boot/initrd-vanilla-4.4.27.gz
  label = Vanilla
******************************************/

Finally, run the lilo command and it’s all done.

lilo

But I’m using ELILO

Me too, replace the LILO section with this part: Configuring ELILO with a generic kernel on Slackware 14.2