This article tackles a topic that often seems intimidating to new administrators: the Linux kernel.
We’ll demystify kernel administration, covering when and why you might need to recompile your kernel, how to do it safely, and how to manage kernel modules. This guide draws from Chapter 32 of “Linux: The Complete Reference,” but I’ll add my own experience and break things down into manageable steps.
What is the Kernel, and Why Should You Care?
The kernel is the core of your Linux operating system. It’s the program that directly interacts with your hardware, manages processes, handles memory, and provides the fundamental services that all other programs rely on. Think of it as the engine of your Linux system.
Why might you need to interact with the kernel?
- New Hardware Support: You might install a new device (a fancy new network card, a specialized storage controller) that isn’t supported by your currently installed kernel.
- Performance Tuning: You might want to optimize the kernel for specific workloads (e.g., a database server might benefit from different kernel settings than a desktop machine).
- Security Patches: Kernel updates often include security fixes.
- New Features: New kernel versions can introduce exciting new features and improvements.
- Bug Fixes: Like any software, kernels can have bugs. Updating to a newer version can fix these.
- Learning: Compiling your own kernel is a great way to learn more about how Linux works under the hood!
Important Distinction: Kernel vs. Modules
- Kernel: The core operating system code.
- Modules: Pieces of code that can be dynamically loaded into and unloaded from the running kernel. Most device drivers are modules.
You often don’t need to recompile the entire kernel to add support for a new device. You might just need to load the appropriate module. We’ll cover modules in detail later.
Read: A Deep Dive into Linux Operating System Architecture: Components and Functions
Kernel Versions
Kernel versions follow a specific numbering scheme:
major.minor.patch-build
Historically, Linux used a system where odd-numbered minor versions (e.g., 2.5.x) indicated development releases, while even-numbered minor versions (e.g., 2.6.x) indicated stable releases. However, since the adoption of Linux 3.0 in 2011, this distinction was dropped in favor of a simpler versioning scheme:
- major: Represents significant architectural changes (incremented rarely)
- minor: Indicates significant changes and feature additions
- patch: Indicates bug fixes, security patches, and minor updates
- build: Includes distribution-specific changes and customizations
Example:
5.15.0-60-generic
- Major version: 5
- Minor version: 15
- Patch level: 0
- Build: 60-generic (Ubuntu/Debian-specific build for generic hardware)
How to check your current kernel version:
uname -r
Read: Demystifying Linux Devices and Modules: A Practical Guide for Admins
Kernel Tuning: Runtime Parameters
Before diving into recompilation, it’s worth knowing that you can often tune kernel behavior without recompiling. Many kernel parameters can be adjusted at runtime.
/proc/sys
: This is a virtual filesystem (like/proc
itself) that provides access to kernel parameters. You can read and write to files in this directory to change kernel settings.Example:# Enable IP forwarding (required for routing/NAT) echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl
: A command-line tool for viewing and modifying kernel parameters.# Display the current value of a parameter sysctl net.ipv4.ip_forward # Set a parameter sysctl -w net.ipv4.ip_forward=1
/etc/sysctl.conf
and/etc/sysctl.d/*.conf
: These files contain settings that are applied at boot time. You can make persistent changes here.# Add this line to /etc/sysctl.conf to make IP forwarding permanent net.ipv4.ip_forward = 1
Warning: Modifying kernel parameters can be risky. Make sure you understand what you’re doing before changing anything!
Installing a New Kernel Version
There are two main ways to get a new kernel:
- From Your Distribution (Recommended): Use your distribution’s package manager to install a pre-compiled kernel package. This is the easiest and safest method. The distribution has tested the kernel and ensured it works with your system.
- Compiling from Source: Download the kernel source code, configure it, compile it, and install it. This gives you maximum control, but it’s more complex and time-consuming.
Installing a Pre-Built Kernel
Let’s look at how to install pre-built kernels across major distributions:
Debian/Ubuntu:
# Update your package lists
sudo apt update
# Search for available kernel packages
sudo apt search linux-image
# Install a specific kernel package
sudo apt install linux-image-generic # For a generic kernel
# OR
sudo apt install linux-image-5.15.0-60-generic # For a specific version
# Also install the matching headers (needed for building modules)
sudo apt install linux-headers-generic # Or specific version
Red Hat/CentOS/Fedora:
# Update package lists
sudo dnf check-update # Fedora/modern RHEL
# OR
sudo yum check-update # Older RHEL/CentOS
# Search for available kernels
sudo dnf list kernel # Fedora/modern RHEL
# OR
sudo yum list kernel # Older RHEL/CentOS
# Install the latest kernel
sudo dnf install kernel # Fedora/modern RHEL
# OR
sudo yum install kernel # Older RHEL/CentOS
# Install matching headers
sudo dnf install kernel-devel # Fedora/modern RHEL
# OR
sudo yum install kernel-devel # Older RHEL/CentOS
openSUSE:
# Update package lists
sudo zypper refresh
# Install the latest kernel
sudo zypper install kernel-default
# Install matching headers
sudo zypper install kernel-default-devel
After installing a new kernel, you’ll need to reboot to use it:
sudo reboot
Understanding Kernel Packages
Most distributions offer several kernel package variants optimized for different hardware and use cases:
- Generic/Default: Balanced configuration suitable for most systems
- Server: Optimized for server workloads (may include additional features like high memory support)
- Lowlatency: Optimized for real-time applications and reduced latency
- Cloud: Tailored for virtualized environments
- Hardware-specific: Optimized for specific CPU architectures (e.g., AMD, Intel)
For example, on Ubuntu you might see packages like:
linux-image-generic
linux-image-lowlatency
linux-image-aws
(for Amazon Web Services)
Choose the package that best matches your system’s purpose and hardware.
Kernel Package Types: Distributions offer various kernel package variants optimized for different purposes
Understanding the Boot Process
When you install a new kernel, it gets placed in the /boot
directory along with several important files:
vmlinuz-[version]
: The compressed kernel itselfinitrd.img-[version]
orinitramfs-[version].img
: The initial RAM disk/filesystemSystem.map-[version]
: Symbol table used for debuggingconfig-[version]
: The configuration used to build this kernel
The initramfs/initrd is particularly important – it’s a temporary root filesystem loaded into memory during boot that contains essential drivers and tools needed before the real root filesystem can be mounted. Without a properly configured initramfs, your system might not boot, especially if your root filesystem uses technologies like LVM, RAID, or encryption.
Modern distributions automatically generate and update the initramfs when you install a new kernel. If you ever need to manually regenerate it:
# Debian/Ubuntu
sudo update-initramfs -u -k [version]
# Red Hat/CentOS/Fedora
sudo dracut --force --kver [version]
# openSUSE
sudo mkinitrd -k [version]
Read: How to restore GRUB Bootloader in Ubuntu
Boot Loader Configuration
The boot loader is responsible for loading the kernel at startup. Most modern Linux systems use GRUB2 (Grand Unified Bootloader version 2).
When you install a new kernel through your distribution’s package manager, the boot loader configuration is usually updated automatically. However, if you compile your own kernel or need to modify boot options, you’ll need to update it manually.
For GRUB2:
- Edit kernel parameters in
/etc/default/grub
- Update the configuration:
# Debian/Ubuntu
sudo update-grub
# Red Hat/CentOS/Fedora
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
# openSUSE
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Important boot loader features:
- Multiple kernel entries: GRUB2 maintains entries for multiple installed kernels, allowing you to boot from an older kernel if a new one causes problems.
- Kernel parameters: You can pass specific parameters to the kernel at boot time (e.g.,
quiet
,splash
,nomodeset
). - Recovery mode: Most configurations include a recovery mode option for each kernel.
Compiling the Kernel from Source
This is the “advanced” method. You only need to do this if:
- You need a feature that’s not included in your distribution’s kernels.
- You want to optimize the kernel for your specific hardware.
- You’re a kernel developer and you want to modify the kernel code.
- You want to create your own customized kernel.
Preparation: Install Required Tools
Before you start, you’ll need development tools:
# Debian/Ubuntu
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev
# Red Hat/CentOS/Fedora
sudo dnf groupinstall "Development Tools"
sudo dnf install ncurses-devel bison flex elfutils-libelf-devel openssl-devel
# openSUSE
sudo zypper install -t pattern devel_basis
sudo zypper install ncurses-devel bison flex libelf-devel openssl-devel
Step-by-Step Kernel Compilation
- Get the Source Code: Download the kernel source code from kernel.org. It will be a large compressed archive (e.g.,
linux-5.15.tar.xz
).wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.tar.xz
- Extract the Source Code:
tar -xf linux-5.15.tar.xz cd linux-5.15
- Start with a Working Configuration: Instead of starting from scratch, it’s often best to start with your distribution’s current kernel configuration:
# Copy your current kernel config cp /boot/config-$(uname -r) .config # Update the config for the new kernel version make olddefconfig
- Configure the Kernel: This is where you choose which features to include. There are several interfaces:
# Text-based menu (recommended for most users) make menuconfig # GUI version using Qt make xconfig # GUI version using GTK make gconfig
Navigation in menuconfig:
- Arrow keys to move
- Enter to select/enter submenus
- Space to toggle options (Y=built-in, M=module, N=excluded)
- ? to view help for an option
- / to search
- ESC twice to exit (with prompt to save)
- Compile the Kernel:
# Determine number of CPU cores for faster compilation nproc # Compile using multiple cores (replace N with your core count) make -jN
This will take a long time (potentially an hour or more, depending on your hardware).
- Compile and Install the Modules:
sudo make modules_install
This installs the modules into
/lib/modules/kernel-version
. - Install the Kernel:
sudo make install
This command:
- Copies the kernel (
vmlinuz
) to/boot
- Copies
System.map
to/boot
- Copies the kernel config to
/boot
- Creates an initramfs/initrd image
- Updates the bootloader configuration
- Copies the kernel (
- Verify the Installation: Check that the files were properly installed in
/boot
:ls -l /boot
You should see your new kernel files.
- Reboot:
sudo reboot
At the GRUB menu, you should see an option for your new kernel. If not, boot into your existing kernel and troubleshoot the bootloader configuration.
Common Pitfalls in Kernel Compilation
- Missing Development Tools: Ensure all necessary packages are installed before starting.
- Insufficient Disk Space: Kernel compilation requires several GB of free space.
- Incorrect Configuration: Starting with a proven configuration (like your distribution’s) reduces risks.
- Hardware Compatibility: If you disable drivers your system needs, it might not boot.
- Bootloader Issues: Always ensure your bootloader is correctly configured to include both your new and old kernels.
Creating a Backup Before Kernel Changes
Before making significant kernel changes, it’s wise to create backups:
# Copy kernel files
sudo cp /boot/vmlinuz-$(uname -r) /boot/vmlinuz-$(uname -r).backup
sudo cp /boot/initrd.img-$(uname -r) /boot/initrd.img-$(uname -r).backup
sudo cp /boot/System.map-$(uname -r) /boot/System.map-$(uname -r).backup
sudo cp /boot/config-$(uname -r) /boot/config-$(uname -r).backup
If you encounter issues, you can boot from your original kernel.
Kernel Modules
Kernel modules are pieces of code that can be dynamically loaded into and unloaded from the running kernel. This allows you to add support for new hardware or features without recompiling the entire kernel.
Module Location and Structure
Modules are stored in the /lib/modules/$(uname -r)/
directory, organized into subdirectories by function:
- kernel/drivers/: Hardware drivers
- kernel/fs/: Filesystem modules
- kernel/net/: Networking modules
- kernel/sound/: Audio subsystem modules
Module files have a .ko
extension (or .ko.xz
if compressed).
Essential Module Management Tools
lsmod
: Lists currently loaded modules and their dependencies.lsmod
modinfo
: Displays detailed information about a module, including parameters it accepts.modinfo e1000e # Information about the Intel e1000e network driver
modprobe
: The preferred tool for loading and unloading modules. It handles dependencies automatically.# Load a module sudo modprobe e1000e # Unload a module sudo modprobe -r e1000e
insmod
/rmmod
: Low-level tools for loading/unloading modules without dependency handling. Generally, usemodprobe
instead.depmod
: Analyzes module dependencies and creates the dependency files used bymodprobe
. Runs automatically when you install new modules.
Finding Available Modules
To list available modules for your kernel:
# Find modules matching a pattern
find /lib/modules/$(uname -r) -type f -name '*.ko*' | grep usb
# Alternative using modern modprobe features
modprobe -D usb
The older modprobe -l
command is deprecated in modern distributions.
Module Configuration
Module configuration is handled through files in /etc/modprobe.d/
(with .conf
extension):
- Autoloading modules: Create aliases for hardware
- Setting module parameters: Control module behavior
- Blacklisting modules: Prevent problematic modules from loading
Examples:
# /etc/modprobe.d/sound.conf
# Set options for the snd-hda-intel module
options snd-hda-intel model=auto
# /etc/modprobe.d/blacklist.conf
# Prevent the pcspkr module from loading
blacklist pcspkr
Automatic Module Loading
Modules are loaded:
- During boot: The kernel loads modules needed for detected hardware
- On demand: When hardware is hot-plugged (USB devices, etc.)
- Via dependencies: When another module requires them
- Manually: When you use
modprobe
Modern Linux uses udev
to handle automatic module loading for hardware.
Kernel Security and Hardening
Kernel security is critical since a kernel vulnerability can compromise the entire system.
Kernel Hardening Options
Many distributions apply security patches and hardening options to their kernels. If you’re compiling your own, consider these hardening options:
- Kernel Address Space Layout Randomization (KASLR): Randomizes the location of the kernel code in memory
- Stack protector: Guards against stack overflow exploits
- Read-only kernel memory: Prevents modification of critical kernel data
- Secure Boot: Prevents loading of unsigned kernel code
Kernel Live Patching
Modern Linux distributions support applying critical kernel updates without rebooting:
- RHEL/CentOS/Fedora: Uses
kpatch
- Ubuntu: Uses
livepatch
- SUSE: Uses
kGraft
For example, on Ubuntu:
# Enable Livepatch service (requires Ubuntu Advantage subscription)
sudo ua enable livepatch
Keeping Your Kernel Updated
Regularly updating your kernel is crucial for security:
# Debian/Ubuntu
sudo apt update && sudo apt upgrade
# Red Hat/CentOS/Fedora
sudo dnf update
# openSUSE
sudo zypper update
Kernel Troubleshooting and Monitoring
When encountering kernel issues, several tools can help diagnose problems.
Monitoring Kernel Messages
dmesg
: Shows kernel messages from the current bootdmesg | grep -i error
journalctl
: On systemd-based systems, provides access to kernel logsjournalctl -k # Kernel messages only
Performance Analysis Tools
perf
: A powerful performance analysis tool included with the kernelperf stat -e cycles,instructions,cache-misses ls -la
bpftrace
/eBPF
: Advanced tracing framework for kernel analysissysdig
: Comprehensive system visibility tool
Common Kernel Issues and Solutions
- System won’t boot with new kernel:
- Boot from an older kernel in the GRUB menu
- Check that the initramfs includes necessary drivers
- Verify bootloader configuration
- Hardware not detected:
- Ensure appropriate modules are loaded
- Check if the hardware is supported by your kernel version
- Look for error messages in
dmesg
- System freezes or panics:
- Boot with the
nomodeset
parameter if graphics-related - Check RAM with
memtest86+
- Look for hardware compatibility issues
- Boot with the
- Out of memory issues:
- Adjust swappiness:
sysctl vm.swappiness=60
- Check for memory leaks in running applications
- Adjust swappiness:
Dynamic Kernel Module Support (DKMS)
DKMS allows kernel modules to be automatically rebuilt when you install a new kernel, ensuring third-party drivers remain available.
To install DKMS:
# Debian/Ubuntu
sudo apt install dkms
# Red Hat/CentOS/Fedora
sudo dnf install dkms
# openSUSE
sudo zypper install dkms
Many third-party drivers (like NVIDIA graphics drivers, VirtualBox guest additions) are packaged to work with DKMS.
Conclusion
Kernel administration is a fundamental skill for Linux system administrators. While most users can rely on distribution-provided kernels, understanding how to tune, customize, and troubleshoot the kernel gives you greater control over your systems.
Remember these key points:
- Start with your distribution’s kernel packages whenever possible
- Use kernel parameters to tune performance before considering recompilation
- Understand kernel modules and how to manage them
- Keep security in mind with regular updates
- Always have a backup plan when making kernel changes
With the knowledge in this guide, you should feel more confident working with the Linux kernel and ready to tackle advanced administration tasks.
Frequently Asked Questions
What exactly is the Linux kernel?
The Linux kernel is the core component of the Linux operating system that provides the fundamental interface between your computer’s hardware and its software. It manages system resources, handles process scheduling, provides memory management, and enables communication with hardware devices. Think of it as the engine that powers your entire Linux system.
How do I check which kernel version I’m currently running?
You can check your current kernel version by opening a terminal and running the command uname -r
. This will display the full version number in the format major.minor.patch-build (e.g., 5.15.0-60-generic).
Why would I need to update or change my kernel?
There are several reasons to update your kernel, including:
- Getting support for new hardware
- Obtaining security patches for vulnerabilities
- Accessing performance improvements and optimizations
- Fixing bugs in previous versions
- Adding new features and capabilities
- Learning more about Linux internals (if compiling your own)
Kernel Management
What’s the difference between updating and recompiling a kernel?
Updating a kernel means installing a pre-built kernel package provided by your distribution. This is simpler, faster, and generally safer. Recompiling a kernel means building it from source code, which gives you more control over included features and optimizations but requires more technical knowledge and time.
How do I update my kernel using my distribution’s package manager?
For Debian/Ubuntu:
sudo apt update
sudo apt install linux-image-generic linux-headers-generic
For Red Hat/CentOS/Fedora:
sudo dnf update kernel kernel-devel
For openSUSE:
sudo zypper update kernel-default kernel-default-devel
If I install a new kernel, can I still use my old one?
Yes. Modern Linux distributions keep previous kernel versions installed and configure the bootloader (typically GRUB2) to include them as boot options. If a new kernel causes problems, you can select an older kernel from the boot menu.
What are kernel modules and why are they important?
Kernel modules are pieces of code that can be dynamically loaded into and unloaded from the running kernel. They allow you to add hardware support and features without recompiling the entire kernel. Most device drivers are implemented as modules, making the kernel more flexible and efficient.
How do I check which kernel modules are currently loaded?
Use the lsmod
command to list all currently loaded modules and their dependencies.
How do I load or unload a kernel module?
To load a module:
sudo modprobe module_name
To unload a module:
sudo modprobe -r module_name
Replace module_name
with the actual name of the module.
Kernel Tuning and Optimization
How can I adjust kernel parameters without recompiling?
You can modify kernel parameters at runtime through the /proc/sys
virtual filesystem or using the sysctl
command. For example:
# View a parameter
cat /proc/sys/net/ipv4/ip_forward
# or
sysctl net.ipv4.ip_forward
# Change a parameter temporarily
echo 1 > /proc/sys/net/ipv4/ip_forward
# or
sysctl -w net.ipv4.ip_forward=1
To make changes permanent, add them to /etc/sysctl.conf
or a file in /etc/sysctl.d/
.
What kernel parameters should I consider tuning for better performance?
Common parameters to tune include:
vm.swappiness
: Controls how aggressively the kernel swaps memory to disknet.core.somaxconn
: Maximum connection backlognet.ipv4.tcp_max_syn_backlog
: TCP connection queue sizevm.dirty_ratio
andvm.dirty_background_ratio
: Control write caching behavior
The specific parameters to tune depend on your workload and hardware.
How do I choose the right kernel type for my system?
Most distributions offer several kernel variants:
- Generic/Default: Good for desktop and general-purpose use
- Server: Optimized for server workloads with support for more RAM and CPUs
- Lowlatency: For real-time applications and audio/video processing
- Cloud: Optimized for virtualized environments
Choose based on your primary use case. When in doubt, the generic kernel is a safe choice.
Compiling Custom Kernels
When should I compile my own kernel instead of using a pre-built one?
Consider compiling your own kernel when:
- You need specific features not enabled in distribution kernels
- You want to optimize for your exact hardware configuration
- You need to apply custom patches
- You’re developing kernel code
- You want to learn more about Linux internals
For most users, pre-built distribution kernels are sufficient.
What tools do I need to compile a kernel?
You’ll need development tools including:
- C compiler (gcc or clang)
- make
- ncurses development libraries (for menuconfig)
- flex and bison (for parsing)
- libssl-dev (for crypto features)
- libelf-dev (for building modules)
The exact package names vary by distribution.
What’s the safest way to start customizing a kernel configuration?
Start with your current working configuration:
cp /boot/config-$(uname -r) .config
make olddefconfig
This gives you a baseline that’s known to work on your system, which you can then modify.
How long does it take to compile a kernel?
Compilation time varies greatly depending on your hardware and configuration choices. On a modern system (8 cores, SSD), it might take 15-60 minutes. On older hardware, it could take several hours.
What are the most common mistakes when compiling a kernel?
Common pitfalls include:
- Forgetting to include drivers for essential hardware (disk controllers, filesystems)
- Not creating an initramfs/initrd image
- Not updating the bootloader configuration
- Removing support for your root filesystem type
- Not setting a proper CONFIG_LOCALVERSION
Always keep your previous working kernel available as a fallback.
Kernel Security
How do I know if my kernel has security vulnerabilities?
Subscribe to your distribution’s security announcements. Major distributions promptly release security advisories when kernel vulnerabilities are discovered. You can also check websites like CVE databases or the National Vulnerability Database (NVD).
What are kernel hardening features and should I enable them?
Kernel hardening features add protective measures against various types of attacks. Common hardening features include:
- Kernel Address Space Layout Randomization (KASLR)
- Stack protector
- Restricted access to kernel memory
- Control flow integrity
Most distribution kernels enable important security features by default. When compiling your own, it’s recommended to enable them.
What is kernel live patching and how do I use it?
Kernel live patching allows applying security fixes without rebooting. Major distributions offer this feature through different technologies:
- Ubuntu: Livepatch service
- RHEL/CentOS/Fedora: kpatch
- SUSE: kGraft
To use it, you typically need to install a service and register your system (sometimes requiring a subscription).
Troubleshooting Kernel Issues
What should I do if my system won’t boot after a kernel update?
- Reboot and select a previous kernel from the GRUB menu (usually accessed by holding Shift during boot)
- If that works, investigate what went wrong with the new kernel
- Check logs (once booted with working kernel) using
journalctl -b -1 -k
to see messages from the failed boot - Ensure your initramfs includes necessary drivers
- Verify bootloader configuration
How do I diagnose hardware compatibility issues with my kernel?
- Check kernel messages for errors:
dmesg | grep -i error
- Look for missing drivers:
lspci -k
shows devices and associated drivers - Compare working and non-working kernel configurations
- Try booting with kernel parameters like
nomodeset
for graphics issues
What logs should I check when troubleshooting kernel problems?
- Kernel ring buffer:
dmesg
- System journal (on systemd systems):
journalctl -k
- Boot logs:
journalctl -b
- System logs in
/var/log/
, particularly/var/log/syslog
or/var/log/messages
How do I handle kernel panics?
For occasional kernel panics:
- Note the error message if possible
- Check hardware, particularly RAM (run memtest86+)
- Boot with an older kernel version
- Check logs after rebooting
For consistent kernel panics preventing boot:
- Boot from a live USB/CD
- Mount your system partitions
- Check logs
- Consider reinstalling the kernel package or booting with different parameters
Advanced Topics
What is DKMS and why is it useful?
Dynamic Kernel Module Support (DKMS) automatically rebuilds out-of-tree kernel modules when you install a new kernel. This ensures third-party drivers (like NVIDIA graphics or VirtualBox guest additions) remain available without manual intervention after kernel updates.
How do I contribute to kernel development?
To start contributing to the Linux kernel:
- Subscribe to the Linux Kernel Mailing List (LKML)
- Read the kernel documentation, particularly the coding style guide
- Find an area of interest (subsystem)
- Start with small fixes (documentation, simple bugs)
- Submit patches following the contribution guidelines
- Be responsive to feedback
How do I debug kernel issues using perf or other tools?
For kernel performance analysis:
perf
tracks CPU performance counters and provides detailed profilingbpftrace
/eBPF
offers advanced tracing capabilitiesftrace
provides function tracing for the kernelsystemtap
allows writing diagnostic scripts
Start with simpler tools like perf stat
and perf record
/perf report
before advancing to more complex options.
Where can I learn more about kernel development and administration?
Recommended resources include:
- The Linux Kernel documentation (https://www.kernel.org/doc/)
- “Linux Kernel in a Nutshell” by Greg Kroah-Hartman
- “Linux Kernel Development” by Robert Love
- Your distribution’s wiki and documentation
- The Linux kernel source code itself
If you like the content, we would appreciate your support by buying us a coffee. Thank you so much for your visit and support.