A quickstart guide to building Linux for the first time.
Daunting at first, building Linux yourself is rewarding, useful, & highly educational. In this post, I'll outline everything you need to build & test your own kernel from a Debian-based operating system, like Ubuntu. Most of what I'm sharing here I learned from trying to build my own pet distro.
Step 0: Ready your compiler & host tooling
Before we even think about downloading a source archive, we need to ready our host system with the tools necessary to compile Linux. The commands outlined in this section are Debian/Ubuntu specific, so if you use another distro or operating system, you will need to work out a different set of incantations.
First, lets install a minimal toolchain containing a C / C++ compiler, and debian package tooling.
sudo apt-get install build-essential
So now we have a C compiler, but we still need to install the remaining tooling.
Fortunately for us, debian-based distributions track the dependencies required to build each package against each package, so if we can figure out how to
install all the packages in the build dependencies list for the
linux package, we are done. Huzzah!
Apt-get again comes to the rescue and makes this easy:
sudo apt-get build-dep linux
Step 1: Download & unpack Linux source
The kernel folk keep sourcecode for all the different versions of Linux neatly packed at kernel.org, so go ahead and pick a reasonably-recent version. For the sake of this post, we will use 5.4.20, with a direct download here.
Its good practice to check the hash of your downloaded file to make sure its authentic, even if it was delivered over HTTPS. From checking other sources the
archive SHA256 is
793f6dcd9a7074dc61bbb092b40b3ce9567f776f21589ecd09f07bc9ed5c67bb, so we can check it like this:
Looks good to me!
[xxx@xxx]:/tmp> sha256sum linux-5.4.20.tar.xz 793f6dcd9a7074dc61bbb092b40b3ce9567f776f21589ecd09f07bc9ed5c67bb linux-5.4.20.tar.xz
Lastly, lets unpack it into its own directory structure. For the sake of this post, lets unpack & build it in
mkdir /tmp/linux-5.4.20 tar -xf linux-5.4.20.tar.xz linux-5.4.20 --directory /tmp/linux-5.4.20 cd /tmp/linux-5.4.20
- Directory and file names are version-dependent - make sure you update the commands if you are using a different version of Linux.
- We referenced the directory
linux-5.4.20after the archive filename
linux-5.4.20.tar.xz. We did this because the archive contains the folder
linux-5.4.20, and we want to extract its contents. If we didn't specify
linux-5.4.20, the source code would have been extracted to
Step 2: Configure Linux how you like it
As you can imagine, theres heaps of options you can tweak to configure how Linux operates and what pieces are included. These options are expressed in the
Kconfig file, which is located at
.config once generated (If you extracted Linux to the same directory as in step 1, thats
Before I tell you how to build this file, know this: Its easy to get overwhelmed about the myriad of options available to you and what they mean. Don't worry too much, just pick a starting point, and update your config + rebuild Linux as you need to change things.
Establishing a Kconfig file for the first time
The easiest way to get started is to generate your Kconfig based on the current system. Run this:
This command will take the current Kconfig of your running system, and use that. New options will be set to their default values. The
generated file will be written to
If you run it a second time (specifically, if a
.config file already exists), it will use the existing configuration, but set
any missing options to their default values.
Tweaking your Kconfig
Linux ships with a nice, menu-based configurator, which you can easily invoke like this:
You'll be able to browse around at your own leisure using the keyboard, manually investigating, enabling, and disabling options as you please. You can enable a highlighted option
y, disable an option with
n, and (if supported, symbolized by angle brackets preceeding the option) compile it as a module using
Setting an option as a module (ie: pressing
m) means enabling that option, but compiling it into its own file (which can be loaded only if its needed) rather than bloating
the kernel. If you want to enable something and it supports being set as a module, enable it as a module (rather than pressing
y) unless theres a good reason.
Scripting changes to Kconfig
Resist the temptation to manually edit
.config, unless you are sure of what you are doing. This is because some options depend on others or are incompatible with other options.
Instead, use provided tooling to script changes to Kconfig, and then run
y) an option
scripts/config --enable CONFIG_MODULE_UNLOAD
n) an option
scripts/config --disable CONFIG_MODULE_UNLOAD
m) an option as a module
scripts/config --module CONFIG_INTEL_MEI_ME
If you were wondering,
make olddefconfig runs through your configuration to make sure its consistent, and for any missing options, sets them to defaults.
Step 3: Build Linux
All the hard work is done! The last thing you need to do is kick off the build, and go get coffee while you wait.
make -j 8 deb-pkg # Replace 8 with the number of cores your system has
deb-pkgnot only builds Linux, but packages it neatly into a debian package we can copy, or install. We could have just run
makeif we didn't want it neatly packaged.
Step 4: Install Linux
Thanks to the
deb-pkg recipe, our newfangled kernel is now packaged neatly into three debian packages, one directory below our source directory:
[xxx@xxx]:/tmp/linux-5.4.20> ls -lah ../*.deb -rw-r--r-- 1 xxx xxx 11M Feb 17 16:58 ../linux-headers-5.4.20_5.4.20-1_amd64.deb -rw-r--r-- 1 xxx xxx 8.9M Feb 17 16:58 ../linux-image-5.4.20_5.4.20-1_amd64.deb -rw-r--r-- 1 xxx xxx 1.1M Feb 17 16:58 ../linux-libc-dev_5.4.20-1_amd64.deb
In most cases you only need to install the
linux-image-KERNEL_VERSION package, like this:
However, If you expect to develop userland or kernel code, you probably want to install all 3:
sudo dpkg -i ../linux-image-5.4.20_5.4.20-1_amd64.deb
sudo dpkg -i ../linux-*.deb.
dpkg will take care of adjusting your boot filesystem, initrd, and grub configuration to make your new kernel available. Enjoy your