Exam weight: This topic carries 3 points on the LPIC-2 201 exam. Focus on
maketargets, the paths/usr/src/linux/.configand/lib/modules/kernel-version/, and the commandsmkinitrd,mkinitramfs, anddepmod.
Directory Layout
| Path | Purpose |
|---|---|
/usr/src/linux/ | Symbolic link to the current kernel source tree |
/usr/src/linux-<version>/ | Actual directory containing source for a specific version |
/usr/src/linux/.config | Kernel configuration file |
/boot/vmlinuz-<version> | Compiled kernel image |
/boot/System.map-<version> | Symbol table for kernel debugging |
/boot/initrd-<version>.img | Initial RAM disk image |
/lib/modules/<version>/ | Kernel modules for a specific version |
/lib/modules/<version>/modules.dep | Module dependency file, generated by depmod |
Note:
/usr/src/linuxis a symbolic link. Create it manually withln -s /usr/src/linux-4.x.x /usr/src/linux. Never place sources directly under/usr/src/linux.
Getting the Kernel Source
All kernel versions are available from kernel.org. Extract the downloaded archive into /usr/src/:
# Download the archive (example for version 4.3.3)
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.3.3.tar.xz
# Extract
tar xvf linux-4.3.3.tar.xz -C /usr/src/
# Create the symbolic link
ln -s /usr/src/linux-4.3.3 /usr/src/linux
# Enter the source directory
cd /usr/src/linux
Tip: You need at least 1 GB of free space to compile. Before building, ensure
gcc,make, and the development headers are installed:apt-get install build-essential(Debian) oryum groupinstall "Development Tools"(RHEL).
Cleaning the Source Tree
Cleaning happens at three levels:
# Level 1: removes most object files but keeps enough for external module builds
make clean
# Level 2: removes the current config (.config) and all object files
make mrproper
# Level 3: same as mrproper, plus editor backups, patch remnants, and other junk
make distclean
Running make mrproper before each new configuration and build is good practice.
Warning:
make mrproperdeletes.configcompletely. If your configuration took significant time, copy.configsomewhere safe before running this command.
Creating the .config File
Before compiling, the kernel must be configured: choose which features to build in directly (=y), which to compile as modules (=m), and which to exclude (=n). The result is saved to /usr/src/linux/.config.
.config is a plain text file where each line describes one option:
CONFIG_64BIT=y
CONFIG_SMP=y
CONFIG_MODULES=y
CONFIG_EXT4_FS=m
# CONFIG_BTRFS_FS is not set
Warning: Editing
.configby hand is strongly discouraged. Use one of themakeconfiguration targets instead.
make Configuration Targets
| Target | Interface | Dependencies | Notes |
|---|---|---|---|
make config | Sequential text prompts | None | Cannot go back. Hundreds of questions in a row. Works on any terminal |
make menuconfig | ncurses pseudo-graphics | libncurses | Menu with navigation. Can save at any point |
make nconfig | ncurses (dark theme) | libncurses | Alternative to menuconfig with a different colour scheme |
make xconfig | Qt GUI | Qt dev libs, X11 | Mouse navigation. Requires a working X Window System |
make gconfig | GTK GUI | GTK+ 2.x dev libs, X11 | Same as xconfig but GTK-based |
make oldconfig | Text, new options only | Existing .config | Carries over old settings, asks only about new options |
make defconfig | No questions | None | Creates a default configuration for the detected system type |
make mrproper | None | None | Removes .config and all object files |
# Enter the kernel source root
cd /usr/src/linux
# Launch the text menu (most common)
make menuconfig
# Update config when upgrading from 4.3 to 4.4
cp /path/to/old/.config /usr/src/linux/.config
make oldconfig
How make oldconfig handles .config
When make oldconfig runs, the old .config is copied to .config.old and a new .config is built from it. For every option not present in the old file, the system asks a question. All previously chosen values are preserved without prompting.
Note:
make xconfig,make gconfig, andmake menuconfigalso automatically pick up an existing.configfrom/usr/src/linux/. New options receive default values.
Exam tip: A common exam question is the difference between
make config,make menuconfig, andmake oldconfig. Remember:menuconfigis an ncurses interface with navigation;oldconfigupdates an existing config asking only about new options;make configis the most primitive โ no going back.
Compiling the Kernel
After creating .config, start the build:
# Compile the compressed kernel image (recommended)
make bzImage
# Compile the uncompressed kernel image
make zImage
# Compile modules only
make modules
# Compile everything: kernel + modules
make all
# Create an RPM source package
make rpm-pkg
# Create a binary RPM package
make binrpm-pkg
# Create a .deb package
make deb-pkg
The resulting bzImage is located at:
/usr/src/linux/arch/x86/boot/bzImage
Note:
bzImageis the compressed kernel image (b = “big”, z = zipped). It differs fromzImagein that it supports sizes over 512 KB. Always usebzImageon modern systems.
make Build Targets
| Target | Description |
|---|---|
all | Build the kernel and all modules |
bzImage | Compressed kernel image (Big zImage) |
zImage | Uncompressed kernel image (limited to 512 KB) |
modules | Compile modules only |
modules_install | Install modules to /lib/modules/<version>/ |
clean | Remove object files (.config is preserved) |
mrproper | Full clean, including .config |
rpm-pkg | Create an RPM package with sources and kernel |
binrpm-pkg | Create a binary RPM package |
deb-pkg | Create a .deb package for Debian systems |
Installing the New Kernel
The full build and install sequence:
# 1. Clean up previous build artifacts
make clean
# 2. Build the kernel image
make bzImage # or make zImage for very old systems
# 3. Build modules
make modules
# 4. Install modules to /lib/modules/<version>/
# The directory is created automatically if it doesn't exist
make modules_install
After building, copy the kernel and related files to /boot/. The path to bzImage depends on the architecture:
# x86_64
cp /usr/src/linux/arch/x86_64/boot/bzImage /boot/vmlinuz-2.6.31
# i386
cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz-2.6.31
# Copy the symbol table (optional, needed for debugging)
cp /usr/src/linux/System.map /boot/System.map-2.6.31
# Rebuild the module dependency file
depmod -a
Including the version in the filename allows multiple kernels to coexist in /boot/ so you can roll back if something goes wrong.
After copying the files, update the bootloader (GRUB):
# GRUB 2
update-grub # Debian/Ubuntu
grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL/CentOS
Important: If the bootloader doesn’t see the new kernel, check two things: the kernel file is in
/boot/and the GRUB config has been updated. The exam tests this.
Kernel Modules
Kernel modules are .ko object files loaded into the kernel on demand. All modules live in a directory hierarchy under /lib/modules/<kernel-version>/.
/lib/modules/4.3.3/
โโโ kernel/
โ โโโ drivers/
โ โ โโโ net/ # Network drivers
โ โ โโโ scsi/ # SCSI drivers
โ โ โโโ block/ # Block devices
โ โโโ fs/ # Filesystems
โโโ modules.dep # Dependency file
modules.dep lists the dependencies of each module. It is generated by depmod:
# Regenerate modules.dep for the running kernel
depmod -a
# Regenerate for a specific kernel version
depmod -a 4.3.3
Example line from modules.dep:
/lib/modules/2.6.31/kernel/drivers/acpi/thermal.ko: \
/lib/modules/2.6.31/kernel/drivers/thermal/thermal_sys.ko
Note:
modprobereadsmodules.depand automatically loads all module dependencies.insmoddoes not handle dependencies.
Initial RAM Disk โ initrd and initramfs
At boot time, the kernel cannot access the disk if the disk driver is compiled as a module. This creates a chicken-and-egg problem: to load the module you need the disk, but to access the disk you need the module. The solution is the initial RAM disk (initrd).
initrd is an image of a minimal root filesystem in RAM. The bootloader (GRUB or LILO) passes it to the kernel along with the kernel image. The kernel mounts initrd as a temporary root filesystem, loads the required modules, then mounts the real root filesystem from disk. After switching root, the old initrd either moves to /initrd or is unmounted.
Checking the format of an existing initrd
Old kernels use a tar archive internally; newer ones use cpio. To find out the format:
zcat /boot/initrd-2.6.18-348.6.1.el5.img | file -
# /dev/stdin: ASCII cpio archive (SVR4 with no CRC)
Building initrd manually
If mkinitrd is unavailable, build the image by hand using a block device โ a RAM disk (/dev/ram0) or a loopback device:
# 1. Create a filesystem on the RAM disk (300 blocks)
mke2fs -m0 /dev/ram0 300
# 2. Mount it
mount -t ext2 /dev/ram0 /mnt
# 3. Create necessary device nodes and directories
mkdir /mnt/dev
mknod /mnt/dev/tty1 c 4 1
# 4. Create /linuxrc โ the kernel runs this first
# For a test, a symlink to /bin/sh is enough
ln -s /bin/sh /mnt/linuxrc
# 5. Copy required modules, scripts, binaries
# 6. Unmount the RAM disk
umount /dev/ram0
# 7. Copy its contents into an image file
dd if=/dev/ram0 bs=1k count=300 of=/boot/initrd
# 8. Free the RAM disk
freeramdisk /dev/ram0
Connect the image to the bootloader. Example entry in GRUB Legacy config:
title=initrd test entry
root (hd0,0)
kernel /vmlinuz-2.6.28
initrd /initrd
Note:
/linuxrcis the initrd entry point. The kernel finds and runs it immediately after mounting the image. In real systems it is a script that loads modules and mounts the real root.
mkinitrd (RPM-based systems)
# Create an initrd image
mkinitrd /boot/initrd-4.3.3.img 4.3.3
# Useful options
mkinitrd --version # Show version
mkinitrd -f /boot/initrd.img 4.3.3 # Overwrite existing file
mkinitrd --omit-scsi-modules ... # Exclude SCSI modules
mkinitramfs (Debian-based systems)
# Create an initramfs image
mkinitramfs -o /boot/initrd.img-4.3.3 4.3.3
# Specify an alternative config directory
mkinitramfs -d /etc/initramfs-tools -o /boot/initrd.img 4.3.3
The mkinitramfs config file is at /etc/initramfs-tools/initramfs.conf.
Important: The exam tests knowledge of both tools:
mkinitrdfor RPM-based systems (Red Hat, SUSE),mkinitramfsfor Debian-based systems (Debian, Ubuntu). Both produce a gzip-compressed cpio archive.
Patching the Kernel
Note: Kernel patching is no longer in the LPIC-2 exam objectives, but it is useful background for working with kernel sources.
A patch file is the output of diff -u old_file new_file. It consists of change blocks called hunks. Each hunk contains context lines โ unchanged lines surrounding the edit. The patch tool uses this context to locate the right place in the file. Lines to remove are marked -, lines to add are marked +. If the context in the file doesn’t match the context in the patch, patch cannot apply that hunk and saves it to a .rej file.
--- a/drivers/net/foo.c 2024-01-01
+++ b/drivers/net/foo.c 2024-01-02
@@ -42,7 +42,7 @@
int ret;
/* init */
- ret = old_init();
+ ret = new_init();
if (ret < 0)
# 1. Place the patch file in /usr/src/
# 2. Enter /usr/src/
cd /usr/src
# 3. Decompress the patch (if in xz format)
unxz patch-4.3.4.xz
# 4. Apply the patch
patch -p1 < patch-4.3.4
# 5. Check for .rej files (rejected hunks)
find /usr/src/linux -name "*.rej"
The -p<n> option controls how many leading path components to strip. git diff writes paths as a/drivers/net/foo.c โ without stripping, patch looks for that literal path and fails. -p1 strips the first component (a/ or b/), leaving the real relative path:
| Option | Path from patch | Result |
|---|---|---|
-p0 | a/drivers/net/foo.c | a/drivers/net/foo.c โ unchanged |
-p1 | a/drivers/net/foo.c | drivers/net/foo.c โ a/ stripped |
-p2 | a/drivers/net/foo.c | net/foo.c โ a/drivers/ stripped |
For kernel patches the standard is -p1.
Useful patch options:
| Option | Description |
|---|---|
-p<n> | Strip n leading path components |
-s | Silent mode, show errors only |
-R | Reverse the patch (undo) |
-E | Delete empty files after patching |
Reverting a patch
patch -R -p1 < patch-2.6.28
# If patch detects it was already applied:
# Reversed (or previously applied) patch detected! Assume -R? [n] y
DKMS
DKMS (Dynamic Kernel Module Support) was developed by Dell in 2003. The problem was concrete: Dell supported customers running Linux, and every kernel update broke modules for proprietary hardware. DKMS solves this by decoupling module sources from the kernel tree and automatically rebuilding them on kernel upgrades.
When the package manager updates the kernel on a DKMS-enabled system, a hook checks which modules need rebuilding for the new kernel. It also works in reverse: a new module installs without being tied to a specific kernel version.
# 1. Install the DKMS package (sources land in /usr/src/<module-version>/)
apt-get install flashcache-dkms
# 2. Add the module to the DKMS tree
dkms add -m flashcache -v 3.1.1
# 3. Build the module for the current kernel
dkms build -m flashcache -v 3.1.1
# 4. Install the module
dkms install -m flashcache -v 3.1.1
# 5. Check status
dkms status
# 6. Remove the installed module
dkms uninstall -m flashcache -v 3.1.1
Each DKMS module is described by a dkms.conf file in /usr/src/<module-version>/:
BUILT_MODULE_NAME="flashcache"
DEST_MODULE_LOCATION="/kernel/drivers/block"
PACKAGE_NAME="flashcache"
PACKAGE_VERSION="3.1.1+git20140801"
AUTOINSTALL="yes"
REMAKE_INITRD="yes"
MAKE="KERNEL_TREE=$kernel_source_dir make modules"
Key dkms.conf directives:
| Directive | Required | Purpose |
|---|---|---|
BUILT_MODULE_NAME | When 2+ modules | Name of the compiled module |
DEST_MODULE_LOCATION | Yes* | Install path, always starts with /kernel |
PACKAGE_NAME | Yes | Package name |
PACKAGE_VERSION | Yes | Package version |
AUTOINSTALL | No | yes โ install the module on every new kernel boot |
REMAKE_INITRD | No | yes โ rebuild initrd after module install (default no) |
MAKE | No | Build command; if unset, DKMS uses the default make |
* DEST_MODULE_LOCATION is not required on Fedora Core 6+, RHEL 5+, SuSE Linux ES 10+, and Ubuntu โ they use distribution directories.
Warning: The
REMAKE_INITRDdirective reads only the first character of the value โ all others are ignored. The first character is treated as “yes” only if it isyorY.yesandYESbehave identically; so donoandnope.
Working with module archives
DKMS can work with tar archives, which is useful for transferring modules between systems:
# Create a tarball from the current modules on this system
dkms mktarball -m flashcache -v 3.1.1
# Import the tarball into the DKMS tree on another system
dkms ldtarball /path/to/flashcache-3.1.1.tar.gz
The archive must contain a valid dkms.conf.
Example config locations
Debian: /usr/share/doc/dkms/examples/
Red Hat: /usr/share/doc/dkms/
Important: DKMS requires kernel headers to be installed:
apt-get install linux-headers-$(uname -r)oryum install kernel-devel.
Note: Global DKMS configuration is in
/etc/dkms/framework.conf. Thesource_treevariable there tells DKMS where to look fordkms.confdirectories.
Dracut
Dracut is a utility for creating initramfs images that supports multiple distributions and can work in event-driven mode. Similar to how DKMS reacts to kernel upgrades and rebuilds modules, dracut reacts to changes and automatically rebuilds the initramfs image.
# Create initramfs for the running kernel
dracut /boot/initramfs-$(uname -r).img $(uname -r)
# Force recreate (overwrite existing image)
dracut --force /boot/initramfs-$(uname -r).img $(uname -r)
Note: The LPIC-2 exam only requires knowing that dracut exists and what it does โ automatic initramfs creation when needed. Deep configuration is not tested.
Exam Cheat Sheet
Key Paths
/usr/src/linux/ โ symbolic link to kernel sources
/usr/src/linux/.config โ kernel configuration file
/boot/vmlinuz-<ver> โ kernel image
/boot/System.map-<ver> โ symbol table
/boot/initrd-<ver>.img โ initial RAM disk
/lib/modules/<ver>/ โ kernel modules
/lib/modules/<ver>/modules.dep โ dependency file
/etc/dkms/framework.conf โ DKMS configuration
/etc/initramfs-tools/initramfs.conf โ mkinitramfs configuration
Key Commands
make mrproper # Full clean + remove .config
make clean # Remove object files only
make menuconfig # Text configurator (ncurses)
make oldconfig # Update .config for new kernel options
make bzImage # Build compressed kernel image
make modules # Build modules only
make modules_install # Install modules to /lib/modules/
depmod -a # Regenerate modules.dep
mkinitrd /boot/img.img <ver> # Create initrd (RPM)
mkinitramfs -o /boot/img.img <ver> # Create initramfs (Debian)
dkms status # DKMS module status
dkms add/build/install # DKMS module lifecycle
update-grub / grub2-mkconfig # Update GRUB config
Common Exam Mistakes
make mrproperdeletes.config;make cleandoes not.mkinitrdis for RPM-based systems;mkinitramfsis for Debian.- After
make modules_install, rundepmod -a. - The compiled
bzImageis atarch/x86/boot/bzImagerelative to the source tree root. DEST_MODULE_LOCATIONindkms.confmust start with/kernel.
Practice Questions
Q1. An admin downloaded kernel sources 4.3.3 and extracted them to /usr/src/linux-4.3.3. Which command makes /usr/src/linux point to these sources?
A) cp -r /usr/src/linux-4.3.3 /usr/src/linux
B) ln -s /usr/src/linux-4.3.3 /usr/src/linux
C) mount --bind /usr/src/linux-4.3.3 /usr/src/linux
D) mv /usr/src/linux-4.3.3 /usr/src/linux
Answer: B. Use a symbolic link. Option A duplicates files; D renames the directory and breaks the version reference.
Q2. An admin wants to update the kernel config from 4.3 to 4.4, keeping all existing settings and only answering questions about new options. Which make target should they use?
A) make config B) make defconfig C) make oldconfig D) make menuconfig
Answer: C. make oldconfig reads the existing .config and asks only about new options. make config asks everything from scratch.
Q3. After compiling the kernel on an x86_64 system, where is the resulting bzImage?
A) /usr/src/linux/bzImage
B) /usr/src/linux/arch/x86/boot/bzImage
C) /boot/bzImage
D) /usr/src/linux/kernel/bzImage
Answer: B. The file is created at arch/x86/boot/bzImage relative to the source tree root.
Q4. Which command creates /lib/modules/<version>/modules.dep?
A) modprobe --update B) insmod --deps C) depmod -a D) ldconfig
Answer: C. depmod -a scans all modules in /lib/modules/<version>/ and writes the dependency file modules.dep.
Q5. An admin on a Debian system wants to create an initramfs image for kernel version 4.3.3. Which command should they use?
A) mkinitrd /boot/initrd-4.3.3.img 4.3.3
B) dracut /boot/initrd.img 4.3.3
C) mkinitramfs -o /boot/initrd.img-4.3.3 4.3.3
D) mkinitrfs 4.3.3 /boot/initrd.img
Answer: C. mkinitramfs is the Debian tool. mkinitrd is for RPM-based systems (Red Hat, SUSE).
Q6. Which file must be present in a DKMS module directory under /usr/src/?
A) Makefile B) dkms.conf C) module.spec D) .config
Answer: B. dkms.conf contains the directives for DKMS and is mandatory for the framework to function.
Q7. An admin wants to completely reset the kernel configuration and remove all previously compiled object files. Which command should they use?
A) make clean B) make distclean C) make mrproper D) make reset
Answer: C. make mrproper removes both object files and .config. make clean removes only object files, preserving .config.
Q8. After installing a new kernel and running make modules_install, the admin notices modprobe cannot load the new module, complaining about a missing dependency file. What fixes this?
A) Restart udevd
B) Run depmod -a
C) Run ldconfig
D) Rebuild the kernel with make all
Answer: B. depmod -a creates the modules.dep file that modprobe reads to resolve dependencies.