Linux kernel is freely available to be build by using any of its hundred of pre configured setups or by tuning the one you need by your self. First of all, you must fullfill all the dependencies needed to compile the kernel, I will not cover them but must have: flex, bison, libssl and gcc among others.


Checking my current Linux kernel setup on my Ubuntu system

Our current linux setup is saved on a file located on the boot folder named with our current linux version. So, the first point is to check our linux kernel version:

uname -r

Once we know our kernel release (4.15.0-29-generic) we are able to find the setup:

cat /boot/config-4.15.0-29-generic


Some of the important settigns

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" # This tells which architecture compile as well as which default configuration file get
CONFIG_X86=y # When we compile for ARM we will change this variables


What we are gonna do is to reuse those settings with the new kernel version we are going to compile, if we just compile the kernel with a not valid setup we may not able to boot up the system.


Downloading the kernel

Linux kernel is always available through where you can download either the latest stable version or any other you prefer. In my case I will download the stable v4.20 while my current kernel is v4.15


Entering to the graphical menu config

make menuconfig


What compile? What generate?

make help

 This command will show you all the typical targets generated when compiling linux. In my case I will generate a kernel based on my previous configuration doing the following:

cp /boot/config-4.15.0-29-generic .config
make menuconfig # Save the changes you do
make vmlinux

 The output will be the statically linked linux kernel named vmlinux. But is this format the one we need to replace our current kernel? The answer is not, in order to be able to replace it we need to know what we want to replace so let'ts discover it:

# file /boot/vmlinuz-4.15.0-29-generic 
/boot/vmlinuz-4.15.0-29-generic: Linux kernel x86 boot executable bzImage, version 4.15.0-29-generic (buildd@lgw01-amd64-057) #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018, RO-rootFS, swap_dev 0x7, Normal VGA

 If you check make help command your probably saw that one of the targets was bzImage, that target will be the one which will generate our linux kernel:

make bzImage

 The output will be generated on the architecture folder (arch/x86/boot/bzImage)


Installing the kernel

There are a sequence of steps in order to install our new kernel to be used

  1. Install the kernel. It updates the vmlinuz images on /boot
    1. sudo make kernel install
  2. Install the modules. It updates the kernel modules (.ko files)
    1. sudo make modules_install
  3. Update the init ram file system. Generates the initrd files
    1. sudo update-initramfs
  4. Update the Grub configuration
    1. sudo update-grub


Modifying the open system call to generate a printk message

printk linux kernel routine is in charge of printing the different kernel messages applying the message level for each case. We are going to modify the open system call routing to print a message every time a that route is called. That file is located on fs/open.c and the routine is defined on the following way: SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)

SYSCALL_DEFINE3 means open routine has three parameters:

  • filename
  • flags
  • mode

By adding this line:

printk(KERN_WARNING "%s : Trying to open a file\n", __FUNCTION__);

 we will print this line every time the open kernel routine is called. The you just need to build and install again the kernel to test the changes. By entering dmesg command on your console you must find several of them.