内置和可加载模块的__init和__exit宏用法

时间:2012-07-26 09:27:16

标签: init exit

我正在阅读有关Linux内核开发的内容,我只是阅读了一些我不理解的文本。这是段落,它讨论了模块的__init和__exit宏:

  

这演示了内核2.2及更高版本的功能。注意这个变化   在init和cleanup函数的定义中。 __init宏   导致init函数被丢弃,并且一旦释放了它的内存   init函数完成内置驱动程序,但不能加载模块。   如果你考虑调用init函数的时候,就可以了   完美的感觉。

     

还有一个__initdata   它与__init类似,但对于init变量而不是   功能

     

__exit宏导致省略函数   该模块内置于内核中,就像   __exit对可加载模块没有影响。同样,如果您考虑清理功能何时运行

我明白了;一旦init函数完成内置驱动程序,宏__init会导致init函数被丢弃并释放内存。但为什么?不适用于可加载模块?我无法理解它。

我知道这是一件很愚蠢的事情,但我想了一段时间并且完全无法理解它。为什么内置驱动程序而不是可加载模块?两者都需要__init中分配的变量,地址等,对吗?

1 个答案:

答案 0 :(得分:3)

你是对的;即使在模块中,也可能存在初始化后您真正不需要的功能,因此它们原则上可以从内存中删除。 __init对模块没有影响的原因更多的是实现它的容易程度。

This answer to a question about the nature of __init阐明了这个问题。本质上,内核构建系统在内核的所有部分中查找用__init标记的所有函数,并对它们进行排列,使它们全部位于同一块内存中。

然后,当内核启动时,它可以同时释放一块内存。

这种预先排序的想法在模块方面效果不佳。加载模块时必须加载init代码,因此它不能与其他init代码共享空间。相反,内核必须从每个模块中挑出几百个字节并单独释放它们。

但是,硬件页面大小通常为4KB,因此很难以小于此的块来释放内存。因此,尝试释放每个单独模块中的__init函数可能比它的价值更麻烦。