Compiling a Linux Kernel

By | January 21, 2019

Rebuilding the Linux kernel is very interesting and sometime often scares off newbies. But there is nothing difficult in this, and compiling the Linux kernel is no more complicated than compiling any other source code. You may need to rebuild the kernel when you need to add some functions not included in the current kernel, or, on the contrary, you want to disable some of them. Or you simple want to migrate to the new kernel version. The main steps to select new kernel configuration, build the kernel and install it are presented below.


All further actions we will perform in Centos Linux. As example Centos6 virtual machine is used.


1. Check the current release of kernel:


# uname -r
2.6.32-358.el6.x86_64

2. Let us go to https://mirrors.edge.kernel.org/pub/linux/kernel/ and download higher version of kernel:


# curl -O https://mirrors.edge.kernel.org/pub/linux/kernel/v3.x/linux-3.18.5.tar.xz
  % Total % Received % Xferd Average Speed Time Time Time Current
     Dload Upload Total Spent Left Speed
100 77.2M 100 77.2M 0 0 2723k 0 0:00:29 0:00:29 –:–:– 2420k

3. Extract kernel 3.18.5 source into /usr/src/kernels directory:


# tar -Jxvf linux-3.18.5.tar.xz -C /usr/src/kernels/

4. Create symbolic link to new kernel source directory, switch to this directory and check its content:


# ln -s /usr/src/kernels/linux-3.18.5/ /usr/src/kernels/linux
# cd /usr/src/kernels/linux
# ls
arch     Documentation  init     lib          README          sound
block    drivers        ipc     MAINTAINERS   REPORTING-BUGS  tools
COPYING  firmware       Kbuild   Makefile     samples         usr
CREDITS  fs             Kconfig  mm           scripts         virt
crypto   include        kernel   net          security

5. Check if we have all necessary development tools and install them:


# yum grouplist “Development Tools”
Loaded plugins: fastestmirror, refresh-packagekit, security
Setting up Group Process
Loading mirror speeds from cached hostfile
 * base: centos.mirror.rafal.ca
 * extras: centos.mirror.rafal.ca
 * updates: centos.mirror.rafal.ca
Installed Groups:
  Development tools
Done

It is possible to check all group components and install only missing ones


# yum groupinfo “Development Tools”

but checking is time consuming process so install all “Development Tools”:


# sudo yum groupinstall “Development Tools”

6. Now everything is ready for compilation, but before verify
/usr/src/kernel/linux directory which contains Makefile. This file does all compiling jobs. Also the file has a lot of targets (options), use “make help” command to check all of them:


# make help
Cleaning targets:
  clean – Remove most generated files but keep the config and
          enough build support to build external modules
  mrproper – Remove all generated files + config + various backup files
  distclean – mrproper + remove editor backup and patch files

Configuration targets:
  config – Update current config utilising a line-oriented program
  nconfig – Update current config utilising a ncurses menu based program
  menuconfig – Update current config utilising a menu based program
  xconfig – Update current config utilising a QT based front-end
  gconfig – Update current config utilising a GTK based front-end
  oldconfig – Update current config utilising a provided .config as base
  localmodconfig – Update current config disabling modules not loaded
  localyesconfig – Update current config converting local mods to core
  silentoldconfig – Same as oldconfig, but quietly, additionally update deps
  defconfig – New config with default from ARCH supplied defconfig
  savedefconfig – Save current config as ./defconfig (minimal config)
  allnoconfig – New config where all options are answered with no
  allyesconfig – New config where all options are accepted with yes
  allmodconfig – New config selecting modules when possible
  alldefconfig – New config with all symbols set to default
  randconfig – New config with random answer to all options
  listnewconfig – List new options
  olddefconfig – Same as silentoldconfig but sets new symbols to their default value
  kvmconfig – Enable additional options for guest kernel support
  tinyconfig – Configure the tiniest possible kernel

Other generic targets:
  all – Build all targets marked with [*]
* vmlinux – Build the bare kernel
* modules – Build all modules
modules_install – Install all modules to INSTALL_MOD_PATH (default: /)
….

For exaplme: “make modules” is used to build all loadable modules
    “make bzImage” to create compressed kernel image (arch/x86/boot/bzImage)
    “make menuconfig” to update current config utilising a menu based program
    “make modules_install” to install all modules to INSTALL_MOD_PATH (default: /), usually /usr/lib/kernel directory is used
    “make install” to install to $(I

7. Compiling version 3 kernel
Start with cleaning just in case however it is not necessary, because no previous compilation was executed before.
Now start “# make menuconfig” config command to select what part of the kernel must be compiled.

After selecting compilation option the menuconfig editor saves them in hidden .config file.

After choosing configuration start compiling using “# make bzImage” target:

The compiling process may take 20 minutes or so.

Now we need to compile modules “# make modules”:

It takes some time and when it will be complited check content of /usr/src/kernels/ directory.
Currently it contains sources of old and new kernels:


# ls -l /usr/src/kernels/
total 8
drwxr-xr-x. 22 root root 4096 Apr 12 2017 2.6.32-358.el6.x86_64
drwxrwxr-x. 23 root root 4096 Jan 29 2015 linux-3.18.5

8. The next step is “make modules_install” which really copy files into appropriate directories structure:

9. It runs install.sh scrip creating System.map, coping accross the system map file, updating /etc/grub.conf file, creating initialization RAM disk and so on:

Installing of 6 modules failed, 2 of them related to NAT (we are using Bridge Adapter), others have different purpose for example soundcore module.
Every module error must be investigated separately and it is not a goal of this topic. Let check result of kernel compilation.

10. Verifying.
Open /etc/grub.conf file, we can see stanza pointing to new kernel:

This kernel is not a default one, to assign it to default we need to change default to 0:

The boot directory content shows the presence of new kernel file names, which have suffix 3.18.5:


# ls /boot
config-2.6.32-358.el6.x86_64           System.map
efi                                    System.map-2.6.32-358.el6.x86_64
grub                                   System.map-3.18.5
initramfs-2.6.32-358.el6.x86_64.img    initramfs-3.18.5.img
vmlinuz                                initrd-2.6.32-358.el6.x86_64kdump.img
vmlinuz-2.6.32-358.el6.x86_64          lost+found
vmlinuz-3.18.5                         symvers-2.6.32-358.el6.x86_64.gz

Now reboot the device and check default kernel version:


# uname -r
3.18.5

Leave a Reply

Your email address will not be published. Required fields are marked *