module_exit
是 Linux 内核中的一个宏,用于在内核模块卸载时执行清理函数。这个宏允许你注册一个函数,该函数会在模块被从内核中移除时自动执行,通常用于释放由模块在加载时分配的资源。
module_exit
宏的定义如下:
c复制代码
#define module_exit(x) __exitcall(x); |
和 module_init
类似,__exitcall
是另一个宏,它负责将清理函数添加到内核的退出函数列表中。这个列表中的函数会在模块卸载时执行。
__exitcall
宏的定义可能因内核版本而异,但通常它看起来像这样:
c复制代码
#define __exitcall(fn) \ | |
static exitcall_t __exitcall_##fn __exit_used \ | |
__attribute__((__section__(".exitcall.exit"))) = fn; |
这里,exitcall_t
是一个函数指针类型,它指向一个返回 void
且不接受任何参数的函数。__exit_used
是另一个 GCC 属性,类似于 __used
,但它用于退出函数。__section__
属性指定函数应该放置在名为 .exitcall.exit
的特殊段中。
在模块代码中,你可以使用 module_exit
宏来指定模块的出口函数,例如:
c复制代码
static void hello_exit(void) { | |
printk("Goodbye, world!\n"); | |
// 释放资源,如内存、设备、中断等 | |
} | |
module_exit(hello_exit); |
在这个例子中,hello_exit
函数会在模块卸载时被执行,它会打印一条消息到内核日志中,并执行任何必要的清理工作。
当模块被卸载时,内核会遍历 .exitcall.exit
段中的所有函数,并按照它们被注册的顺序执行它们。这确保了模块在卸载前能够正确地释放其占用的所有资源。