Device Drivers & Kernel Modules

the module lifecycle

A loadable module has a clear birth and death, unlike a normal program that runs from main() to return. It has two key moments: the instant it is loaded (init), where it must set everything up, and the instant it is removed (exit), where it must tear everything down. Picture a temporary stall at a market: when you arrive you put up the tent and lay out goods; when you leave you must pack every single thing, or you leave litter behind that nobody will clean up.

Concretely, you mark one function with module_init() and one with module_exit(). When insmod or modprobe loads the .ko, the kernel calls the init function exactly once; it returns 0 for success or a negative error code (like -ENODEV) if it cannot proceed, in which case the load fails and the module is discarded. The init function typically registers a device, allocates buffers, requests an IRQ, and maps registers. The exit function, called by rmmod, must undo all of that in reverse order: free the buffers, free the IRQ, unregister the device. There is no garbage collector and no automatic cleanup — whatever init grabbed, exit must release.

This matters because the kernel keeps running for months, so every leak accumulates: a module that allocates memory in init but forgets to free it in exit leaks kernel memory on every load/unload cycle, and a missing unregister can leave a stale pointer that crashes the kernel later when something calls into your unloaded code. A common, dangerous mistake is partial-failure cleanup: if init succeeds at step 1 and 2 but fails at step 3, it must undo steps 2 and 1 before returning the error — error paths must unwind exactly what succeeded.

static int __init my_init(void) { int err = register_chrdev(...); if (err) return err; // load fails cleanly return 0; // success } static void __exit my_exit(void) { unregister_chrdev(...); // undo exactly what init did } module_init(my_init); module_exit(my_exit);

The minimal lifecycle: init returns 0 or a negative error; exit reverses init. The __init/__exit hints let the kernel free that code after use.

Error paths in init must unwind in reverse the steps that already succeeded; forgetting this leaks kernel resources or leaves dangling registrations that crash the kernel after unload.

Also called
init/exitmodule load and unload模組載入與卸載