An artisan, home made, hand crafted kernel, runs faster, feels smoother and sounds better. It's a learning experience that brings us back to our roots - let's build a kernel like our grandmothers used to make. So sit back, relax, and enjoy the smooth sounds of a compiling kernel.
How to build the Linux Kernel
The following instructions are based on CentOS 7, these should work for most other distributions, however, the initial dependencies will need to be reviewed.
Unless prefixed with
sudo, all commands can be executed as a non-root user.
There’s a few reasons why you’d want to build your own kernel, however, most of the point below aren’t significant.
- Access recent enhancements not yet available in Linux distributions, in my case, I wanted to continue to run CentOS on my server, but build my kernel myself to access modern features (prebuilt unsupported Kernels are available).
- Learning exercise - this was my secondary reason.
- Creating a slimmer Kernel for performance (with many modules only being loaded when needed, I’m not sure on this)
- Security’s sake (this requires you to be vigilant to always update the Kernel yourself)
In this case, we want tools like
gcc (for compiling) and
ncurses (for menuconfig):
$ sudo yum groupinstall "Development Tools" $ sudo yum install ncurses-devel -y
Fetch the Kernel source
Go to kernel.org to fetch the kernel version that you’d like, most likely, you’ll just want the latest stable.
$ mkdir linux $ cd linux/ $ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.1.tar.xz $ tar xfJ linux-3.18.1.tar.xz $ cd linux-3.18.1/
Configure the Kernel
To preconfigure my kernel, I’m using the existing configuration options based on CentOS’s current running Kernel. This’ll help me compile everything I need, and just look for the specific options I want or don’t want.
The Kernel also comes with options to build a default config (
make defconfig), but I don’t know exactly how this
configuration is built. Some options are set in
arch/x86/configs/x86_64_defconfig, but not all.
But for the moment, I’ll reuse CentOS’s but you could use the default by running
make defconfig instead of the
$ cp /boot/config-`uname -r ` .config
If you’re using CentOS’s default from an older Kernel, you’ll want to upgrade the .config file to incorporate the new
options. The command
make olddefconfig will upgrade the .config file, setting the default values without prompting.
Alternatively, you can run
make oldconfig which prompts for answers to each configuration option. Only run this if
you’re upgrading the .config file (not using a .config file build from
$ make olddefconfig
From here, I use
menuconfig, a ncurses based interface to choose Kernel configuration options. There’s also GTK+ (
gconfig), QT (
make xconfig), a purely text based option (
$ make menuconfig
Compile the Kernel
This process takes a while, depending on options and CPU age and number of CPUs, less so disk IO speed. Optionally, and
likely recommended, is to supply the
-j [jobs] flag, this specifies the number of jobs running concurrently - you’ll
want to set this number to the number of CPUs in your system.
In my case, because I have 2 CPUs, I would run:
$ make -j 2
Because I wanted to time the events, and run at a higher concurrency rate (long story short, it didn’t perform any better), I used the following command to also include timing information:
$ START_DATE=`date`; time make -j4; echo "Start date: $START_DATE"; echo -n "End date: "; date real 350m30.902s user 440m34.103s sys 224m7.598s Start date: Wed Dec 24 09:42:43 ACDT 2014 End date: Wed Dec 24 15:33:14 ACDT 2014
Grab a tea, this’ll take a while if you’re running older hardware (in my case, a Virtual Box guest on a 2008 2.4GHz Core 2 duo).
Install the Kernel
This process is far quicker, but may still take a few minutes depending on your disks. Note, only now do we need to run as a root user.
$ sudo make modules_install $ sudo make install
Your Kernel is not built and installed, it should have also updated GRUB configuration. But in some cases, you may
need to run
mkinitrd, but it appears
make install did more work than I expected.
In my final case, I wanted this new Kernel to be my default, so I set it like so:
$ sudo grub2-set-default 0