Step-by-Step Guide: Compile Linux Kernel and Debug with QEMU + GDB
Learn how to compile the Linux 4.19.172 kernel on CentOS, create a rootfs with BusyBox, and set up QEMU‑based debugging using GDB, including required kernel boot parameters, troubleshooting static linking errors, and optional Eclipse visual debugging.
1. Overview
When analyzing kernel execution flows, GDB step‑by‑step debugging is often more direct than BPF tracing. This guide details compiling a Linux kernel on a 16‑core CentOS 7.7 machine, building a BusyBox root filesystem, and debugging the kernel in an Ubuntu 20.04 VM using QEMU and GDB. Adding the nokaslr boot parameter is essential for breakpoints to be hit.
2. Linux Kernel Compilation
The source is downloaded from the Tsinghua mirror (e.g., linux-4.19.172.tar.gz) and compiled on CentOS 7.7.
sudo yum group install "Development Tools"
yum install ncurses-devel bison flex elfutils-libelf-devel openssl-devel
wget http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/v4.x/linux-4.19.172.tar.gz
tar xzvf linux-4.19.172.tar.gz
cd linux-4.19.172/
make menuconfigEnable Compile the kernel with debug info (already selected in 4.19.172) under Kernel hacking → Compile-time checks and compiler options . Verify the option:
# grep CONFIG_DEBUG_INFO .config
CONFIG_DEBUG_INFO=yCompile the kernel using all available cores:
# nproc # show CPU count
make -j 12 # or make bzImage -j NResulting files: vmlinux – uncompressed kernel with symbols (≈ 449 MiB) arch/x86_64/boot/bzImage – compressed boot image (≈ 7.6 MiB)
3. Building the Initramfs with BusyBox
# Install static dependencies
yum install -y glibc-static.x86_64 -y
wget https://busybox.net/downloads/busybox-1.32.1.tar.bz2
tar -xvf busybox-1.32.1.tar.bz2
cd busybox-1.32.1/
make menuconfig
make && make install
cd _install
mkdir proc sys
touch init
chmod +x init
find . | cpio -o --format=newc > ./rootfs.img
ls -lh rootfs.imgThe init script prints timing information during boot:
#!/bin/sh
echo "{==DBG==} INIT SCRIPT"
mkdir /tmp
mount -t proc none /proc
mount -t sysfs none /sys
mount -t debugfs none /sys/kernel/debug
mount -t tmpfs none /tmp
mdev -s
echo -e "{==DBG==} Boot took $(cut -d' ' -f1 /proc/uptime) seconds"
setsid /bin/cttyhack setuidgid 1000 /bin/sh4. Error Troubleshooting
Static linking may fail with messages such as:
/bin/ld: cannot find -lcrypt
/bin/ld: cannot find -lm
... (other missing libraries)Install the missing static libraries (e.g., glibc-static) or use yum provides */libm.a to locate the appropriate packages, then rebuild.
5. Launching the Kernel with QEMU
On the Ubuntu 20.04 host (installed inside VirtualBox), install QEMU tools:
apt install qemu qemu-utils qemu-kvm virt-manager libvirt-daemon-system libvirt-clients bridge-utilsCopy vmlinux, bzImage, rootfs.img, and the kernel source directory to the Ubuntu machine.
Start QEMU with GDB support:
qemu-system-x86_64 -kernel ./bzImage -initrd ./rootfs.img -append "nokaslr console=ttyS0" -s -S -nographicExplanation of key parameters: -kernel ./bzImage: specifies the kernel image. -initrd ./rootfs.img: supplies the initramfs. -append "nokaslr console=ttyS0": disables KASLR and redirects console output to the serial port; nokaslr is required for GDB breakpoints. -s: opens a GDB stub on port 1234. -S: pauses the VM at startup, waiting for GDB. -nographic: runs without a graphical display, sending output to the terminal.
6. GDB Debugging
On a second terminal, launch GDB against the uncompressed kernel:
(gdb) file vmlinux
(gdb) target remote :1234
(gdb) break start_kernel
(gdb) continueThe kernel stops at start_kernel, allowing step‑by‑step inspection.
7. Eclipse Visual Debugging (Optional)
Import the kernel source as a “Makefile Project with Existing Code” in Eclipse CDT. Create a “C/C++ Attach to Application” debug configuration:
Project: the imported kernel project.
C/C++ Application: vmlinux (with symbols).
Build before launching: disable auto‑build.
Debugger: gdbserver with TCP port 1234.
Start the debug session to obtain a graphical view similar to the GDB console.
8. References
How to compile and install Linux Kernel 5.6.9 from source code
Using QEMU + GDB to debug Linux kernel
QEMU + BusyBox environment setup
Full QEMU + GDB kernel debugging workflow
Linux kernel compilation and debugging methods
How to Build A Custom Linux Kernel For Qemu (2015 Edition)
Differences between QEMU and QEMU‑KVM
Debugging Linux kernel in QEMU environment
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
