Building Custom Ubuntu Kernels

In a previous article, I went about Building a tickless Ubuntu Kernel. While that approach is fairly straightforward, I’ve been building a variety of kernel configs recently and was starting to find it a bit hard to manage.

Here is a simpler and slightly more automated version of building kernel configs.

Some steps remain the same as before, but I’ve included them here for completeness.

Uncomment source repositories

This step might be optional depending on your setup:

Let’s quickly backup our sources.list

1
sudo cp /etc/apt/sources.list /etc/apt/sources.list-

Open /etc/apt/sources.list and uncomment the deb-src lines.

Install required dependencies

1
2
3
4
sudo apt update
sudo apt build-dep linux linux-image-lowlatency linux-image-generic
sudo apt install devscripts
sudo apt install libcap-dev

If you have problems with the above you might also need to:

1
sudo apt --fix-broken install

Clone kernel repo

The official site is very slow, but let’s use that anyway. If you’d like to clone from a faster location, please check the article mentioned above.

The last line picks one version ahead, for ease of recognition and for the newly compiled kernel to be the default at boot.

1
2
3
4
5
mkdir -p kernel-workspace/config
git init kernel-workspace/config
cd kernel-workspace
sudo apt install linux-source
tar xjvf /usr/src/linux-source-5.15.0.tar.bz2

Copy the config of the current setup as a base for further changes:

1
cp /boot/config-`uname -r` config/config.base

Create and Manage config changes

We will use the kernel-workspace/config directory to manage configs and changes. This is also initialized as a git repo.

Create a file overriding config changes for the tickless kernel: Create a file representing config changes for the tickless kernel:

1
2
3
4
5
6
7
cat <<EOF > config/tickless.sh
scripts/config --disable CONFIG_PREEMPT_VOLUNTARY

scripts/config --set-val CONFIG_PREEMPT_NONE y
scripts/config --set-val CONFIG_NO_HZ_FULL y
scripts/config --set-val CONFIG_RCU_NOCB_CPU y
EOF

In a similar fashion, any number of config files can be created and/or versioned as necessary.

Apply config to kernel build

Start with the base config stored earlier and apply config changes:

1
2
3
4
5
6
7
cd linux-source-5.15.0
cp ../config/config.base .config
sh ../config/tickless.sh
mkdir -p debian
cp /usr/src/linux-source-5.15.0/debian/canonical-certs.pem debian/
cp /usr/src/linux-source-5.15.0/debian/canonical-revoked-certs.pem debian/
make oldconfig

It’s alternatively possible to use skip verification and use defaults by using make olddefconfig instead of make oldconfig.

Build the kernel

The following will build the kernel using the number of cores:

1
2
make clean
make -j $(nproc) deb-pkg LOCALVERSION=-tickless

Sign the kernel

Follow the instructions in UEFI section of the previous article to sign the kernel.

Reboot

Reboot into the new kernel. It should be selected by default during boot process. Verify after boot using uname -r.