Table of Contents
- Prerequisites
- Choosing a Kernel Version
- Downloading the Kernel Source Code
- Setting Up the Build Environment
- Configuring the Kernel
- Compiling the Kernel
- Installing the Kernel and Updating GRUB
- Testing the New Kernel
- Troubleshooting Common Issues
- Conclusion
- References
Prerequisites
Before diving in, ensure your system meets these requirements:
- A Linux-based OS: This tutorial uses Ubuntu 22.04 LTS, but the steps are similar for other Debian/Ubuntu derivatives. For Fedora/RHEL, replace
aptwithdnf/yum. - Sudo privileges: You’ll need root access to install packages and modify system files.
- Disk space: At least 30 GB free (source code, build files, and installed kernel/modules).
- Time: Compilation can take 30 minutes to several hours, depending on your CPU (faster with multi-core systems).
- Basic command-line familiarity: You should be comfortable using
cd,cp,sudo, and text editors.
Choosing a Kernel Version
The Linux kernel is maintained at kernel.org, where you’ll find three main release types:
- Mainline: The latest development version (e.g., 6.6-rc1). Not recommended for stability.
- Stable: Tested, bug-fixed versions (e.g., 6.5.7). Good for most users.
- Long-Term Support (LTS): Supported for 2–6 years (e.g., 6.1.x, 5.15.x). Best for reliability.
For your first build, pick a stable or LTS version. Check your current kernel with:
uname -r # Example output: 5.15.0-78-generic
Downloading the Kernel Source Code
You can download the source via Git or a tarball. We’ll use the tarball method for simplicity.
-
Visit kernel.org and copy the link to the stable or LTS tarball (e.g.,
linux-6.5.7.tar.xz). -
Download it with
wget:wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.5.7.tar.xz -
Extract the source code:
tar xvf linux-6.5.7.tar.xz # Replace with your downloaded filename cd linux-6.5.7 # Enter the source directory
Setting Up the Build Environment
Install tools required for compiling the kernel:
sudo apt update && sudo apt install -y \
build-essential \ # GCC, make, and basic build tools
libncurses-dev \ # For `make menuconfig` (text-based config)
flex \ # Parser generator (required for kernel build)
bison \ # Parser generator
libssl-dev \ # For cryptographic modules (e.g., HTTPS)
libelf-dev \ # For ELF binary support
dwarves \ # For `pahole` (optimizes kernel debugging info)
bc \ # Arbitrary-precision calculator (used in kernel math)
rsync \ # For efficient file copying (during installation)
git # Optional, for fetching patches
Configuring the Kernel
The kernel uses a .config file to define which features, drivers, and modules to include. You’ll need to generate this file before compiling.
Step 1: Start with a Baseline Config
A safe starting point is to reuse your current kernel’s config. Copy it into the source directory:
cp /boot/config-$(uname -r) .config
This ensures compatibility with your hardware (e.g., drivers for your GPU, Wi-Fi, etc.).
Step 2: Tweak the Config with menuconfig
To customize the kernel (e.g., add/remove features), use make menuconfig—a text-based interface for editing .config.
Run:
make menuconfig
You’ll see a menu with categories like “General setup,” “Device Drivers,” and “File systems.” Navigate with arrow keys, and use:
Y: Build a feature directly into the kernel (required for boot-critical drivers).M: Build as a loadable module (loaded dynamically after boot, saves space).N: Exclude the feature.
For your first build, stick to the baseline config (no need to change anything). Press F6 to load the .config file (if not auto-loaded), navigate to “Save,” and exit.
Compiling the Kernel
Now, compile the kernel and its modules. This is the longest step!
Step 1: Clean Up Old Build Files (Optional)
If you’ve compiled before, clean residual files:
make clean # Removes most build files (keeps .config)
# OR
make mrproper # Removes all build files + .config (start fresh)
Step 2: Compile the Kernel
Use make with the -j flag to parallelize compilation (use nproc to get core count):
make -j$(nproc) # e.g., `make -j8` for 8 cores
What’s Happening?
- The kernel compiles into
vmlinux(the raw kernel image). - Modules compile into
.kofiles (stored indrivers/,fs/, etc.).
Step 3: Compile and Install Modules
Install loadable modules to /lib/modules/<version>/:
sudo make modules_install -j$(nproc)
Step 4: Install the Kernel Image
Copy the kernel image, initramfs (initial RAM filesystem), and System.map (symbol table) to /boot/:
sudo make install
This command also updates initramfs (to include modules needed for boot) and GRUB (the bootloader).
Installing the Kernel and Updating GRUB
The make install step should automatically update GRUB, but verify with:
sudo update-grub
You’ll see output like:
Found linux image: /boot/vmlinuz-6.5.7
Found initrd image: /boot/initrd.img-6.5.7
Testing the New Kernel
Reboot your system to load the new kernel:
sudo reboot
Selecting the Kernel in GRUB
On boot, hold the Shift key (or Esc on some systems) to open the GRUB menu. Select your new kernel (e.g., “Ubuntu, with Linux 6.5.7”).
Verify the Kernel Version
After logging in, confirm the new kernel is running:
uname -r # Should output: 6.5.7
Check for Errors
Check boot logs for issues:
dmesg | grep -i "error\|warn" # Look for critical errors
Test basic functionality: Wi-Fi, sound, USB ports, and apps. If something breaks, it may be due to a missing module (we’ll troubleshoot this later).
Troubleshooting Common Issues
Problem: The New Kernel Won’t Boot
If your system hangs or fails to boot:
- Reboot and select your old kernel from the GRUB menu (e.g., “Ubuntu, with Linux 5.15.0-78-generic”).
- Check boot logs in the old kernel:
Common culprits: Missing disk/network drivers, or misconfigured initramfs.sudo less /var/log/boot.log # Or `journalctl -b -1` (logs from last boot)
Problem: Missing Modules (e.g., Wi-Fi Not Working)
If a device isn’t detected, the driver may be excluded. Reconfigure the kernel:
cd /path/to/linux-source # e.g., ~/linux-6.5.7
make menuconfig
Search for the driver (e.g., “Intel Wi-Fi”) and set it to Y or M, then recompile:
make -j$(nproc) && sudo make modules_install && sudo make install
Problem: Insufficient Disk Space
If compilation fails with “No space left on device,” free up space or move the source to a larger partition.
Conclusion
Congratulations! You’ve built and installed a custom Linux kernel. This process demystifies how the kernel works and gives you control over your OS. As you get comfortable, try:
- Enabling experimental features (e.g., new filesystems like Btrfs).
- Patching the kernel with custom code (e.g., for hardware support).
- Optimizing for your CPU (e.g.,
make localmodconfigto trim unused modules).
Remember: Building kernels is a learning process—don’t fear mistakes (you can always revert to the old kernel!).