# 研讀 The Linux Kernel Module Programming Guide > https://sysprog21.github.io/lkmpg/ ## Pre kernel modules 至少要有兩個函式: - `init_module()` which is called when `insmod` - `cleanup_module()` which is called when `rmmod` `cleanup_module()` is supported to undo whatever `init_module()` did. - kernel coding style about indentation is tabs not spaces. - print macros : `pr_info()`, `pr_debug()` - To learn how to compile modules which are not offical, see Documentation/kbuild/modules.rst. - details about Makefiles for kernel modules, see Documentation/kbuild/makefile.rst. `init_module()` 和 `cleanup_module()` 可以改成用 macro `module_init()` 和 `module_exit()` 來做, macro 傳入值為進入/離開的 function name。 `__init`, `__exit` Passing command line arguments to a module with macros: - module_param() - module_param_array() - module_param_string() Library functions are used in user mode. System calls are provided by the kernel itself. 工具: ==strace== Unix uses only two rings - ring 0, supervisor mode - ring 1, user node When writing kernel code, every module will be linked against entire kernel, thus namespace pollution is a problem. We should - use `static` qualifier - use prefix for symbols The file */proc/kallsyms* holds all symbols that kernel knows. :::success (剛剛開了本地的,發現有 235827 行... ::: Since a module is code which can be dynamically inserted and removed in the kernel, it shares the kernel's codespace rather than having its own. --- Device drivers are one class of module, which provides functionality for hardware. They are located in */dev*. ```shell crw------- 1 root root 10, 126 3月 11 11:46 ecryptfs crw-rw---- 1 root video 29, 0 3月 11 11:46 fb0 lrwxrwxrwx 1 root root 13 3月 11 11:46 fd -> /proc/self/fd crw------- 1 root root 505, 0 3月 11 13:10 fibonacci ``` 逗號第一個數字是 major number ,第二個是 minor number 。 Each driver is assigned a unique major number. All device files with the same major number are controlled by the same driver. The minor number is used by the driver to distinguish between the various hardware it controls. The kernel doesn't care minor number. The drivers care. Devices have two types - character devices :列表中以 c 開頭的 - block devices :列表中以 b 開頭的 Block devices - 有自己的 buffer 可以決定先處理哪個 request - only accept input and return output in fixed block size ## Character Device Drivers > [linux/fs.h](https://github.com/torvalds/linux/blob/master/include/linux/fs.h) `file_operations` structure holds pointers to functions defined by the driver. The unused entries should be set to `NULL`. Since Linux v5.6, the `proc_ops` structure was introduced to replace the use of `file_operations` when registering proc handlers. - A ==file== is a kernel level structure and never appears in a user space program. - A ==FILE== is defined by glibc and would never appear in a kernel space function. `inode`, `filp` ### Register and Unregister Adding a driver means registering in with kernel ```c static inline int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops) ``` If pass `major` of 0 to `register_chrdev()`, the number will be dynamically allocated. `register_chrdev` would occupy a range of minor numbers associated to the major. recommend to use `cdev` interface --- We can not allow the kernel module to be `rmmod`'ed whenever root feels like it. We should check the refcnt. The check will be performed by `sys_deleta_module()` defined in [linux/syscall.h](https://github.com/torvalds/linux/blob/master/include/linux/syscalls.h). The counter should not be used directly. We should use the interface in [linux/module.h](https://github.com/torvalds/linux/blob/master/include/linux/module.h) : - `try_module_get()` - `module_put()` - `module_refcount()` ### chardev.c sample :::info page pointer : 35 :::