我正在阅读有关Linux内核开发的内容,我只是阅读了一些我不理解的文本。这是段落,它讨论了模块的__init和__exit宏:
这演示了内核2.2及更高版本的功能。注意这个变化 在init和cleanup函数的定义中。 __init宏 导致init函数被丢弃,并且一旦释放了它的内存 init函数完成内置驱动程序,但不能加载模块。 如果你考虑调用init函数的时候,就可以了 完美的感觉。
还有一个__initdata 它与__init类似,但对于init变量而不是 功能
__exit宏导致省略函数 该模块内置于内核中,就像 __exit对可加载模块没有影响。同样,如果您考虑清理功能何时运行
我明白了;一旦init函数完成内置驱动程序,宏__init
会导致init函数被丢弃并释放内存。但为什么?不适用于可加载模块?我无法理解它。
我知道这是一件很愚蠢的事情,但我想了一段时间并且完全无法理解它。为什么内置驱动程序而不是可加载模块?两者都需要__init
中分配的变量,地址等,对吗?
答案 0 :(得分:3)
你是对的;即使在模块中,也可能存在初始化后您真正不需要的功能,因此它们原则上可以从内存中删除。 __init
对模块没有影响的原因更多的是实现它的容易程度。
This answer to a question about the nature of __init
阐明了这个问题。本质上,内核构建系统在内核的所有部分中查找用__init
标记的所有函数,并对它们进行排列,使它们全部位于同一块内存中。
然后,当内核启动时,它可以同时释放一块内存。
这种预先排序的想法在模块方面效果不佳。加载模块时必须加载init代码,因此它不能与其他init代码共享空间。相反,内核必须从每个模块中挑出几百个字节并单独释放它们。
但是,硬件页面大小通常为4KB,因此很难以小于此的块来释放内存。因此,尝试释放每个单独模块中的__init
函数可能比它的价值更麻烦。