The Linux Kernel Module Programming Guide (Peter Jay Salzman, Michael Burian etc.) (Z-Library)
Linux
A book on linux kernel modules
AI Reading Assistant
Whole-book reading guide from stratified index samples; jump to passages in the text
AI guide
【One-Line Pitch】
A practical, hands-on guide for anyone who wants to write Linux kernel modules—from your first "Hello World" to full character device drivers—covering everything from build systems to kernel internals, with a focus on doing, not just reading.
【Book Arc】
- **Opening (~0%–10%)**: Introduces what kernel modules are, why they exist, and the essential setup—installing headers, understanding module versioning (modversions), and the critical Makefile pattern for building modules against your running kernel. This stage solves the "how do I even compile this?" problem.
- **Early (~10%–30%)**: Walks through the anatomy of a module: the mandatory init/cleanup functions, the `__init`/`__exit` macros, licensing with `MODULE_LICENSE`, and passing command-line arguments via `module_param()`. Also covers multi-file modules and the tricky business of building for a precompiled kernel, including a deep dive into why `PWD` gets lost under `sudo`.
- **Early-to-Middle (~30%–40%)**: Shifts from "how to write" to "what you're writing against"—explaining user space vs. kernel space, the ring model (ring 0 vs. user mode), and how system calls bridge the two. Uses `strace` to demystify what `printf()` actually does, setting the stage for writing code that runs in supervisor mode.
- **Middle (~40%–60%)**: Dives into character device drivers, the heart of the book. Covers the `file_operations` structure (with C99 designated initializers), the kernel's `struct file` vs. glibc's `FILE`, and the registration process—choosing between `register_chrdev_region` and `alloc_chrdev_region`, plus initializing `struct cdev`. Includes a full, annotated example driver.
- **Late (~60%–100%)**: The excerpts thin out here, but the trajectory points toward advanced topics like proc filesystem handlers (`proc_ops`), and likely more complex driver patterns. The guide's structure suggests a progression from simple modules to production-grade device drivers.
【Key Takeaways】
- **The Makefile is half the battle** (Early): Building modules isn't like compiling user-space code—you must use the kernel's build system with `obj-m` and `make -C /lib/modules/$(uname -r)/build M=$(PWD) modules`. The `PWD := $(CURDIR)` line is a subtle but critical fix for `sudo make` failures, since `sudo` resets environment variables by default.
- **Every module needs a start and an end** (Early): At minimum, you need an init function (called on `insmod`) and a cleanup function (called on `rmmod`). Modern kernels let you name them anything via `module_init()` and `module_exit()`, but the classic `init_module()`/`cleanup_module()` still works.
- **Licensing isn't just legal—it's technical** (Early): `MODULE_LICENSE("GPL")` isn't a formality. An "unspecified" license taints the kernel, which can affect debugging and support. The macro accepts values like "GPL", "Dual BSD/GPL", and "Proprietary".
- **Command-line arguments work differently in kernel space** (Early): No `argc`/`argv` here. Declare globals, then use `module_param()` (with type and permission bits) and `module_param_array()` for arrays. At load time, `insmod` fills them in—e.g., `sudo insmod hello-5.ko mystring="bebop" myintarray=-1`.
- **Kernel space is a different world** (Early-to-Middle): The kernel runs in ring 0 (supervisor mode) where all actions are permissible, while user programs run in user mode. Library functions like `printf()` are just wrappers around system calls that execute in kernel space on your behalf—`strace` reveals the `write()` underneath.
- **Character devices are built on `file_operations`** (Middle): This struct holds function pointers for `read`, `write`, `open`, `release`, etc. Use C99 designated initializers (`.read = device_read`) for portability, and know that unassigned members default to NULL. Since Linux v3.14, read/write/seek are thread-safe via the `f_pos` lock.
- **`struct file` is not `FILE`** (Middle): The kernel's `struct file` represents an abstract open file (often named `filp`), distinct from glibc's `FILE` and from on-disk files (which are `inode`s). Drivers don't fill `file` directly—they use structures contained within it.
- **Register your device numbers carefully** (Middle): Use `register_chrdev_region()` when you know the major number, or `alloc_chrdev_region()` for dynamic allocation. Then initialize `struct cdev`—either with `cdev_alloc()` for standalone use or `cdev_init()` when embedding it in your own device structure.
【Reading Tips】
- **Skim the licensing and authorship sections** (Opening): They're boilerplate. Jump straight to Section 1.3 ("What Is A Kernel Module?") and the Hello World examples.
- **Deep-read the Makefile and build sections** (Early): This is where beginners stumble. Pay special attention to the `PWD := $(CURDIR)` fix and the modversioning warning—if your module won't load, it's often a version mismatch, not a code bug.
- **Work through the examples in order, from a console** (Early): The book explicitly warns against using X Window System for this. Each example (hello-1 through hello-5) builds on the last—don't skip ahead. Use `journalctl` or `dmesg` to see your module's output.
- **Treat the character device chapter as the main course** (Middle): Read the full `chardev` example carefully, line by line. Understand the `atomic_t` usage for preventing multiple opens, and the `__user` annotation on buffer pointers—it's a hint about kernel/user memory boundaries.
- **Skim the kernel internals sections** (Early-to-Middle): The user space vs. kernel space discussion and the `strace` detour are useful context, but you can skim if you're eager to write code. Come back to them when you hit a "why isn't this working?" moment.
【Coverage Limits】
The excerpts cover roughly the first 60% of the book in detail (through character device drivers). Later sections—likely covering proc filesystems, advanced driver patterns, and module versioning in depth—are not represented in this guide's source material.
Page 3
ce . . . . . . . . . . . . . . . . . . . . . . . . . . 24 5.6 Device Drivers . . . . . . . . . . . . . . . . . . . . . . . . 25 6 Character Device drivers . ...
View in text
Page 14
learn how to do this in Section 4.2. 4.2 Hello and Goodbye In early kernel versions you had to use the init_module and cleanup_module functions, as in the fi...
View in text
Excerpt 3
be familiar with write, since most people use library func- tions for file I/O (like fopen, fputs, fclose). If that is the case, try looking at man 2 write. ...
View in text
Excerpt 4
In this case, we’ll need cdev_init for the initialization. 1 void cdev_init(struct cdev *cdev, const struct file_operations *fops); Once we finish the initia...
View in text
Excerpt 5
n", procfs_buffer_size); 51 return procfs_buffer_size; 52 } 53 static int procfs_open(struct inode *inode, struct file *file) 54 { 55 try_module_get(THIS_MOD...
View in text
Excerpt 6
data *ioctl_data; 128 129 pr_alert("%s call.\n", __func__); 130 ioctl_data = kmalloc(sizeof(struct test_ioctl_data), GFP_KERNEL); 131 132 if (ioctl_data == N...
View in text
Excerpt 7
l about KASLR (Ker- nel Address Space Layout Randomization). KASLR may randomize the address of kernel code and data at every boot time, such as the static a...
View in text
Excerpt 8
(unsigned long **)sym; 198 199 return NULL; 200 #endif 201 202 #ifdef HAVE_KPROBES 203 unsigned long (*kallsyms_lookup_name)(const char *name); 204 struct kp...
View in text
Tags
AI categories
LinuxOSProgramming Language
Text Preview (First 20 pages)
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
Generating text preview…
Loading comments...
Reply to Comment
Edit Comment