.init.setup 位置

在內核裏經常可以看到__init,__devinit這樣的語句,這都是在init.h中定義的宏,gcc在編譯時會將被修飾的內容放到這些宏所代表的section。

其典型的定義如下:

  1. #define __init        __section(.init.text) __cold notrace
  1. #define __initdata    __section(.init.data)
  2. #define __initconst    __section(.init.rodata)
  3. #define __exitdata    __section(.exit.data)
  4. #define __exit_call    __used __section(.exitcall.exit)

其典型用法如下:

  1. static int __init xxx_drv_init(void)
  1. {
  1.      return pci_register_driver(&xxx_driver);
  1. }

根據上面的定義與用法,xxx_drv_init()函數將會被link到.init.text段。

之所以加入這樣的宏,原因有2:

1,一部分內核初始化機制依賴與它。如kernel將初始化要執行的init函數,分爲7個級別,core_initcall,postcore_initcall, arch_initcall, subsys_initcall, fs_iitcall, device_initcall,late_initcall。這7個級別優先級遞減,即先執行core_initcall, 最後執行late_initcall。通過使用文中提到的宏,gcc會將初始化代碼按下面的結構安排:

__init_begin -------------------------------

                            | .init.text        |----------__init

                            |------------------|

                            |  .init.data     |----------__initdata

__setup_start  |------------------------|

                          |.initcall1.init |------core_initcall

                          |------------------|

                          |.initcall2.init |------postcore_initcall

                          |------------------|

                          |.initcall3.init |------arch_initcall

                          |------------------|

                          |.initcall4.init |------subsys_initcall

                          |------------------|

                          |.initcall5.init |------fs_initcall

                          |------------------|

                          |.initcall6.init |------device_initcall

                          |------------------|

                          |.initcall7.init |------late_initcall

__initcall_end      |------------------|

                          |                           |

                          |            .....          |

                          |                           |

__init_end     ---------------------------------


在內核初始化時,從__initcall_start到__initcall_end之間的initcall被一次執行。

2,提高系統效率

初始化代碼的特點是,在系統啓動時運行,且一旦運行後馬上推出內存,不再佔用內存。

================================================================================

常用的宏:

  • __init,標記內核啓動時所用的初始化代碼,內核啓動完成後就不再使用。其所修飾的內容被放到.init.text section中。
  • __exit,標記模塊退出代碼,對非模塊無效
  • __initdata,標記內核啓動時所用的初始化數據結構,內核啓動完成後不再使用。其所修飾的內容被放到.init.data section中。
  • __devinit,標記設備初始化所用的代碼
  • __devinitdata,標記設備初始化所用的數據結構
  • __devexit,標記設備移除時所用的代碼
  • xxx_initcall,7個級別的初始化函數

==================================================================================

driver中的使用:

  • module_init, module_exit函數所調用的函數,需要分別用__init和__exit來標記
  • pci_driver數據結構不需要標記
  • probe和remove函數用__devinit和__devexit來標記
  • 如果remove使用__devexit標記,則在pci_drvier結構中要用__devexit_p(remove)來引用remove函數
  • 如果不確定需不需要添加宏,則不要添加

 

源文檔 <http://blog.chinaunix.net/uid-25871104-id-2854544.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章