Building the Linux Kernel from Source
The complete 7-step overview and Step 1: How to obtain the kernel source code
What You Will Learn
1. The Big Picture — 7 Steps to Build a Kernel
Building the Linux kernel from source is not as hard as it sounds. It is a well-defined sequence of steps. Once you do it once, you will understand exactly what is happening at each stage. Let us look at the complete process first so you have the full picture before going into the details.
Download a tarball from kernel.org or clone the Git repository
Unpack the .tar.xz file into a directory in your home folder (skip if you used git clone)
Use make menuconfig to select which features and drivers to include or exclude
Run make -j$(nproc) all to compile the kernel image, modules, and DTBs
Run sudo make modules_install to copy .ko files into /lib/modules/
Run sudo make install to create the initramfs image and update GRUB
Adjust boot menu entries, default kernel, timeout settings if needed
2. What Does the Build Actually Produce?
Before we dive into Step 1, it helps to know what you are building towards. After the entire process is complete, here is what gets created:
| Output File | Location | What It Is |
|---|---|---|
| bzImage | arch/x86/boot/ | The compressed kernel image the bootloader loads |
| vmlinux | source root | Uncompressed kernel binary, used for debugging with gdb/perf |
| System.map | source root | Symbol table mapping function names to memory addresses |
| *.ko files | scattered in tree | Loadable kernel modules, copied to /lib/modules/ at install time |
| *.dtb files | arch/arm/boot/dts/ | Device Tree Blobs, used on ARM/embedded boards (not needed on x86) |
3. Step 1 — Obtaining the Linux Kernel Source
Before you can build anything, you need the source code. There are two main ways to get it. The right choice depends entirely on what you plan to do with it.
Option A: Downloading a Specific Kernel Tarball
The kernel source is hosted at kernel.org. From there you can download any version you need. The files are in .tar.xz format, which is a tar archive compressed with XZ compression. This format gives very good compression ratios, which is why the kernel source at ~1.3 GB compresses down to around 110-130 MB.
First, install the prerequisites your system needs to build the kernel:
sudo apt update
sudo apt install -y build-essential libncurses-dev bison flex \
libssl-dev libelf-dev bc dwarves zstd
pahole tool (part of the dwarves package) to generate BTF (BPF Type Format) debug information. This was not needed in older kernels. If you skip this, the build will fail with a confusing error about BTF.Now download your chosen LTS kernel. Always verify the download with the checksum file to make sure the file was not corrupted in transit:
# Create a folder for your kernels
mkdir -p ~/kernels
cd ~/kernels
# Download the kernel tarball (replace 6.6.34 with the version you need)
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.34.tar.xz
# Download the checksum file alongside it
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.34.tar.xz.sha256
# Verify the download integrity
sha256sum -c linux-6.6.34.tar.xz.sha256
If the verification shows OK, you are good to go. If it shows FAILED, the download is corrupted and you should delete it and try again. Never build a kernel from a corrupted source — you will get strange build failures that are very difficult to debug.
Option B: Cloning the Git Repository
If your goal is to contribute patches to the kernel community, you need to work on the very latest version of the source. The mainline kernel repository is maintained by Linus Torvalds on kernel.org. Cloning it gives you the complete Git history and lets you create branches for your work.
# Clone Linus Torvalds' mainline kernel tree
# Warning: this is 3+ GB, takes time and bandwidth
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
The full clone includes the entire Git history of the project going back years. If you just want to explore the code or do a quick build, you can save time and disk space with a shallow clone. A shallow clone gives you only the most recent commits instead of the full history:
# Shallow clone with only the last 3 commits
# Much faster, much smaller download
git clone --depth=3 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
After cloning, you already have the source tree extracted in a directory called linux. There is no need to run tar — git clone handles the extraction automatically. So if you used Option B, you can skip Step 2 (extracting) and go directly to Step 3 (configuration).
|
YES ─── Clone with git (Option B)
| You need the latest mainline tree
|
NO
|
Does your project require a specific kernel version?
|
YES ─── Download the tarball (Option A)
| Pick the LTS version for your project
|
NO (just learning)
|
Download the latest LTS tarball (Option A)
Fastest way to get a stable working base
🧠 Key Takeaways
🎯 Interview Questions
The process has 7 steps: (1) obtain the source via tarball download or git clone, (2) extract the tarball if downloaded as a compressed file, (3) configure the kernel using make menuconfig, (4) build the kernel and modules with make -j all, (5) install the modules with sudo make modules_install, (6) set up the bootloader and initramfs with sudo make install, and (7) optionally customize the GRUB menu. This chapter covers Steps 1 to 3 in detail.
Use a tarball download when you need a specific, fixed kernel version for a product or learning project. It is faster and gives you a known-good snapshot. Use a Git clone when you want to contribute patches upstream, since you need to work on the very latest mainline code and be able to create branches and track history. For most beginners and embedded product developers, the tarball approach is the better starting point.
A shallow clone (using git clone –depth=n) downloads only the most recent n commits instead of the full project history. This dramatically reduces the download size and time. For a full Git clone of the Linux kernel, you need 3+ GB. A shallow clone with –depth=3 can bring that down significantly. It is useful when you just want to build the latest kernel or explore the source without needing the full history. However, if you need to investigate old commits, do git blame across many files, or bisect a bug, you need the full clone.
bzImage is the compressed kernel image that the bootloader (like GRUB) loads when the system starts. The “bz” stands for big-zipped. vmlinux is the raw, uncompressed kernel binary generated during the build. The bootloader uses bzImage because it is smaller and fits in memory more easily. vmlinux is used by kernel debugging tools like gdb, perf, and crash for analyzing kernel internals and crash dumps. You need vmlinux when debugging, but the system boots from bzImage.
Verifying the tarball with sha256sum ensures the downloaded file is not corrupted. A partially downloaded or corrupted tarball can cause strange and difficult-to-diagnose build failures. In the worst case, a tampered tarball (if you downloaded from an untrusted source) could introduce malicious code into your kernel. Always download from the official kernel.org CDN and verify the checksum before extracting.
A Device Tree Blob is a binary file that describes the hardware layout of a system to the Linux kernel — things like which peripherals are connected, their base memory addresses, interrupt numbers, and so on. DTBs are needed on ARM and other embedded architectures where hardware is not self-discoverable. On x86 PCs, hardware discovery happens through ACPI and PCI enumeration, so DTBs are not required. If you are doing embedded Linux work on a custom board or an ARM single-board computer, compiling and providing the correct DTB is an essential part of the build process.
