Posts /

Kernel Compilation and Installation

Twitter Facebook Google+
26 Feb 2017

Command Summary

Follows the list of commands used in the sequence:

.config manipulations:

zcat /proc/config.gz > .config

or

cp /boot/config-`uname -r` .config

Change .config file:

make nconfig
make olddefconfig
make kvmconfig
make localmodconfig

Compile:

make ARCH=x86_64 -j8
make modules_install

Install:

sudo make modules_install
sudo make headers_install INSTALL_HDR_PATH=/usr
sudo make install
sudo make install

Remove:

rm -rf /boot/vmlinuz-[target]
rm -rf /boot/initrd-[target]
rm -rf /boot/System-map-[target]
rm -rf /boot/config-[target]
rm -rf /lib/modules/[target]
rm -rf /var/lib/initramfs/[target]

Choose Your Weapon

Nowadays we have multiple options to play around with Linux Kernel. For simplicity sake, I classify the available approaches into three broad areas: virtualisation, Desktop/Laptop, and embedded device. The virtualisation technique is the safer way to conduct experiments with Linux kernel because any fatal mistake has a few consequences. For example, if you crash the entire system, you can create another virtual machine or take one of your backups (yes, make a backup of your running kernel images). Experiment on your computer is more fun, but also more risk. Any potential problem could break all your system. Finally, for the embedded device, you can make tests in a developing kit. In this section, we choose our weapons. We will work first with Qemu, followed by the local computer.

If you want to use Qemu for work, I recommend you to read my post about it in “Use Qemu to play with Linux Kernel

Get Your kernel

Linux project has many subsystems and most of them keep their clone of the Kernel. Usually, the maintainer(s) of each subsystem is responsible for receiving patches, and decide to apply or not the change. Later, the maintainer says to Torvalds which branch to merge. This explanation is an oversimplification of the process; you can find more details in the documentation. It is important to realise that you have to figure out which system you intend to contribute, discover their repository, and work based on their branch. For example, if you want to contribute to RISC-V subsystem you have to work on Palmer Dabbelt repository; if you’re going to contribute to iio use Jonathan Cameron repository. You can quickly figure out the target branch by looking at the MAINTAINERS file. For this tutorial, we use the Torvalds repository.

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

There are thousands of forks from Linux Kernel spread around the Internet. It is possible to find entire organisations that keep their branch of the Kernel with their specific changes. Also, you can find a mirror from Torvalds on Github. Few free to use it, but keep in mind that you may encounter some problems with non-official repositories. I prefer to use the git.kernel.org to use because it simplifies future works.

The Super .config file

The .config file keeps all the configurations used during the Kernel compilation. In this file, you can find which subsystem and configuration will be compiled or not. The .config file has three possible answers per target: (1) m, (2) y, and (3) n. The “m” character means that the target will be compiled as a module; the ‘y’ and ‘n’ designates if the target will be compiled or not as a part of the Kernel image.

Every Linux Distribution (e.g., Arch, Debian, and Fedora) usually maintain and distribute their own .config file. The distributions .config file; normally enables most of the available options (especially the device drivers) because they have to run in a large variety of hardware. It means that you may have various device driver on your computer that you do not need. Nonetheless, the important thing here is: the more options you have enabled in the .config file, more time will be taken by the compilation.

If it is your first attempt to use your own compiled kernel version, I strongly recommend you to use the .config file provided by your distribution to increase the chances of success. Later, you can expand the modification as we describe in this tutorial.

If it is your first attempt to use your own compiled kernel version, I strongly recommend you to use the .config file provided by your distribution to increase the chances of success. Later, you can customize things as we describe in this tutorial.

Attention: The .config file has Superpower, I recommend you to invest some time to understand it better. Also, save your working .config files, it will save time for you.

Get your .config file

Depending on the distribution which you use, there are two options to get .config file: from /proc, or /boot. Both cases produce the same results, but it is not all distribution that enables /proc option (e.g., Arch enable it, but Debian not). The command bellow makes the copy, notice that I suppose that you are in the Linux Kernel directory (previously cloned).

  1. Get .config from /proc
zcat /proc/config.gz > .config
  1. Get .config from /boot
cp /boot/config-`uname -r` .config

Make your customizations

Attention: There is a basic rule about .config file: NEVER CHANGE IT BY HAND, ALWAYS USE A TOOL

There are several options to change the .config manually file. I introduce two:

make nconfig

nconfig looks like this:

Foo
nconfig

Finally, we have menuconfig:

make menuconfig

menuconfig looks like this:

Foo
Menuconfig

Final considerations about .config and tips

When you use a configuration file provided by a Linux Distribution, hundreds of device drivers are enabled; typically, you need a few drivers. All the enabled drivers will raise the compile time with no need for you; fortunately, there is an option that automatically changes the .config file to enable only required drivers. Nonetheless, before using the command, it is highly recommended to enable all the devices that you use with your computer to ensure that .config file have all the required driver for your machine enabled. In other words, plug all the devices that you usually use before executing the command:

make localmodconfig

Remember: Enables all the device

This command, basically uses lsmod to check the enables or disables devices drivers in the .config file.

Sometimes, when you rebase your local master branch with the remote you will notice when try to compile that some questions are raised related to the ativation or deactiavion of features. This happens, because during the evolution of the Kernel new features are added that was not in present in you .config file. As a result, you are asked to take a decision. Sometimes, there is a way to partially reduce the amount of asked question with the command:

make olddefconfig

Finally, one last tip is related for someone that make experiments in the Qemu with Kvm. There is an option that enables some important features for this scenario:

make kvmconfig

Compile!

Now, it timeeeeee! After a bunch of setup, I am quite sure that you anxious for this part. So, here we go… type:

make -j [two_times_the_number_of_core]

Just replace the two_times_the_number_of_core for the number of cores you have by two. For example, if you have 8 cores you should add 16.

This command uses lsmod to check the enables or disables devices drivers in the .config file.

make ARCH=x86_64 -j [two_times_the_number_of_core]

For compiling the kernel modules, type:

make modules_install

Compilation Outputs

Install new your custom kernel

It is important to pay attention in the installation order; we install modules as following:

  1. Install modules
  2. Install header
  3. Install Image
  4. Update bootloader (Grub)

Attention: Double your attention in the install steps. You can crash your system because you have executed all commands as a root user.

Install modules and headers

Just type:

sudo make modules_install

If you want to check the changes, take a look at /lib/modules/$(uname -r)

Finally, install headers:

sudo make headers_install INSTALL_HDR_PATH=/usr

Install new image (works on Debian)

Finally, it is time to install your Kernel image. This step does not work on Arch Linux, see next section if you are interested in Arch.

To install the Kernel module just type:

sudo make install

We are, reallyyyyy close to finishing the process. We have to update the bootloader, and here we suppose you are using Grub. Type:

sudo update-grub2

Notice, that the command below is a wrapper to the following command:

sudo grub-mkconfig -o /boot/grub/grub.cfg

So… If the first command fails, try the last one.

Now, reboot your system and check if everything is ok.

Arch Linux Installation

If you use Arch Linux, we present the basics steps to install your custom image. You can find a detailed explanation of this processes in the Arch Linux wiki.

First, you have copied your kernel image to the /boot/ directory with the command:

sudo cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-[name]

Replace [name] by any name. It could be your name.

Second, you have to create a new mkinitcpio. Follow the steps below:

  1. Copy an existing mkinitcpio
sudo cp /etc/mkinitcpio.d/linux.present /etc/mkinitcpio.d/linux-[name].present
  1. Open the copied file, and look it line by line and replaces the old kernel name by the name you assigned. See the example:

Attention: Keep in mind that you have to adapt this file by yourself. There is no blind copy and paste here.

  1. Generate the initramfs
sudo mkinitcpio -p linux-[name].prensent

Remove

Finally, you may want to remove an old Kernel version for space or organization reasons. First of all, boot in another version of the Kernel and follow the steps below:

rm -rf /boot/vmlinuz-[target]
rm -rf /boot/initrd-[target]
rm -rf /boot/System-map-[target]
rm -rf /boot/config-[target]
rm -rf /lib/modules/[target]
rm -rf /var/lib/initramfs/[target]

References

  1. Install customised kernel in Arch Linux
  2. Overview about Initramfs
  3. Practical stuffs about Initramfs
  4. Great explanation about initramfs
  5. More about initramfs
  6. Nice discussion in Stack Exchange about bzimage in qemu
  7. Kernel Readme
  8. Speedup kernel compilation
  9. Stack Overflow with some tips about speedup kernel compilation
  10. SYSTEMD-BOOT
  11. cpio tutorial
  12. Busybox, build system

Twitter Facebook Google+