Although kernels that come preconfigured with most Linux distributions are good enough for general use cases, at times, we may want to have a custom kernel installed for our special use case. One may want a custom Linux kernel to optimize or support specific hardware or just to enable an experimental feature not yet available on the stable channel. And some hobbyists just want to deep dive into kernel workings and want to explore. Whatever the case, compiling and installing a custom Linux kernel is not hard at all. One doesn't need to be a hardcore systems programmer to do that. Let's see how we can do it.
If you are doing it for the first time, use a spare computer to get familiar with the whole process. Once you get a hang of it, go ahead with your actual work computer to get the kernel of your choice.
The package installation commands may differ depending on the Linux distribution, but apart from that, all the compilation and installation steps are the same for every distribution.
Why Compile Your Kernel?
If you have never thought about it before, you may be curious why I need to do this. Let's see some of the reasons one may opt to compile and use a custom Linux kernel.
- Performance Tuning: If you running mission-critical applications on your Linux system and want a faster and leaner kernel, you may opt to remove unnecessary components from it.
- Feature Activation: Sometimes you may get tempted to test new experimental features which are not included in the default kernel supplied with your Linux distribution.
- Hardware Compatibility: Sometimes, you may be using a recently launched or specialized hardware whose drivers and native kernel support are missing in the default kernel.
- Learning: Last but not least, you may be interested in understanding the workings of the Linux kernel and want to explore more.
Whatever the case, compiling a custom Linux kernel is a unique experience, every time you do it. It also gives you a good understanding of how kernel components can be added and removed from the core.
Prerequisites for Compiling a Custom Linux Kernel
Before we dive into creating our own version of the Linux kernel, let's quickly see the tools and applications we need to successfully complete this process.
Let's start with the general requirements.
- A Linux distribution of your choice, e.g., Arch, Fedora, or Ubuntu.
- Enough disk space on your system (at least 20GB).
- A good internet connection.
- Access to the root account on your Linux system.
- Working knowledge of command line and Linux system administration.
Required Development Tools
You'll need a few developer tools to be able to compile a Linux kernel. Here's how to install them.
# For Debian/Ubuntu-based distributions:
sudo apt update
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev
# For Fedora/Red Hat-based distributions:
sudo dnf group install "Development Tools"
sudo dnf install ncurses-devel bison flex elfutils-libelf-devel openssl-devel
# For Arch-based distributions:
sudo pacman -S base-devel linux-headers
Now that we know all the prerequisites and the tools needed for the job, let's move on to the next step.
Step 1: Download the Linux Kernel Source
We'll start with downloading the Linux kernel source code. Make sure you know in advance which kernel version you want to download. Here's how to do it.
- Go to the official Linux kernel website.
- Select the desired version from the list of kernel source archives and download it.
- And finally, extract the source code on your Linux system. Here's how to do it.
Replace allwget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-x.x.x.tar.xz tar xvf linux-x.x.x.tar.xz cd linux-x.x.xxinstances with the kernel version you want to download.
After completing this step, you'll have the extracted source code of the Linux kernel you want to customize. Additionally, you will enter the directory of the kernel source code.
Step 2: Configure the Kernel
And now comes the important part. The whole purpose of this exercise is to create a custom Linux kernel. You get 3 different methods to configure the kernel components before you start the compilation process. Let's take a look at all 3 methods.
Option 1: Use Your Current Kernel Configuration
Although this is not what we want, still it's worth mentioning.
cp /boot/config-$(uname -r) .config
make oldconfig
If you do not want to make drastic changes and just want to tweak the default kernel, a little bit, this option is the best way to move forward. It copies your existing kernel configuration and lets you interactively tweak (add or delete) the options.
Option 2: Generate a Default Configuration
As the name implies, this is more or less like using your default kernel supplied with your Linux distribution.
make defconfig
This option essentially creates a stripped-down and minimal version that runs nicely with your system's hardware. Generally, it is faster than the default one though differences are only noticeable in the benchmarking results.
Option 3: Fully Customized Configuration
This is the one we are looking for. A fully customized version implies you select and add kernel components and features one by one from scratch.
make menuconfig
Upon firing this command, you get a graphical interactive menu where you can cherry-pick the kernel features you'd like to include in your final build. Here are some key areas to take care of while customizing your kernel.
- Processor Type: Now this one is quite obvious. Make sure you are choosing the CPU architecture supported by your existing processor. It'll ensure you get the best performance on your Linux system.
- Filesystem Support: Here you can choose all the filesystems you may want to use. For e.g., ext3, ext4, zfs, or btrfs. Remember, only add the filesystems you are going to use.
- Networking Options: Once again, choose the network protocols (e.g., WiFi, Bluetooth) you want to use in a daily workflow.
- Device Drivers: Here you need to be extra cautious. Carefully choose the right device drivers that match your hardware. Make a list in advance before starting the configuring process.
- Security Features: Last but not least, security modules like AppArmor can be installed for added security. But, they are optional and can be skipped. Configuration of Linux security tools is mentioned in this guide.
Once the kernel configuration process is over, it's time to compile it. Let's see how to do it.
Step 3: Compile the Kernel
Linux kernel compilation is comparatively much easier and can be completed in a few commands. Though the process itself can take some time, the commands are simple and work seamlessly without any user intervention. Let's go!
# Clean up the build environment
make clean && make mrproper
# Compile the kernel using all available CPU cores
make -j$(nproc)
# Compile kernel modules
make modules -j$(nproc)
Kernel modules are like Windows .dll files which can be loaded dynamically—whenever required. The entire kernel compilation process is time-consuming unless you are using a high-end processor.
Step 4: Install the Kernel
Both the kernel configuration and building process are now complete. Finally, it's time to install it. For that, we have to execute a couple of commands and that's it.
# Install kernel modules
sudo make modules_install
# Install the Kernel
sudo make install
When you install the kernel, its newly-built image and the related files are kept in the /boot directory. Once this process is complete, your Linux system's bootloader needs to be updated.
Step 5: Update the Bootloader
The final step is to update your GRUB bootloader to add an entry to the newly installed kernel. Here's how to do it.
# Update GRUB to add new kernel entry
sudo update-grub
# For systems using 'grub2-mkconfig', use:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
If you are using another bootloader, refer to the documentation of that bootloader to make the necessary changes.
Step 6: Reboot and Test
After all the steps are complete, it's time to test the new kernel and ensure everything is working as intended. Here are the steps to do it.
- First of all, reboot the system using the
sudo rebootcommand. - Upon rebooting, you'll get the new and updated GRUB menu. Select the new kernel entry from the menu.
- Log in and verify the new kernel by using the
uname -rcommand.
Troubleshooting and Tips
Now it is very much possible that things may go wrong and you may encounter issues. Let's see some of the common issues and how to tackle them.
Common Issues
- Kernel Panic: This error happens because of misconfigured options. To troubleshoot it, reboot the system and log in using the old kernel. Thereafter, you can double-check if the configuration was done correctly or not. The entire process is a lengthy and separate topic that I'll cover in another post.
- Missing Drivers: Similarly, if the correct device drivers are not configured, you may not be able to boot and use the new kernel. Once again, log in using the old kernel and check if the correct drivers are installed or not.
- Performance Issues: This can be tricky to troubleshoot. Check the system log files to find the root cause of performance issues. The only solution to this problem is to recompile the kernel with the new options removing the ones causing this issue.
Rollback Plan
While compiling and installing the new Linux kernel, always make sure to keep the old kernel's entry intact in the GRUB bootloader. In case anything goes wrong, you can easily switch to the old version to keep your system in a working condition.
Testing Safely
The two important precautions you can take before diving into the new kernel installation process are:
- Try the entire exercise in a Linux instance running inside a virtual machine.
- Before starting this process, take a backup of the
/bootdirectory.
Conclusion
Compiling and installing a custom Linux kernel is challenging yet a full experience. It enables you to customize your Linux system for special use cases and simultaneously provides insights about the Linux kernel internals.
Have you compiled a custom Linux kernel before? Do share your experiences in the comments below!