Published on September 18, 2022
Introduction
These are my notes on how to build your own Linux kernel for Ubuntu, as the information online is scattered all over the place and dated. Fortunately, Canonical recently followed suit and it is now possible to simply build a mainline Linux kernel, rather than having to build Canonical's fork. While this may be useful if you need more recents drivers, because drivers such as amdgpu are typically behind on Ubuntu, this guide is targeted at users who want to either write their own drivers or modify existing drivers in the Linux kernel.
Installing build dependencies
There are number of dependencies that need to be installed before we can build the Linux kernel. They can be installed by running the following command on Ubuntu:
sudo apt-get install libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf llvm
Building the kernel
Now that we have all the dependencies required to build the kernel, we can either download a tarball with the Linux source code from https://kernel.org or clone the appropriate tag from the Linux kernel repository. For instance, we can clone the source code of the Linux kernel for version 6.5 as follows:
git clone -b v6.5 --depth=1 https://github.com/torvalds/linux
Once we have downloaded the source code, we can simply cd
into the directory as follows:
cd linux
Before we can build the Linux kernel, we need to configure the kernel. Fortunately, we can simply copy the kernel configuration from an existing installation:
cp -v /boot/config-$(uname -r) .config
However, we have to tune a few configuration options before we can actually build the kernel 1:
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS
In addition, the kernel configuration we copied may be from an older version than the kernel version we are trying to compile. We can update the kernel configuration to be compatible with the version of the forked Linux kernel tree as follows:
make olddefconfig
The above command will simply pick the default option for any newly introduced configuration option.
To build the Linux kernel and the kernel modules we can simply invoke make
.
However, make
will by default only use one CPU core/thread, so we have to specify the jobs option or -j
followed by the number of threads that we want to use.
For example, to use 16 CPU cores/threads, we can invoke make
as follows:
make -j16
If the above command was successful, we can now install the kernel modules:
sudo make INSTALL_MOD_STRIP=1 modules_install
As well as the Linux kernel:
sudo make install
The above command will also update the initramfs and regenerate the GRUB configuration file automatically on Ubuntu. However, it is also possible to update the initramfs or regenerate the GRUB configuration file yourself.
The commands that get passed to the kernel by GRUB during boot are located in /etc/default/grub
. You can modify the kernel command line in /etc/default/grub
, then you can run the following to update the GRUB configuration file:
sudo update-grub
If you want to rebuild the initramfs, you can run the following:
sudo update-initramfs -u
Finally, after installing the Linux kernel, the kernel modules and updating the initramfs and GRUB configuration, you can reboot your system:
sudo reboot
GRUB should now present you with the option to boot the newly installed kernel.
However, depending on your installation, GRUB may not present you with a boot menu at all, e.g. on Ubuntu this is the default behavior.
To change this, you can edit the /etc/default/grub
file.
More specifically, comment out the GRUB_TIMEOUT_STYLE
variable and set GRUB_TIMEOUT
to a non-zero value as follows:
#GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=10
Then run the following command to regenerate the GRUB configuration file:
sudo update-grub
If you like my work or if my work has been useful to you in any way, then feel free to donate me a cup of coffee. Any donation is much appreciated!