0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux Kernel源代碼中與段有關(guān)的重要宏定義

Q4MP_gh_c472c21 ? 2018-02-05 10:07 ? 次閱讀

__init, __initdata等屬性標(biāo)志,是要把這種屬性的代碼放入目標(biāo)文件的.init.text節(jié),數(shù)據(jù)放入.init.data節(jié)──這一過程是通過編譯內(nèi)核時(shí)為相關(guān)目標(biāo)平臺(tái)提供了xxx.lds鏈接腳本來指導(dǎo)ld完成的。

對編譯成module的代碼和數(shù)據(jù)來說,當(dāng)模塊加載時(shí),__init屬性的函數(shù)就被執(zhí)行;

對靜態(tài)編入內(nèi)核的代碼和數(shù)據(jù)來說,當(dāng)內(nèi)核引導(dǎo)時(shí),do_basic_setup()函數(shù)調(diào)用do_initcalls()函數(shù),后者負(fù)責(zé)所有.init節(jié)函數(shù)的執(zhí)行。

在初始化完成后,用這些關(guān)鍵字標(biāo)識(shí)的函數(shù)或數(shù)據(jù)所占的內(nèi)存會(huì)被釋放掉。

1)所有標(biāo)識(shí)為__init的函數(shù)在鏈接的時(shí)候都放在.init.text這個(gè)區(qū)段內(nèi),,"__init"僅告訴kernel,此函數(shù)僅在初始化階段使用,使用后所占用的內(nèi)存資源會(huì)釋放

在這個(gè)區(qū)段中,函數(shù)的擺放順序是和鏈接的順序有關(guān)的,是不確定的。2)所有的__init函數(shù)在區(qū)段.initcall.init中還保存了一份函數(shù)指針,在初始化時(shí)內(nèi)核會(huì)通過這些函數(shù)指針調(diào)用這些__init函數(shù)指針,并在整個(gè)初始化完成后,釋放整個(gè)init區(qū)段(包括.init.text,.initcall.init等),注意,這些函數(shù)在內(nèi)核初始化過程中的調(diào)用順序只和這里的函數(shù)指針的順序有關(guān),和1)中所述的這些函數(shù)本身在.init.text區(qū)段中的順序無關(guān)。在2.4內(nèi)核中,這些函數(shù)指針的順序也是和鏈接的順序有關(guān)的,是不確定的。在2.6內(nèi)核中,initcall.init區(qū)段又分成7個(gè)子區(qū)段,分別是

.initcall1.init.initcall2.init.initcall3.init.initcall4.init.initcall5.init.initcall6.init.initcall7.init

(參見include/linux/init.h和vmlinux.lds )當(dāng)需要把函數(shù)fn放到.initcall1.init區(qū)段時(shí),只要聲明core_initcall(fn);即可。其他的各個(gè)區(qū)段的定義方法分別是:

core_initcall(fn) --->.initcall1.initpostcore_initcall(fn) --->.initcall2.initarch_initcall(fn) --->.initcall3.initsubsys_initcall(fn) --->.initcall4.initfs_initcall(fn) --->.initcall5.initdevice_initcall(fn) --->.initcall6.initlate_initcall(fn) --->.initcall7.init

而與2.4兼容的initcall(fn)則等價(jià)于device_initcall(fn)。各個(gè)子區(qū)段之間的順序是確定的,即先調(diào)用.initcall1.init中的函數(shù)指針再調(diào)用.initcall2.init中的函數(shù)指針,等等。而在每個(gè)子區(qū)段中的函數(shù)指針的順序是和鏈接順序相關(guān)的,是不確定的。在內(nèi)核中,不同的init函數(shù)被放在不同的子區(qū)段中,因此也就決定了它們的調(diào)用順序。這樣也就解決了一些init函數(shù)之間必須保證一定的調(diào)用順序的問題。

2. Linux Kernel源代碼中與段有關(guān)的重要宏定義

A. 關(guān)于__init、__initdata、__exit、__exitdata及類似的宏

打開Linux Kernel源代碼樹中的文件:include/init.h,可以看到有下面的宏定議:

#define __init __attribute__ ((__section__ (".init.text"))) __cold

#define __initdata __attribute__ (( __section__ (".init.data")))

#define __exitdata __attribute__ (( __section__ (".exit.data")))

#define __exit_call __attribute_used__ __attribute__ (( __section__ (".exitcall.exit")))

#define __init_refok oninline __attribute__ ((__section__ (".text.init.refok")))

#define __initdata_refok __attribute__ ((__section__ (".data.init.refok")))

#define __exit_refok noinline __attribute__ ((__section__ (".exit.text.refok")))

.........

#ifdef MODULE

#define __exit __attribute__ (( __section__ (".exit.text"))) __cold

#else

#define __exit __attribute_used__ __attribute__ ((__section__ (".exit.text"))) __cold

#endif

對于經(jīng)常寫驅(qū)動(dòng)模塊或翻閱Kernel源代碼的人,看到熟悉的宏了吧:__init, __initdata, __exit, __exitdata。

__init 宏最常用的地方是驅(qū)動(dòng)模塊初始化函數(shù)的定義處,其目的是將驅(qū)動(dòng)模塊的初始化函數(shù)放入名叫.init.text的輸入段。當(dāng)內(nèi)核啟動(dòng)完畢后,這個(gè)段中的內(nèi)存會(huì)被釋放掉供其他使用。

__initdata宏用于數(shù)據(jù)定義,目的是將數(shù)據(jù)放入名叫.init.data的輸入段。其它幾個(gè)宏也類似。

另外需要注意的是,在以上定意中,用__section__代替了section。還有其它一些類似的宏定義,這里不一一列出,其作用都是類似的。

模塊加載分為動(dòng)態(tài)加載和靜態(tài)加載。

所謂靜態(tài)加載就是,開機(jī)加載系統(tǒng)時(shí)將模塊加載上去,這就是編譯進(jìn)內(nèi)核。

而動(dòng)態(tài)加載就是在開機(jī)以后將模塊加載上去,這就是編譯成模塊!

init_module是默認(rèn)的模塊的入口,如果你想指定其他的函數(shù)作為模塊的入口就需要module_init函數(shù)來指定,比如

module_init (your_func);

其中your_func是你編寫的一個(gè)函數(shù)的名稱.

init_module()是真正的入口,module_init是宏,如果在模塊中使用,最終還是要轉(zhuǎn)換到init_module()上。

如果不是在模塊中使用,module_init可以說沒有什么作用??傊褂胢odule_init方便代碼在模塊和非模塊間移植。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11213

    瀏覽量

    208736

原文標(biāo)題:嵌入式Linux內(nèi)核中_init,_exit中的作用

文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux內(nèi)核源代碼漫游

    Linux內(nèi)核源代碼漫游 本章試圖以順序的方式來解釋Linux源代碼,以幫助讀者對源代碼的體系結(jié)構(gòu)以及很多相關(guān)的unix特性的實(shí)現(xiàn)有一個(gè)很
    發(fā)表于 02-09 15:27 ?26次下載

    Linux源代碼簡介

     Linux源代碼簡介歡迎進(jìn)入Linux的世界!隨著人們對開放源代碼軟件熱情的不斷高漲,Linux也受到了越來越多的關(guān)注。
    發(fā)表于 02-10 13:54 ?78次下載

    kernel 匯編實(shí)時(shí)運(yùn)行核心的匯編源代碼

    kernel 匯編實(shí)時(shí)運(yùn)行核心的匯編源代碼.rar /*Listing 1      Scheduling Algorithm(C
    發(fā)表于 02-25 15:48 ?6次下載

    Linux內(nèi)核源代碼漫游

    本章試圖以順序的方式來解釋Linux源代碼,以幫助讀者對源代碼的體系結(jié)構(gòu)以及很多相關(guān)的unix特性的實(shí)現(xiàn)有一個(gè)很好的理解。目標(biāo)是幫助對Linux不甚了解的有經(jīng)驗(yàn)的C程序員對整個(gè)
    發(fā)表于 04-03 20:26 ?57次下載

    Linux0.11源代碼0.11

    Linux0.11源代碼配合《Linux 0.11 源代碼完全分析0.11》一起學(xué)習(xí),很好的資料
    發(fā)表于 10-30 17:14 ?24次下載

    怎樣去讀Linux內(nèi)核源代碼

    怎樣去讀Linux內(nèi)核源代碼
    發(fā)表于 10-25 10:15 ?13次下載
    怎樣去讀<b class='flag-5'>Linux</b>內(nèi)核<b class='flag-5'>源代碼</b>

    linux kernel工作隊(duì)列及源碼解析

    1. 前言 工作隊(duì)列(workqueue)的Linux內(nèi)核定義的用來處理不是很緊急事件的回調(diào)方式處理方法。 以下代碼linux內(nèi)核版本
    發(fā)表于 10-27 10:19 ?0次下載

    linux kernel工作隊(duì)列及源碼詳細(xì)講解

    1. 前言 工作隊(duì)列(workqueue)的Linux內(nèi)核定義的用來處理不是很緊急事件的回調(diào)方式處理方法. 以下代碼linux內(nèi)核版本
    發(fā)表于 11-30 17:43 ?581次閱讀

    Linux操作的防火墻軟件應(yīng)用程序定義和配置設(shè)置及底層源代碼

    雖然一般PC用戶有許多免費(fèi)的防火墻軟件應(yīng)用程序,但Linux操作系統(tǒng)的最大優(yōu)勢之一是它們能夠自定義和配置設(shè)置和底層源代碼。
    的頭像 發(fā)表于 07-17 10:19 ?5121次閱讀

    Linux應(yīng)用程序PING的源代碼免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是Linux應(yīng)用程序PING的源代碼免費(fèi)下載。
    發(fā)表于 10-18 17:46 ?13次下載

    ARM Linux中一些重要及地址定義

    ARM Linux中一些重要及地址定義
    的頭像 發(fā)表于 06-22 17:02 ?2693次閱讀

    基于Android的Linux內(nèi)核的電源管理:概述

    1.電源管理的狀態(tài)Android的Linux內(nèi)核為系統(tǒng)提供了4種電源狀態(tài),內(nèi)核的源代碼為其中的3種定義了名字和對應(yīng)的定義,名字
    發(fā)表于 01-07 11:14 ?6次下載
    基于Android的<b class='flag-5'>Linux</b>內(nèi)核的電源管理:概述

    如何選擇合適的工具來閱讀源代碼

    在做嵌入式 Linux 軟件開發(fā)的時(shí)候,經(jīng)常會(huì)閱讀大型工程源碼,比如 uboot 源代碼Linux Kernel 源碼等。
    的頭像 發(fā)表于 03-30 14:01 ?1142次閱讀

    linux內(nèi)核源代碼詳解

     在安裝好的Linux系統(tǒng),內(nèi)核的源代碼位于/ust/src/linux.如果是從GNU網(wǎng)站下載的Linux內(nèi)核的tar文件,則展開以后在
    發(fā)表于 09-06 17:01 ?4次下載

    SVdefine定義的用法

    SV中使用預(yù)處理指令`define來定義,可以用來創(chuàng)建文本替換。根據(jù)場景不同,`define主要用來定義常量、簡化復(fù)雜的表達(dá)式或代碼
    的頭像 發(fā)表于 10-21 14:22 ?211次閱讀