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]
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”
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.
.config
fileThe .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.
.config
fileDepending 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).
.config
from /proc
zcat /proc/config.gz > .config
.config
from /boot
cp /boot/config-`uname -r` .config
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:
Finally, we have menuconfig
:
make menuconfig
menuconfig
looks like this:
.config
and tipsWhen 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
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
It is important to pay attention in the installation order; we install modules as following:
Attention: Double your attention in the install steps. You can crash your system because you have executed all commands as a root user.
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
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.
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:
mkinitcpio
sudo cp /etc/mkinitcpio.d/linux.present /etc/mkinitcpio.d/linux-[name].present
Attention: Keep in mind that you have to adapt this file by yourself. There is no blind copy and paste here.
sudo mkinitcpio -p linux-[name].prensent
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]