A driver copied out of a 2022 kernel book often will not compile on today’s kernel. The driver core changed class_create() in 6.4, the I2C core made its remove() callback return void in 6.1, and the platform bus did the same in 6.11. A chapter that built cleanly when it went to print now stops at the first make, so you need to know which kernel each book targets before you buy it.
Below are eight Linux kernel programming books, from a first loadable module through drivers, debugging, embedded systems and the system call layer. We checked every edition against the publisher and Amazon’s catalog, then built the companion code from three of them against the current stable kernel. Every build in this guide was run on Fedora 45 with kernel 7.2.11 in October 2026, and the errors you’ll hit are captured further down.
Pick a Book by the Code You Write
Most readers need one core book plus one for their specialty. Start from the kind of kernel code you will actually be writing:
- Best first kernel book: Linux Kernel Programming, Second Edition
- Best for device drivers: Linux Device Driver Development, Second Edition
- Best for character drivers and interrupts: Linux Kernel Programming Part 2
- Best for finding kernel bugs: Linux Kernel Debugging
- Best for embedded boards: Mastering Embedded Linux Development, Fourth Edition
- Best system call reference: The Linux Programming Interface
If you have never written C, fix that first; our list of C and C++ books has the beginner titles. Readers who want to trace and profile a running kernel rather than change it should look at the eBPF books instead, because that’s where tracing work happens now.
How We Picked and Tested
We searched Amazon’s catalog by publisher (Packt, O’Reilly, No Starch Press, Addison-Wesley, Manning and Apress) as well as by keyword, because a keyword search for “linux kernel” returns more self-published titles than trade books. Each pick had to be a print edition sold new on Amazon in October 2026, and its contents come from the publisher’s page or the book’s companion repository on GitHub.
For the lab we cloned a Fedora 45 VM, installed kernel-devel for the running 7.2.11 kernel, and ran each book’s module code through the kernel’s own build system. Linux Kernel Programming and its Part 2 built cleanly. Linux Device Driver Development failed in all three chapters we tried. The kernel.org release table put mainline at 7.3 and the newest longterm branch at 6.18 when we checked, so no book here targets anything newer than 6.6, two longterm branches behind.
Some well-known titles did not make the list, mostly because of age:
- Understanding the Linux Kernel, 3rd Edition (2005) and Linux Kernel in a Nutshell (2006)
- Linux Device Drivers, 3rd Edition (2005), which LWN hosts free under a Creative Commons license and which is current as of 2.6.10
- Linux System Programming, 2nd Edition (2013), now scarce on Amazon
- Rust kernel books, which so far come only from small presses and self-publishers
Linux Device Drivers in Action, a new Packt title by Kaiwan Billimoria, was listed for preorder with a January 2027 date, so it is not reviewed here.
Compare the Eight Books
The kernel column matters more than the publication date. It tells you which API changes in the build section below will hit you while you work through the code:
| Book | Publisher, date | Kernel it targets | Pages | Best for |
|---|---|---|---|---|
| Linux Kernel Programming, 2nd Ed | Packt, February 2024 | 6.1 LTS | 826 | Modules, memory, scheduler, locking |
| Linux Kernel Programming Part 2 | Packt, March 2021 | 5.4 LTS | 452 | Char drivers, interrupts, user-kernel interfaces |
| Linux Device Driver Development, 2nd Ed | Packt, April 2022 | Not stated | 708 | Device tree, I2C, SPI, GPIO, IIO |
| Linux Kernel Debugging | Packt, August 2022 | 5.10 LTS | 638 | KASAN, KCSAN, ftrace, KGDB |
| Linux Kernel Development, 3rd Ed | Addison-Wesley, June 2010 | 2.6 | 480 | How the subsystems are designed |
| The Linux Programming Interface | No Starch, October 2010 | 2.6.35, glibc 2.12 | 1,552 | The system call API |
| System Programming in Linux | No Starch, September 2025 | Not stated | 1,048 | Learning system programming in C |
| Mastering Embedded Linux Development, 4th Ed | Packt, May 2025 | 6.6, Yocto 5.0 | 710 | Buildroot, Yocto, real boards |
1. Linux Kernel Programming, Second Edition
Kaiwan N. Billimoria’s book is the one to start with. It’s the newest general kernel title from a trade publisher, and the only general one written for a 6.x kernel, so its code still builds today:
You build the 6.1 LTS kernel from source across two chapters and write a first loadable module. The rest of the book works through process and thread internals, memory management, the kernel memory allocators, the CPU scheduler (including cgroups v2) and two chapters on synchronization. The companion repository says the code was tested on Ubuntu 22.04 and 23.04, Fedora 38 and 39, and a Raspberry Pi 4 running the author’s own 6.1 build. That means you can follow it on a laptop VM or a cheap board.
Its hello-world module from chapter 4 built without a single change on kernel 7.2.11 in our lab. The failure you will most likely meet with this book is not the code at all but Secure Boot, covered further down, because a self-built module is unsigned. The book was printed when 6.1 was due to end in December 2026; kernel.org has since pushed that to December 2027, so the kernel you build in chapter 2 is still a supported longterm branch.
The weak spot is scheduler internals. Its scheduler chapters describe CFS, and Linux 6.6 replaced CFS with EEVDF, so treat those two chapters as history. It sold for $25 to $35 when we checked. Check the current price on Amazon.
2. Linux Kernel Programming Part 2
The companion volume picks up where the first book’s module chapters end. It turns them into real character drivers, which is the step most readers want next:

You write a misc class character driver, then connect it to user space through procfs, sysfs, debugfs, netlink sockets and ioctl. Later chapters handle hardware interrupts (IRQ allocation, threaded handlers, tasklets and softirqs), memory-mapped peripheral I/O, kernel timers, kthreads and workqueues. Packt’s description says the code targets the 5.4 LTS kernel, which kernel.org no longer maintains.
Age is less of a problem than that suggests. The author kept the repository current after print, it now carries version checks for kernels up to 6.6, and its chapter 1 misc driver built cleanly on 7.2.11 for us. Clone the repository rather than typing the listings from the page, because the repository has been updated since the book was printed.
Pass on it if synchronization is all you need, since the second edition of pick 1 already has two chapters on it. Expect to pay $35 to $45, since it sells near list. Check the current price on Amazon.
3. Linux Device Driver Development, Second Edition
John Madieu writes for embedded developers, so this book spends its pages on the buses and subsystems a board exposes rather than on PC hardware:
Its 17 chapters start with building and tailoring the kernel, then cover these driver topics:
- Describing hardware with the device tree
- Platform drivers, I2C and SPI client drivers
- The regmap framework and DMA
- Timekeeping and concurrency managed workqueues
- The GPIO, IIO and input subsystems
The book assumes a Cortex-A board (a Raspberry Pi, BeagleBone or Jetson Nano works) because most of the subsystems only make sense with real pins and buses attached.
Of the three books we built, this one ages worst on a current kernel. Chapter 4’s character driver, chapter 7’s platform driver and chapter 16’s I2C GPIO expander all failed to build on 7.2.11. All three predate the class_create() change in 6.4, the void remove() callbacks and the removal of gpiochip_add() in 6.11 in favor of gpiochip_add_data(). Each fix is a few lines, and the build section shows the errors so you can recognize them.
Do not buy it for code that compiles as printed; buy it for the subsystem explanations, which have not changed much. It sold for $35 to $45 when we checked. Check the current price on Amazon.
4. Linux Kernel Debugging
The third Billimoria title on this list is about finding what’s wrong once your module runs. It’s the only pick here built around that job, so buy it when your code loads but misbehaves:
The chapters open with instrumentation (printk and the dynamic debug framework), move to static and dynamic kprobes, then spend several chapters on memory defects with KASAN, UBSAN, SLUB debug and kmemleak. Data races get their own treatment with KCSAN, tracing is done with Ftrace and trace-cmd, and the last part single-steps module code under KGDB. The repository’s examples run on 5.10 kernels under Ubuntu 21.04 and 21.10.
Debugging tools age more slowly than driver APIs, since KASAN and Ftrace work the same way on 7.x, but menu paths and config option names in the book won’t always match your kernel’s make menuconfig. Pair it with our guide to compiling the kernel from source, because most of these tools need a debug build.
Leave it until you have written a few modules; it assumes you already know the code you are debugging. It cost $40 to $50 when we checked. Check the current price on Amazon.
5. Linux Kernel Development, Third Edition
Robert Love’s book is sixteen years old, and it still explains why the kernel is built the way it is better than it explains any API:
Its 20 chapters go subsystem by subsystem, from process management and scheduling through system calls, interrupts and bottom halves, synchronization, timers and memory management. Later chapters cover the virtual filesystem, the block I/O layer, the page cache, and devices and modules. Each one explains the design before the code, which suits readers who want to know why before they type anything.
Everything in it describes the 2.6 kernel, so read it for concepts and never for function signatures. The scheduler chapter is about CFS, which EEVDF replaced in 6.6, so treat the code excerpts as 2.6-era illustrations rather than something to compile.
If you learn by typing code, start with pick 1 instead. It sold for $25 to $35 when we checked. Check the current price on Amazon.
6. The Linux Programming Interface
Michael Kerrisk maintained the Linux man-pages project for years. This is his reference for the system call layer that every driver you write is reached through:
At 1,552 pages it covers the whole API between user space and the kernel:
- Files, file I/O and filesystems
- Processes, signals, threads and timers
- Pipes, FIFOs, message queues, semaphores and shared memory
- Sockets and terminals
Kernel work needs it because you have to know what user space expects of the read(), ioctl() or mmap() your driver implements. A driver that returns the wrong error code from one of them breaks programs that followed the man page to the letter.
The book went to press current as of Linux 2.6.35 and glibc 2.12, but Kerrisk keeps a list of API changes since publication, kept up kernel release by kernel release. Read the two together and the age stops mattering much. There’s no second edition yet.
Price is the catch, since the hardcover sold for close to $100 through a third-party seller when we checked, and stock was listed as limited. Check the current price on Amazon.
7. System Programming in Linux
Stewart N. Weiss’s book is the newest one here. It covers the same territory as pick 6, but as a course, so it’s the gentler way in:
Weiss wrote it as a course rather than a reference. Its 19 chapters start from core concepts and build up through file I/O, filesystems, signals, timers and process creation, then move on to pipes, daemons, threads, alternative I/O methods, terminals and NCurses. Each chapter has you write working programs, which suits a reader who finds Kerrisk too dense to start with.
Kernel internals and driver code are out of scope, so it belongs on this list as the user-space half of the picture. Read it before pick 1 if you’ve written C but never called fork() or handled a signal.
You can skip it if you already own The Linux Programming Interface. It sold for $70 to $80 when we checked. Check the current price on Amazon.
8. Mastering Embedded Linux Development, Fourth Edition
Chris Simmonds wrote the first two editions of this embedded Linux title alone, and Frank Vasquez has co-written it since the third, so it is now on its fourth. The latest is from May 2025, so its kernel and build tools are recent:

Its 21 chapters build complete systems with Buildroot 2024.02 LTS and Yocto Project 5.0 (Scarthgap) on a Linux 6.6 kernel, using a BeaglePlay, a Raspberry Pi 4 and QEMU as targets. It covers toolchains, U-Boot, the kernel build, root filesystems, over-the-air updates with Mender or balena, and talking to hardware from user space without writing a driver. That last part is often the right answer for a prototype.
The repository’s errata says the exercises need an x86-64 Ubuntu 24.04 host, so on an Apple Silicon Mac you’ll be working inside an x86-64 Ubuntu VM (the author suggests Parallels with Rosetta). Readers coming from microcontrollers will also want our IoT books for the device side.
Readers who only write drivers for PCs and servers can skip it. It sold for $20 to $30 when we checked. Check the current price on Amazon.
Build Book Code on a Current Kernel
Every one of these books asks you to build modules against your running kernel, and on a 2026 distribution that fails in a few predictable ways. On Fedora, install the compiler, the kernel headers and dwarves, which provides the pahole tool the build uses for BTF type data:
sudo dnf -y install gcc make elfutils-libelf-devel dwarves git
Then install the headers on their own line, so a missing headers package cannot take the toolchain down with it:
sudo dnf -y install kernel-devel-$(uname -r)
dnf treats an unavailable package as a failed transaction, so on one combined line a missing kernel-devel would also leave gcc and make uninstalled. Naming the package as kernel-devel-$(uname -r) asks for headers that match the kernel you’re running, not just the newest ones in the repository. If dnf answers with No match for argument, the troubleshooting entry for that error below has the fix. Otherwise, confirm both versions before building anything:
uname -r
rpm -q kernel-devel-$(uname -r)
Both lines should show the same version, as they did on our lab VM:
7.2.11-300.fc45.x86_64
kernel-devel-7.2.11-300.fc45.x86_64
With matching headers, clone a book’s repository and build a chapter through the kernel’s build system. This is the platform driver from chapter 7 of Linux Device Driver Development:
git clone https://github.com/PacktPublishing/Linux-Device-Driver-Development-Second-Edition.git
cd Linux-Device-Driver-Development-Second-Edition/Chapter07
make -C /lib/modules/$(uname -r)/build M=$PWD modules
The kernel’s own build flags turn incompatible pointer types into errors, whatever GCC version you have: scripts/Makefile.warn in the 7.2 headers adds -Werror=incompatible-pointer-types. A callback with the wrong return type therefore stops the build instead of printing a warning. These are the lines that stop it:
platform-dummy-char.c:61:19: error: too many arguments to function βclass_createβ; expected 1, have 2
61 | dummy_class = class_create(THIS_MODULE, "dummy_char_class");
| ^~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
platform-dummy-char.c:104:19: error: initialization of βvoid (*)(struct platform_device *)β from incompatible pointer type βint (*)(struct platform_device *)β [-Wincompatible-pointer-types]
104 | .remove = my_pdrv_remove,
| ^~~~~~~~~~~~~~
Each error maps to one change in the kernel’s driver API. We checked the version that introduced each one in the kernel source, and these are the six you will meet in code written for kernels older than 6.11:
| Book code | Current kernel | Changed in |
|---|---|---|
class_create(THIS_MODULE, "name") | class_create("name") | 6.4 |
int I2C remove() callback | Returns void | 6.1 |
I2C probe(client, id) | probe(client), one argument | 6.3 |
int platform remove() callback | Returns void | 6.11 |
struct gpio_chip from <linux/gpio.h> | Include <linux/gpio/driver.h> | 6.4 |
gpiochip_add(chip) | gpiochip_add_data(chip, NULL) | 6.11 |
The fix for the first one is a one-word edit. Chapter 4’s character driver fails only on class_create(), so move to that chapter and remove THIS_MODULE from the call:
cd ../Chapter04
sed -i 's/class_create(THIS_MODULE, "dummy_char_class")/class_create("dummy_char_class")/' dummy-char.c
make -C /lib/modules/$(uname -r)/build M=$PWD modules
The missing-prototype warnings stay, but the build now links the module, which is how it finished on our 7.2.11 VM:
MODPOST Module.symvers
CC [M] dummy-char.mod.o
CC [M] .module-common.o
LD [M] dummy-char.ko
BTF [M] dummy-char.ko
Skipping BTF generation for dummy-char.ko due to unavailability of vmlinux
For the remove() callbacks, change the function to return void and delete its return 0; line. The probe change works the same way: drop the i2c_device_id argument and call i2c_client_get_device_id() inside the function if the driver still needs it. Chapter 16’s GPIO expander fails first with field βchipβ has incomplete type, because since 6.4 <linux/gpio.h> no longer provides struct gpio_chip. Include <linux/gpio/driver.h> instead and replace gpiochip_add(chip) with gpiochip_add_data(chip, NULL).
insmod: ERROR: could not insert module: Key was rejected by service
This one is not the book’s fault. A module you build yourself is unsigned, and a machine with Secure Boot enabled refuses to load it. Loading the Linux Kernel Programming hello-world module on our lab VM failed like this:
insmod: ERROR: could not insert module ./helloworld_lkm.ko: Key was rejected by service
The kernel log names the cause:
[ 64.668107] Loading of unsigned module is rejected
On a throwaway VM, the simplest fix is to turn Secure Boot off in the VM’s firmware settings. On a machine you care about, sign the module instead, using the kernel’s scripts/sign-file and a key you enroll with mokutil --import. On Fedora the script ships at /usr/src/kernels/$(uname -r)/scripts/sign-file, and the kernel module signing guide covers the steps. Check which case you’re in first:
mokutil --sb-state
No match for argument: kernel-devel
dnf prints this when the headers for your running kernel have left the repositories. Our Fedora 45 VM started on an older kernel, so the headers install stopped at the first error:
No match for argument: kernel-devel-7.2.7-300.fc45.x86_64
There is no package to install for that kernel any more, so the fix is to move to the newest one, as in the next error.
make: *** /lib/modules/…/build: No such file or directory
This means there are no headers for the kernel you are running. If you skip the failed install and go straight to make, the build finds the build link pointing at nothing:
make: *** /lib/modules/7.2.7-300.fc45.x86_64/build: No such file or directory. Stop.
Bring the system up to date, install the headers for the newest kernel, then reboot into it. A full dnf upgrade picks up the new kernel together with whichever kernel packages your system has installed, modules included. Use install for the headers rather than upgrade: on our VM dnf upgrade kernel-devel refused with “available, but not installed” because no headers package was present yet:
sudo dnf -y upgrade --refresh && sudo dnf -y install kernel-devel && sudo reboot
After the reboot, uname -r and rpm -q kernel-devel-$(uname -r) agreed again, both on the new kernel. On Debian and Ubuntu the matching package is linux-headers-$(uname -r), and on Kali the same steps are in our guide to installing kernel headers on Kali.
warning: pahole version differs from the one used to build the kernel
The build prints this when pahole is not installed at all, which shows up as “You are using: 0”. The module still builds, but without BTF type information. Installing dwarves removes the warning; on a distribution kernel the build then reports that it skipped BTF generation because vmlinux isn’t available, which is harmless for learning modules.
Buy for the Kernel You’ll Ship
Start with Linux Kernel Programming, Second Edition, because it is the only general book written for a 6.x kernel and its code still builds. Add Part 2 or Linux Device Driver Development for drivers, expecting to fix the older API calls yourself, and keep Love’s book and The Linux Programming Interface for the concepts that have not moved. When you need something newer than any of these, the kernel’s own documentation and our notes on what changed in kernel 7.1 are where the current APIs are written down. Our Linux books for sysadmins cover the administration side if that’s where you are starting from.





