Lab 7: The Linux kernel¶
Objectives¶
After completing this lab, you will be able to:
- install a new kernel from a binary package
- compile and install a new kernel from source files
Estimated time to complete this lab: 90 minutes
kernel¶
One of the tasks you might occasionally need to perform while administering a Linux system will be to upgrade or troubleshoot something related to the operating system kernel.
The kernel is the heart of the Linux operating system. It is the one thing that the various distributions of Linux (Rocky Linux, Red hat, Mandrake, SuSE, Yellow dog etc) have in common. It is responsible for managing various system resources and serves as an abstraction layer between the system hardware and the software that interfaces with the system, by providing hardware drivers.
The kernel is always being improved, and new features are always added to it or bugs fixed. As an administrator you may need to upgrade to the newest kernel because:
- The newer kernel contains bug fixes or specific desirable optimizations
- It repairs security holes that were present in the old kernel
- It contains drivers for a piece of hardware that you couldn’t use with the old kernel
Kernel source code and versions¶
The kernel comprises over a million lines of C programming code. This constitutes what is known as the Kernel source code.
The main repository for the kernel is the kernel website maintained under the URL:
At this site, you'll always find the kernel's latest [and oldest] versions.
As already mentioned, the kernel is common amongst all the various Linux distributions. These distributions sometimes re-package the source code for the kernel to make installation and upgrades easier or to suit their particular distribution.
The various Kernel source code versions use the following naming convention:
linux-<kernel.version>.tar.bz2 (or linux-<kernel.version>.tar.gz)
The current convention is to name and number major new kernel releases as “Linux 5.x” (also called the vanilla or mainline kernels). Thus, the first of this series will be Linux version 5.0 (same as 5.0.0), the next will be Linux version 5.1 (same as 5.1.0), followed by Linux version 5.2, and so on.
Any minor changes or updates within each major release version will be reflected by increments to the third digit. These are commonly referred to as stable point releases. Thus, the next stable point release for the 5.0.0 series kernel will be Linux version 5.0.1, followed by version 5.0.2, and so forth. Another way of stating this is to say, for example, that Linux version 5.0.4 is the fourth stable release based on the Linux 5.0.0 series.
kernel modules¶
Modules are shared object files (with names like module_name.o, module_name.ko etc). Think of modules as you would drivers in Microsoft Windows.
Modules are chunks of kernel code which may or may not be included directly in the kernel. They are compiled separately and can be inserted and removed from the running kernel at anytime. Modern systems make extensive use of loadable module support. Loadable modules offer various advantages such:
- It reduces the overall size of the final kernel image - since they are not strictly a part of the running kernel.
- It saves RAM - they are only loaded into RAM when needed
Some modules need to be directly compiled into the kernel while it is okay to make others separate loadable modules.
The choice of when to make a particular feature available as a module or to compile it into the kernel is usually fairly straightforward. In general, if it is infrequently used and performs as needed as a module, you should compile it as a module.
Configuring the kernel¶
There are generally three methods by which the kernel can be managed on Linux distributions. These are:
-
Using the prepackaged version of the kernel from the distributions vendor. e.g. using kernel-
<version>
.*.rpm. This is the safest, easiest and most preferred recommended. -
Via patching. Using patch files like - patch-kernel.version.gz.
-
Compiling the kernel from source e.g. using linux-kernel.version.tar.bz2
You will upgrade your running kernel to a slightly more recent version in the following exercises. You will first use a prepackaged (binary) version of the Linux kernel to perform the upgrade.
Exercise 1¶
Upgrade from binary [rpm] package¶
In this exercise you will directly upgrade your kernel using the rpm application.
To upgrade the kernel using rpm¶
-
Ensure you are logged into the system as root.
-
Run the
rpm
utility to list all kernel packages currently installed on the system. Type:rpm -q kernel
-
Execute the
uname
utility to view some information about the current running kernel. Type:uname --kernel-release 5.*.el9_8.x86_64
Make a note of the version/release number in your output.
-
Use
dnf
to download the latest kernel package available from the official Rocky Linux package repository. Type:dnf download kernel
You should now have an RPM package with a name similar to kernel-*.x86_64.rpm saved in your PWD.
-
Use
rpm
again to query the downloaded package for more information about itself. Type:[root@localhost ~]# rpm -qip kernel-*.x86_64.rpm
-
Use
rpm
to do a test install of the downloaded kernel*.rpm to ensure that all its dependencies will be met. Type:$ rpm --test -ivh kernel-*.x86_64.rpm error: Failed dependencies: kernel-core-uname-r = *.x86_64 is needed by kernel-*.x86_64 kernel-modules-uname-r = *.x86_64 is needed by kernel-*.x86_64
From the output we can see that the package has unmet dependencies.
-
Use
dnf
to download the needed dependencies reported in the previous error message. Type:dnf download kernel-core-uname-r kernel-modules-uname-r
-
Run
rpm
with the test option again to see if the kernel package can be upgraded. Type:$ rpm --test -Uvh kernel-*.rpm Verifying... ################################# [100%] Preparing... ################################# [100%]
Everything looks good this time!
-
Finally use
rpm
to install the kernel package along with all its dependencies. Type:sudo rpm -ivh kernel-*.rpm
-
Use
rpm
to list all the installed kernel packages on your system.Question
What is different between the output of the rpm -q kernel command - before and after you installed the new kernel?
-
We are done with using RPM to manage kernel packages on the system directly. Uninstall the latest kernel package that you downloaded and installed. For this, you'll need to specify the exact and correct name-epoch-version-release-architecture (NEVRA) info for the kernel and its associated dependencies that you want to uninstall. Type:
[root@localhost ~]# rpm -e \ kernel-<NEVRA> \ kernel-core-<NEVRA> \ kernel-modules-<NEVRA>
Exercise 2¶
Upgrade from the package repository¶
In this exercise you will upgrade your kernel using the dnf
application. DNF is a package manager for RPM-base Linux distributions. It can be used to manage system packages using configured online repositories.
To upgrade the kernel using DNF¶
-
Ensure you are logged into the system as root.
-
Use
dnf
to list all kernel packages installed on the system as well as kernel packages available on the remote package repository. TYpe:[root@localhost ~]# dnf list kernel
-
Use the
dnf
program to check for any updated kernel packages available. Type:[root@localhost ~]# dnf check-update kernel
You may or may not see any available kernel package updates on your system; Your output depends on how recently you updated the entire system.
-
If you see a new version of the kernel listed as being available, you can use
dnf
to query the remote repository for more information about the package by running:[root@localhost ~]# dnf info kernel --available
-
Use
dnf
to automatically find, download, and install the latest kernel package available in the remote package repository. Type:[root@localhost ~]# dnf -y update kernel
-
Now list the installed kernel packages. Type:
[root@localhost ~]# dnf list kernel --installed
Exercise 3¶
Upgrade the kernel from source¶
In this exercise you will build a new kernel from source, by configuring, compiling, and installing it yourself.
To upgrade the kernel from source¶
Notes
The kernel version used in this exercise was the latest available at the time. The latest version available at the time you are reading this material may be different. An asterisk () has been used to denote the particular kernel version used. You will need to replace the "" with the specific version you are using. For example, assuming the kernel version used in the steps below was - 6.6.13.4 - the kernel will be referred to as version 6.6.*
-
Log into the system as a user with Administrative privileges.
-
Install needed development tools. Type:
sudo dnf -y groupinstall 'Development Tools'
-
Install the needed libraries and tools. Type:
sudo dnf -y install ncurses-devel bc openssl-devel elfutils-libelf-devel python3 dwarves
-
Download the latest kernel source by typing:
[root@localhost ~]# curl -L -o linux-6.5.7.tar.xz \ https://www.kernel.org/pub/linux/kernel/v6.x/linux-6.5.7.tar.xz
Note that linux-6.5.7.tar.xz just happens to be the latest kernel available at time of this writing. You should substitute linux-6.5.7.tar.xz or linux-6.*.tar.xz with whatever version of the kernel that you choose to follow along this exercise with.
-
Unpack the kernel tarball into your pwd. Type:
[root@localhost ~]# tar xvJf linux-6.*.tar.xz
The tar command will create a new directory called: “linux-6.*” under your PWD.
-
List the contents of the new kernel source directory
-
Change (cd) into the kernel source directory. Type:
cd linux-6.5.7
-
Clean (prepare) the kernel build environment by using the
make mrproper
command. Type:make O=~/build/kernel mrproper
-
Copy over and rename the preexisting configuration file from the /boot directory into our kernel build environment:
cp /boot/config-`uname -r` ~/build/kernel/.config
-
Launch the graphical kernel configuration utility. Type:
make O=~/build/kernel menuconfig
A screen similar to this will appear:
Note
The kernel configuration screen that appears is divided into roughly three areas:
-
The top part shows various helpful information, keyboard shortcuts, and legends that can help you navigate the application.
-
The main body of the screen shows an expandable tree-structured list of the overall configurable kernel options. You can further drill down into items with arrows in the parent to view and/or configure sub-menu (or child) items.
-
Finally, the bottom of the screen displays the actual actions/options that the user can choose.
-
-
For demonstration purposes you'll add Btrfs filesystem support to the new kernel. In the main configuration screen, use your arrow keys to navigate to and highlight the File systems item. With File systems selected, press Enter to view the sub-menu or child items for File systems.
In the File Systems section, use your arrow keys to navigate to Btrfs filesystem support.
-
With Btrfs filesystem support highlighted, press
y
to include support forbtrfs
in the custom kernel. When you are done, an asterisk symbol (*) should appear beside the highlighted option. The final screen should look like the one shown here: -
Return to the main kernel configuration screen by pressing Esc twice on your keyboard.
-
Exit the kernel configuration application by pressing Esc twice again on your keyboard. Exiting the kernel configurator will force saving your changes to the .config file in the root of the kernel source tree.
-
A dialog box will appear prompting you to save your new configuration. Ensure that Yes is selected and then press Enter.
-
After the kernel configuration utility exits, you will be thrown back to your shell—inside the kernel source tree.
Tip
To view the results of some of the changes you made using the
menuconfig
tool, use the grep utility to view the .config file that you saved directly. For example, to view the effect of you enablingbtrfs
filesystem support, type the following:# grep ^CONFIG_BTRFS_FS ~/build/kernel/.config CONFIG_BTRFS_FS=y
-
Let's optimize the kernel build time and also reduce the amount of disk space used during the kernel compile stage. By setting
CONFIG_DEBUG_INFO=no
, the resulting kernel image will NOT include debugging info thereby resulting in a smaller kernel image. This removes debugging symbols from the built kernel and modules. Type:$ ./scripts/config --file ~/build/kernel/.config -d DEBUG_INFO \ -d DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT -d DEBUG_INFO_DWARF4 \ -d DEBUG_INFO_DWARF5 -e CONFIG_DEBUG_INFO_NONE
-
Complete another important step for custom Kernels on Rocky Linux distribution. Type:
sed -ri '/CONFIG_SYSTEM_TRUSTED_KEYS/s/=.+/=""/g' ~/build/kernel/.config
-
Add a simple customization to the new kernel, allowing you to distinguish it from the other stock Kernels more easily. For this, use the
sed
utility to edit the Makefile in place. Type:sed -i 's/^EXTRAVERSION.*/EXTRAVERSION = -custom/' Makefile
-
Verify the full version of the kernel that you just customized by passing the
kernelversion
target to themake
command. Type:make O=~/build/kernel kernelversion
OUTPUT:
make[1]: Entering directory '/home/rocky/build/kernel' 6.5.7-custom make[1]: Leaving directory '/home/rocky/build/kernel'
-
You are ready to compile the kernel. Type:
sudo make O=~/build/kernel -j $(nproc)
OUTPUT:
make[1]: Entering directory '/root/build/kernel' SYNC include/config/auto.conf.cmd GEN Makefile HOSTCC scripts/kconfig/conf.o ...
-
After the compilation completes successfully, you'll end up with the finished kernel stored here:
~/build/kernel/arch/x86/boot/bzImage
-
Install the portions of the kernel that were configured as modules. Type:
sudo make O=~/build/kernel modules_install
-
With the kernel now built it's time to install it. Type:
sudo cp ~/build/kernel/arch/x86/boot/bzImage \ /boot/vmlinuz-<kernel-version>
Replace
<kernel-version>
with the version number of your custom kernel. For the sample kernel we are using in this guide, the filename would be vmlinuz-6.*-custom. So here’s the exact command for this example:sudo cp ~/build/kernel/arch/x86/boot/bzImage /boot/vmlinuz-6.5.7-custom
-
Copy over and rename the corresponding System.map file into the /boot directory using the same naming convention:
sudo cp -v ~/build/kernel/System.map /boot/System.map-6.5.7-custom
-
Use the
kernel-install
utility to complete the file step. Type:sudo kernel-install add 6.5.7-custom /boot/vmlinuz-6.5.7-custom
-
The
kernel-install
utility will create a new boot entry in the boot loader configuration file. For EFI based systems you can look under /boot/loader/entries/ for matching entries. -
Run the grubby program to view the default kernel for the server. Type:
sudo grubby --default-kernel
-
All done. Moment of truth now. The latest kernel will likely be configured as the new default kernel to boot into. If you have access to the system's console you can reboot your system and select the new custom Kernel in the GRUB boot menu. If all goes well after the reboot, you can verify that system is running the custom kernel by running the
uname
command like this:uname -r
Author: Wale Soyinka
Contributors: Steven Spencer, Ganna Zhyrnova