我想为Linux创建一个可加载的内核模块。这是密码
#include <linux/module.h>
#include <linux/init.h>
static int __init mymodule_init(void)
{
printk ("My module worked!\n");
return 0;
}
static void __exit mymodule_exit(void)
{
printk ("Unloading my module.\n");
return;
}
module_init(mymodule_init);
module_exit(mymodule_exit);
MODULE_LICENSE("GPL");现在请注意__init宏。正如医生所说:
__init宏向编译器指示该关联函数仅在初始化期间使用。编译器将所有标记为__init的代码放入初始化后释放的特殊内存部分。
我正试图理解初始化方法最终会导致内存泄漏的原因。是因为堆栈中函数调用的FIFO处理造成的吗?
发布于 2018-02-01 08:59:47
以非常宽泛的笔触:
可执行代码(编译成的源代码)占用内存。现代CPU会读取指令所在的内存部分,并执行它们。对于大多数用户空间应用程序,进程内存的代码段只加载一次,并且在程序执行过程中不会更改。代码总是存在的,除非程序员玩它。
这不是问题,因为操作系统将管理进程、虚拟内存,冷代码段最终将被卸载到交换文件中。在用户空间中,物理内存从来不会被“浪费”。
对于内核,代码在特权模式下运行,没有什么会像在用户模式下那样“卸载”未使用的页面。如果一个函数被放入内核的常规代码段中,那么只要内核运行,它就会占用物理内存,这可能是相当长的时间。如果一个函数只被调用一次,那就是浪费空间。
现在,虽然通常可以加载和卸载可加载的内核模块,因此它们的代码可能不会无限期占用空间,但占用只调用一次的函数的空间仍然有些浪费。
由于现代CPU将代码视为可执行数据的一种形式,因此有可能将该数据放入内存段,而该内存段不会无限期地保留。函数被加载,然后调用,然后这个段可以用于其他事情。这就是__init宏指示编译器做的事情。发出可在调用后轻松卸载的代码。
https://stackoverflow.com/questions/48558460
复制相似问题