Last modified: October 11, 2021
This article is written in: 🇺🇸
We will now delve deeply into the Linux kernel to understand its role in the operating system, where it resides on your system, and how kernel modules function. We will also explore how to download and examine the Linux kernel source code, and discuss the various configuration options available within it. The goal is to provide you with a comprehensive understanding of this critical component of the operating system—not necessarily to enable you to compile your own custom kernel, but to appreciate what the kernel does and how it operates.
TODO: - compare various kernel versions
The Linux kernel is the core component of the Linux operating system. According to Wikipedia:
The Linux kernel is a computer program that manages input/output requests from software and translates them into data processing instructions for the CPU and other electronic components of a computer.
In simpler terms, the kernel acts as a bridge between software applications and the hardware of a computer. It handles critical tasks such as:
Think of the kernel as the director or manager of all system operations at the lowest level. It is responsible for:
Without the kernel, applications would have to manage hardware interactions themselves, leading to complexity and potential instability.
In operating systems like Linux, the concepts of kernel space and user space are fundamental. They represent two separate areas of memory used for different purposes, ensuring the system's stability and security by controlling how processes interact with hardware and core system functions.
+--------------------------------------------------+
| User Space |
| |
| +--------------------------------------------+ |
| | User Applications | |
| | | |
| | +---------+ +---------+ +---------+ | |
| | | App 1 | | App 2 | | App 3 | | |
| | +---------+ +---------+ +---------+ | |
| | | |
| +--------------------------------------------+ |
| |
+--------------------------------------------------+
| Kernel Space |
| |
| +--------------------------------------------+ |
| | Operating System Kernel | |
| | | |
| | +---------+ +----------+ +-----------+ | |
| | | Memory | | Scheduler | | Drivers | | |
| | | Manager | | | | | | |
| | +---------+ +----------+ +-----------+ | |
| | | |
| +--------------------------------------------+ |
| |
+--------------------------------------------------+
| Hardware Layer |
| |
| +--------------------------------------------+ |
| | Physical Hardware | |
| +--------------------------------------------+ |
| |
+--------------------------------------------------+
+------------------------+ 0xFFFFFFFF (Highest Address)
| Kernel Space |
| (Shared among all |
| processes) |
+------------------------+ 0xC0000000 (On 32-bit systems)
| |
| |
| |
| User Space |
| (Per-process virtual |
| memory space) |
| |
| |
+------------------------+ 0x00000000 (Lowest Address)
User Space Memory:
Kernel Space Memory:
User Space:
+-----------------+
| User App |
| Calls read() |
+--------+--------+
|
v
Kernel Space:
+-----------------+
| System Call |
| Handler |
+--------+--------+
|
v
+-----------------+
| Filesystem |
| Driver |
+--------+--------+
|
v
Hardware Layer:
+-----------------+
| Disk Hardware |
+-----------------+
The kernel and its related files reside in the /boot
directory on a Linux system. This directory contains essential components needed during the boot process.
To view the contents of the /boot
directory, open a terminal and run:
ls /boot
You may see output similar to:
config-5.4.0-42-generic
initrd.img-5.4.0-42-generic
vmlinuz-5.4.0-42-generic
System.map-5.4.0-42-generic
vmlinuz-5.4.0-42-generic
is the compressed Linux kernel executable.initrd.img
is initial RAM disk image used during boot.config-
and System.map-
are configuration and symbol map files for the kernel.It's common to have multiple kernels installed on your system. This provides flexibility and safety:
Listing available kernels:
ls /boot/vmlinuz*
Example output:
/boot/vmlinuz-5.4.0-40-generic
/boot/vmlinuz-5.4.0-42-generic
The bootloader, typically GRUB2 (GRand Unified Bootloader version 2) in modern Linux distributions, allows you to select which kernel to boot.
To select a kernel at boot time:
Shift
key (for BIOS systems) or press Esc
repeatedly (for UEFI systems) during startup to access the GRUB menu.Advanced options for Ubuntu
or similar.Note: Modifying GRUB configurations can be complex and may affect system boot. Always proceed with caution.
Kernel modules are pieces of code that can be loaded and unloaded into the kernel at runtime. They extend the functionality of the kernel without the need to reboot the system.
Examples of kernel modules include:
To see which modules are currently loaded into the kernel, use the lsmod
command:
lsmod
The output will list modules with their sizes and usage counts:
Module Size Used by
snd_hda_codec_realtek 94208 1
snd_hda_codec_generic 77824 1 snd_hda_codec_realtek
uvcvideo 102400 0
videobuf2_vmalloc 16384 1 uvcvideo
/lib/modules
DirectoryKernel modules are stored in the /lib/modules/<kernel-version>
directory. Each kernel version has its own set of modules.
To list modules for a specific kernel:
ls /lib/modules/$(uname -r)
This directory contains subdirectories and files that represent various modules and their dependencies.
The official source code for the Linux kernel is available at kernel.org.
To download the kernel source code:
5.8.12
..tar.xz
link to download the compressed source code.Alternatively, from the terminal:
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.8.12.tar.xz
After downloading, extract the source code using the tar
command:
tar -xf linux-5.8.12.tar.xz
This will create a directory named linux-5.8.12
.
Change into the source directory:
cd linux-5.8.12
List the contents:
ls
Key directories include:
Directory | Description |
arch/ |
Architecture-specific code. |
drivers/ |
Device driver source code. |
fs/ |
File system implementations. |
include/ |
Header files. |
kernel/ |
Core kernel code. |
net/ |
Networking stack code. |
Documentation/ |
Documentation for various kernel components. |
Example: Exploring Network Drivers
Navigate to the network drivers directory:
cd drivers/net
ls
You will see directories for different types of network devices, such as:
Directory | Description |
ethernet/ |
Ethernet drivers. |
wireless/ |
Wireless network drivers. |
usb/ |
USB network drivers. |
Viewing a Specific Driver
For example, to view the source code for a Realtek Ethernet driver:
cd ethernet/realtek
ls
Files like r8169.c
represent the source code for specific drivers.
You can examine the code using a text editor:
less r8169.c
Note: Understanding kernel source code requires knowledge of the C programming language and kernel development practices.
Before configuring the kernel, ensure that you have the necessary tools installed.
Install Required Packages on Ubuntu/Debian:
sudo apt-get install build-essential libncurses-dev bison flex libssl-dev libelf-dev
Package | Description |
build-essential |
Provides essential tools like gcc and make . |
libncurses-dev |
Needed for the menu configuration interface. |
bison and flex |
Required for parsing during the build process. |
libssl-dev |
Provides SSL libraries. |
libelf-dev |
ELF object file access library. |
make menuconfig
make menuconfig
is a terminal-based configuration utility that allows you to configure the kernel options via a text-based menu.
Steps:
I. Navigate to the Kernel Source Directory:
cd linux-5.8.12
II. Run the Configuration Utility:
make menuconfig
This will display a menu with various categories:
Navigating the Menu:
Key | Description |
Arrow Keys | Move up and down the menu. |
Enter | Select a menu item or enter a submenu. |
Spacebar | Toggle selections. |
Configuration Symbols:
Symbol | Description |
[*] |
Feature is built into the kernel. |
[ ] |
Feature is not included. |
<M> |
Feature is built as a loadable module. |
Example: Configuring File System Support
I. Select File systems
:
File systems --->
II. View Supported File Systems:
III. Enabling NTFS Support:
Spacebar
to select NTFS file system supportExample: Enabling a Device Driver as a Module
I. Navigate to Device Drivers
:
Device Drivers --->
II. Select a Device Category (e.g., Network device support
):
Network device support --->
III. Choose a Specific Driver:
M
to compile it as a module.sysctl
sysctl
is a utility that allows for querying and modifying kernel parameters at runtime. These parameters control various aspects of the operating system's behavior, such as networking, process limits, security settings, and more. It is commonly used by system administrators to fine-tune the performance and behavior of the system without needing to reboot.
/proc/sys/
directory. Each parameter is represented as a file that can be read or modified using the sysctl
command.Usage:
I. View current kernel parameters:
sysctl -a
This command will list all kernel parameters and their current values.
II. View a specific kernel parameter:
sysctl net.ipv4.ip_forward
This will display the value of the net.ipv4.ip_forward
parameter, which controls whether the system can act as a router by forwarding network packets.
III. Modify a kernel parameter temporarily:
sysctl -w net.ipv4.ip_forward=1
This command will enable IP forwarding, but the change will only last until the system is rebooted.
IV. Make changes permanent:
To make changes permanent, you need to add the parameter to the /etc/sysctl.conf
file (or in newer systems, files in /etc/sysctl.d/
):
net.ipv4.ip_forward = 1
After editing the configuration file, you can apply the changes without rebooting using:
sysctl -p
Here are some common scenarios where sysctl
is used, with relevant examples and explanations for each:
You want to optimize the network performance, especially for high-bandwidth or high-latency environments, by adjusting TCP buffer sizes.
sysctl -w net.core.rmem_max=16777216 # Max receive buffer size
sysctl -w net.core.wmem_max=16777216 # Max send buffer size
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216" # Receive buffer settings
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216" # Send buffer settings
Permanent Configuration:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
Adjusting TCP buffer sizes can significantly impact network performance, particularly for high-latency links like satellite or intercontinental connections.
You want to reduce swap usage to improve performance for systems with enough RAM by adjusting how aggressively the system uses swap space.
sysctl -w vm.swappiness=10
Permanent Configuration:
vm.swappiness = 10
vm.swappiness
controls how likely the kernel is to swap memory pages to disk. A lower value (0-10) means the system will prioritize using RAM before swapping, which is helpful for performance on systems with sufficient memory.
You want to enhance system security by enabling address space layout randomization (ASLR), which helps prevent certain types of attacks.
sysctl -w kernel.randomize_va_space=2
Permanent Configuration:
kernel.randomize_va_space = 2
ASLR randomizes the memory addresses used by system processes, making it harder for attackers to exploit memory corruption vulnerabilities. Setting kernel.randomize_va_space
to 2 fully enables it.
You need to increase the maximum number of file descriptors a process can open, which is important for applications handling many simultaneous connections (e.g., web servers).
sysctl -w fs.file-max=100000
Permanent Configuration:
fs.file-max = 100000
This setting increases the limit on the total number of file descriptors the kernel can allocate. Useful for optimizing servers under heavy load.
You are tuning a database (e.g., PostgreSQL) that relies on shared memory, and you need to increase the shared memory limits.
sysctl -w kernel.shmmax=68719476736 # Set maximum size of a single shared memory segment
sysctl -w kernel.shmall=4294967296 # Set total amount of shared memory (in pages)
Permanent Configuration:
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
These parameters configure how much shared memory can be allocated by the system, which is critical for database systems that use shared memory for caching and buffers.
To enhance network security, you want to disable the system’s acceptance of ICMP redirects, which can be used maliciously to alter routing tables.
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.default.accept_redirects=0
Permanent Configuration:
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
Disabling ICMP redirects ensures that malicious users cannot alter the routing table by sending false ICMP redirect messages. It is a common practice to harden system security.
You want to enable SYN cookies to protect against SYN flood attacks, a type of denial-of-service (DoS) attack.
sysctl -w net.ipv4.tcp_syncookies=1
Permanent Configuration:
net.ipv4.tcp_syncookies = 1
SYN cookies help mitigate SYN flood attacks by ensuring that the kernel doesn't allocate resources to half-open TCP connections during an attack. Instead, it uses cryptographic cookies to validate connection requests.
Proper kernel configuration is crucial:
Caution: Incorrect configuration may result in an unbootable system. It's advisable to:
After configuring the kernel, you can proceed to compile it.
Compile the Kernel and Modules:
make -j$(nproc)
Options:
-j$(nproc)
utilizes all available CPU cores for faster compilation.Note: The compilation process may take considerable time depending on system resources.
Install Kernel Modules:
sudo make modules_install
This installs the kernel modules to /lib/modules/<kernel-version>
.
Install the Kernel:
sudo make install
This installs:
File | Description |
Kernel Image | /boot/vmlinuz-<kernel-version> |
System Map | /boot/System.map-<kernel-version> |
Configuration | /boot/config-<kernel-version> |
After installing the new kernel, update the bootloader to recognize it.
For GRUB2:
sudo update-grub
This scans for all available kernels and updates /boot/grub/grub.cfg
.
Verify the New Kernel Entry:
grep menuentry /boot/grub/grub.cfg
Look for an entry corresponding to your new kernel version.
sysrq
trigger). Capture and analyze the output to understand the cause of the panic and how to recover from such situations./boot
directory, updating the boot loader configuration, and rebooting the system.git bisect
tool to identify a regression in the kernel. Document the process of finding the offending commit in the kernel source.