In order to doing some research in operating system, I need to build Linux kernel from source. Although my GNU/Linux distro provide Linux kernel package which ready to use, I can not use it for Linux Kernel development. It is recommended to be able build my own Linux kernel in order to customize my build.

Build & Install

To build the Linux kernel from source, I need several tools: make, gcc, libssl-dev, git and (optionally) ctags, cscope, and/or ncurses-dev. make & gcc is essential tools to build binaries from source. libssl-dev is for cryptography purpose. git is used for control the revision of the source code, it is recommended if I want to submit patch regarding Linux Kernel. The ncurses-dev tools are used if I make menuconfig or make nconfig. The tool packages may be called something else in some Linux distribution, so I may need to determine the package first.

I use Ubuntu, so I can get these tools by running:

sudo apt install make gcc libssl-dev bc git exuberant-ctags libncurses5-dev

If you using different Linux distro, on Red Hat based systems like Fedora, CentOS you can run:

sudo yum install gcc make git ctags ncurses-devel openssl-devel

And on SUSE based systems (like SLES, Leap or Tumbleweed), you can run:

sudo zypper in git gcc ncurses-devel libopenssl-devel ctags cscope

If you develop using git, there are different development tree of Linux Kernel available. Different tree serve different purpose. Some of them I often use:

  • rc: The latest version out from Linus Torvald tree. It serves main purpose to include some new feature or fix which ready for testing. Not recommended for production use.
  • stable: Kernel marked stable are come from the stable maintainer which currently done by Greg-Kroah Hartman. This version good for production use.
  • staging: The staging tree is collection of new driver which not yet ready to be included in Linus rc tree. This one highly recommended for new and aspiring Linux Kernel developer who want to contribute.

I need to change configuration parameters to determine which settings and modules which need to build. Several options available:

1. Use default kernel configuration.

This settings comes from the kernel maintainer. Remember, a default config may not have the options you are currently using.

$ make defconfig

2. Use existing configuration.

Just press “Enter” when asked for configuration options.

$ make localmodconfig

3. Manual selection with graphical menu.

$ make menuconfig

Compiling a kernel from scratch from a distribution configuration can take “forever” because the distros turn on every hardware configuration possible. For people wanting to do kernel development fast, you want to make a minimal configuration. Steve Rostedt uses ktest.pl make_min_config to get a truely minimum config, but it will take a day or two to build. Warning: make sure you have all your USB devices plugged into the system, or you won’t get the drivers for them!

4. Duplicate current config.

When I want to see if a bug is fixed, I can duplicate the configuration on my running kernel. That config file is stored somewhere in /boot/. There might be several files that start with config, so I can use the one associated with your running kernel. I can find it by running uname -a and finding the config file that ends with my kernel version number. I copy that file into the source directory as .config. Or just run this command:

$ sudo cp /boot/config-`uname -r`* .config

Among these options, I tend to use latest option because it use config from distro developer and cause it recognizes most of my hardware.

Then, compile source, this process can take a while.

$ make -jX

Where X is a number like 2 or 4. If you have a dual core, 2 or 3 might be good. Quad core, 4 or 6. Do not run with really big numbers unless you want your machine to be slow. You can check the number with:

$ cat /proc/cpuinfo

On my machine, there are 0-3 processor available. I want to use all of these resources to perform the compiling process. So I can use make -j4.
This compiling process can take a lot of time. So you can make the time to do some other interesting tasks such as read books of Linux Kernel development, read LWN, lurking on LKML, etc.

Install modules.

$ sudo make modules_install

Bootloader setup.

$ sudo make install

Double check bootloader setup.

$ sudo update-grub2

Reboot the system. I can check my new installed kernel with this command.

$ uname -a

Enjoy the new kernel.

Remove

When there is such as installation process, then there should be the unintallation process too.
Fist I need to find out the version of custom kernel. I can look at /boot directory.

$ ls /boot/

There are several files. I can refer to the vmlinuz files to determine which version I need to process.

/boot/vmlinuz-4.15.0-23-generic
/boot/vmlinuz-4.15.0-29-generic
/boot/vmlinuz-4.18.0-rc5
/boot/vmlinuz-4.18.0-rc6

In this example, I want to remove kernel version 4.18.0-rc5.
But, before doing this, I must ensure that my system has other kernel installed beside $CUSTOM_KERNEL_VERSION. Also I must ensure that I not removing kernel which I currently running on, because it can lead to unexpected behaviour of my system. When everything is okay, I can delete all files and folders which contain $CUSTOM_KERNEL_VERSION name.

$ CUSTOM_KERNEL_VERSION="4.18.0-rc5"
$ sudo rm /boot/vmlinuz-$CUSTOM_KERNEL_VERSION
$ sudo rm /boot/initrd.img-$CUSTOM_KERNEL_VERSION
$ sudo rm /boot/System.map-$CUSTOM_KERNEL_VERSION
$ sudo rm /boot/config-$CUSTOM_KERNEL_VERSION
$ sudo rm -rf /lib/modules/$CUSTOM_KERNEL_VERSION/
$ sudo rm /var/lib/initramfs-tools/$CUSTOM_KERNEL_VERSION

Lastly, I do some cleaning.

$ sudo update-initramfs -k all -u
$ sudo update-grub2

Finish. My kernel has been successfully uninstalled.