__init and __exit

來源:互聯網
上載者:User
The __init and __exit declarations are special kernel macros designed to tell the kernel to flag these
functions for special handling in cases where they are compiled in statically rather than included as
parts of modules.
 The __init declaration allows the kernel to reclaim the space used by initialization
functions, while the __exit declaration tells the kernel to just plain ignore the function altogether. If
you’re only going to write your device driver as a module, with no possibility that it will be included
statically, it is perfectly safe to leave these special declarations out.

1 __init:

/* These macros are used to mark some functions or
 * initialized data (doesn't apply to uninitialized data)
 * as `initialization' functions. The kernel can take this
 * as hint that the function is used only during the initialization
 * phase and free up used memory resources after
 *
 * Usage:
 * For functions:
 *

 * You should add __init immediately before the function name, like:
 *
 * static void __init initme(int x, int y)
 * {
 *    extern int z; z = x * y;
 * }
 *
 * If the function has a prototype somewhere, you can also add
 * __init between closing brace of the prototype and semicolon:
 *
 * extern int initialize_foobar_device(int, int, int) __init;
 *
 * For initialized data:
 * You should insert __initdata between the variable name and equal
 * sign followed by value, e.g.:
 *
 * static int init_variable __initdata = 0;
 * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
 *
 * Don't forget to initialize data not at file scope, i.e. within a function,
 * as gcc otherwise puts the data into the bss section and not into the init
 * section.
 *
 * Also note, that this data cannot be "const".

其主要作用是初始化.

2)module_init:
/**
 * module_init() - driver initialization entry point
 * @x: function to be run at kernel boot time or module insertion
 *
 * module_init() will add the driver initialization routine in
 * the "__initcall.int" code segment if the driver is checked as
 * "y" or static, or else it will wrap the driver initialization
 * routine with init_module() which is used by insmod and
 * modprobe when the driver is used as a module.
 */
/**
 * module_exit() - driver exit entry point
 * @x: function to be run when driver is removed
 *
 * module_exit() will wrap the driver clean-up code
 * with cleanup_module() when used with rmmod when
 * the driver is a module.  If the driver is statically
 * compiled into the kernel, module_exit() has no effect.
 */

注意一下init和cleanup這兩個函數定義的變化。__init宏使內建模組中的init函數在執行完成後釋放掉,不過可裝載的模組不受影響。如果你關心init函數什麼時候調用,這一點是很有用的。

還有個__initdata,和__init的作用基本上一樣,不過它是針對變數而不是函數的。

__exit宏會使那些內建到核心的模組省略掉cleanup函數,不過和__init一樣,對loadable模組沒影響。再說一遍,如果你關心cleanup啟動並執行時機,這是重要的。Built-in的驅動不需要cleanup,反正它們也不能退出,不過loadable式的模組顯然是需要一個的。

這些宏都定義在linux/init.h中,它們會釋放核心的記憶體。你啟動核心的時候會看到一些諸如Freeing unused kernel memory:236k freed,之類的資訊,這多半就是它們乾的。

_init修飾,以及.init開頭的節,在模組插入完畢運行之後,這一部分
的記憶體空間會被釋放,因此dump的時候這些資訊是無法得到的。


核心模組至少要有兩個函數:一個叫做init_module()的“start”初始化函數供insmod的時候調用,一個叫clean_module()的“end”清除函數供rmmod的時候調用。實際上,2.3.13之後的核心這兩個函數不再必須使用這兩個名字了。你給它們起什麼名字都可以,2.3節我會將具體怎麼做。給這兩個函數自己起名字其實是個挺好的主意,不過還是有很多人使用init_module和clean_module函數。L

很經典的,init_module函數會向核心註冊一些什麼東西,或者用自己的代碼替換核心的一些什麼功能(通常它們做點什麼動作之後還是會調用原來的函數)。而clean_module函數則會把init_module乾的事情做個了結,以便安全的卸載模組。

最後,每個核心模組都要包含linux/module.h。僅僅為了KERL_ALERT(2.1.1節會講到它)還需要在這個例子中包括linux/kernel.h。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.