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.
pr_info()
, pr_debug()
init_module()
和 cleanup_module()
可以改成用 macro module_init()
和 module_exit()
來做, macro 傳入值為進入/離開的 function name。
__init
, __exit
Passing command line arguments to a module with macros:
Library functions are used in user mode.
System calls are provided by the kernel itself.
工具: strace
Unix uses only two rings
When writing kernel code, every module will be linked against entire kernel, thus namespace pollution is a problem. We should
static
qualifierThe file /proc/kallsyms holds all symbols that kernel knows.
(剛剛開了本地的,發現有 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.
逗號第一個數字是 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
Block devices
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.
inode
, filp
Adding a driver means registering in with kernel
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.
The counter should not be used directly. We should use the interface in linux/module.h :
try_module_get()
module_put()
module_refcount()
page pointer : 35