<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > linux配置、編譯內(nèi)核實用工具

          linux配置、編譯內(nèi)核實用工具

          ——
          作者: 時間:2007-04-18 來源: 收藏

          Make 

          Make是一種幫助大型軟件工程的編譯工作實現(xiàn)自動化的編程語言。正確地使用Make可以大大減少因編譯程序而花費的時間,因為它可以消除不必要的再編譯。Make的基本設(shè)計思想是如果目標文件是在最近一次對源文件的修改之后編譯的,它就是“新的”,不需要重新編譯;如果最近一次對源文件的修改之后沒有及時更新目標文件,那么該目標文件就是“舊的”,需要重新編譯。為了理解Make如何執(zhí)行一個任務(wù),需要了解一些術(shù)語: 

          ◆目標 需要執(zhí)行的一個任務(wù)。多數(shù)情況下它就是用戶要生成的文件的名字,但是它也可以僅是個任務(wù)的名字。 

          ◆依賴關(guān)系 兩個目標之間相互依存的關(guān)系。如果修改目標B會造成目標A的修改,那么就說目標A依賴于目標B,B是A的先決條件。 

          ◆變量 一種存儲臨時信息的載體。Make中使用的變量應(yīng)該加上括號,例如$(TEMP)。 

          ◆命令 執(zhí)行任務(wù)時使用的指令,可以是一條、多條,甚至沒有。 

          ◆規(guī)則 一條完整的規(guī)則具有以下格式: 

          目標(target) : 先決條件(prerequisites) 

          規(guī)則(command) 

          ...... 

          其中只有目標必須要有,其它成分可以沒有。一條完整的規(guī)則描述了編譯一個目標的方法和依賴關(guān)系,是Makefile中最重要的部分。 

          ◆Makefile文件 描述如何生成一個或多個目標的文件。它列出目標依賴的各個文件,并提供正確編譯這些目標所需要的規(guī)則。 

          接下來以2.4.23的kbuild為例,簡要介紹一下內(nèi)核的構(gòu)建過程。首先,完整的內(nèi)核構(gòu)建過程由以下五種Makefile封裝。 

          1.根目錄Makefile 

          它是最重要的Makefile,定義所有與體系結(jié)構(gòu)無關(guān)的變量和目標。它讀取.config文件,并根據(jù)其信息最終生成vmlinux和modules。Make通過向下遞歸調(diào)用子目錄中的Makefile來編譯這兩個目標。 

          2.配置文件.config 

          執(zhí)行“make ”會在根目錄下生成該配置文件,其內(nèi)容記錄了具體的配置選擇,也可以將舊內(nèi)核的配置文件放在這里。 

          3.a(chǎn)rch/*/Makefile 

          這是與特定體系結(jié)構(gòu)相關(guān)的Makefile。它包含在根目錄下的Makefile中,為kbuild提供體系結(jié)構(gòu)的特定信息。 

          4.子目錄Makefiles 

          它們存在于每個子目錄下,大約有幾百個。它們接受來自上層Make傳遞下來的信息,并根據(jù)這些信息來構(gòu)造一個需要編譯的文件列表,并交由Rules.make處理。 

          5.Rules.make 

          幾乎每個子目錄Makefile都包含該Makefile。根據(jù)子目錄Makefiles構(gòu)建的文件列表,Make使用Rules.make定義的通用規(guī)則來編譯所有來自列表的源文件。 

          kbuild的執(zhí)行過程是:Make從根目錄Makefile開始執(zhí)行,從中獲得與體系結(jié)構(gòu)無關(guān)的變量和依賴關(guān)系,并同時從arch/*/Makefile中獲得體系特定的變量等信息,這些信息擴展了根目錄Makefile提供的變量。此時kbuild已經(jīng)擁有構(gòu)建內(nèi)核需要的所有變量和目標。然后,Make進入子目錄,把部分變量傳遞給子目錄Makefile。子目錄Makefile根據(jù)配置信息決定編譯哪些源文件,從而構(gòu)建出一個需要編譯的文件列表。最后,Rules.make根據(jù)其定義的編譯規(guī)則決定這些文件的編譯方式。 

          需要注意的是,由于Make的向下遞歸特性和無序性,其執(zhí)行過程并不完全遵守順序逐行執(zhí)行的規(guī)則,但無論Make的執(zhí)行有多復(fù)雜,也只分為兩個階段。第一個階段Make會讀取所有變量和分析所有目標的依賴關(guān)系,并最終建立一棵依賴關(guān)系樹。同時,所有的立即型變量(通過“:=”賦值)在這個過程中被擴展,就像C變量一樣。而在這個階段的最后,所有的延遲型變量才被擴展(通過“=”賦值)。這點需要格外注意。第二個階段Make會根據(jù)依賴關(guān)系樹執(zhí)行命令。 

          因此,一個目標和其先決條件的規(guī)則定義的順序是無所謂的,很可能一個目標的先決條件的規(guī)則定義在百行以后才出現(xiàn)。Make會耐心讀完所有的Makefile后分析得出依賴關(guān)系樹。 

          GCC 

          GCC是GNU的免費編譯程序,也是內(nèi)核惟一指定使用的。GCC在執(zhí)行一個完整的編譯任務(wù)時會經(jīng)過以下步驟: 

          ◆預(yù)處理 GCC會調(diào)用cpp程序來分析各種宏指令,如#define、#if、#include等。 

          ◆編譯 這一階段根據(jù)輸入文件產(chǎn)生匯編語言指令。由于通常情況下是立即調(diào)用匯編程序as,所以輸出一般不保存在文件中,可以使用-S選項強制輸出源程序的匯編版本。 

          ◆匯編 這一階段將匯編語言源程序作為輸入,生成.o目標文件。 

          ◆鏈接 這是最后一個階段。該階段中,各個.o模塊被鏈接在一起構(gòu)成可執(zhí)行文件。 

          as 

          用戶可以明確地要求使用as來直接處理匯編文件。as產(chǎn)生的目標文件可以分為文本段(.text)、數(shù)據(jù)段(.data)和未初始化數(shù)據(jù)段(.bss)。 

          ld 

          與as相似,用戶可以明確地要求使用ld鏈接程序?qū)讉€模塊組合成一個單獨的可執(zhí)行文件。其鏈接過程通常由一個叫l(wèi)d鏈接腳本的文件來描述。該腳本使用Linker Command Language編寫。使用“l(fā)d --verose”命令可以看到這個默認使用的ld鏈接腳本。 

          ar 

          ar是GNU的二進制文件處理程序,用于創(chuàng)建、修改及從歸檔文件中抽取文件。由它生成的.a歸檔文件實際上是一個包含許多可執(zhí)行二進制代碼子程序集合的庫文件。 

          RPMBuild 

          使用“make rpm”可以把內(nèi)核源代碼制作成RPM包。在此之前,kbuild會執(zhí)行“make spec”生成rpmbuild程序用到的spec文件,詳見“man rpmbuild”。 

          中間件 

          根目錄scripts下的各種腳本和C源文件都可以稱作中間件。它們并不是內(nèi)核組件的一部分,只是在kbuild執(zhí)行過程中的輔助程序。以split-include為例,講述配置文件的運作機理。 

          .config由關(guān)鍵字/值對組成,其內(nèi)容類似于: 




          CONFIG_MPENTIUMIII=y 
          # CONFIG_MPENTIUM4 is not set 
          CONFIG_REISERFS_FS=m 
            




          這些信息在執(zhí)行“make ”時自動生成。同時include/linux/autoconf.h依照.config的內(nèi)容生成。它的格式類似于: 




          #define CONFIG_MPENTIUMIII 1 
          #undef CONFIG_MPENTIUM4 
          #undefCONFIG_REISERFS_FS 
          #define CONFIG_REISERFS_FS_MODULE 1 
            




          對比一下不難發(fā)現(xiàn),include/linux/autoconf.h明確地洞悉了.config的意圖:哪些組件不編譯,哪些需要編譯進內(nèi)核,而哪些又要作為模塊來編譯?split-include根據(jù)include/linux/autoconf.h在include/config/下建立相關(guān)的目錄和.h文件。每個.h文件只包括include/linux/autoconf.h中的某一行,比如在配置內(nèi)核選項時支持NTFS文件系統(tǒng),并把它編譯進內(nèi)核,在.config中就會生成“CONFIG_NTFS_FS=y”,相應(yīng)地在include/linux/autoconf.h中會生成“#define CONFIG_NTFS_FS 1”一項。這樣,所有與NTFS文件系統(tǒng)相關(guān)的C源文件都會包含include/config/ntfs/fs.h頭文件。 

          如果以前編譯過內(nèi)核,并且沒有使用過“make mrproper”,.config、include/linux/autoconf.h和include/linux/config/就不會被刪除。這里涉及到新舊內(nèi)核的配置問題。一個全新的內(nèi)核代碼是未經(jīng)配置的。如果只在原內(nèi)核的功能基礎(chǔ)上增加對NTFS的支持,那么從頭開始配置無疑是浪費時間。可以繼續(xù)使用原內(nèi)核的.config文件,而所有的配置信息不會有任何更改,并且可以直接在原配置的基礎(chǔ)上增加新功能。 

          在復(fù)雜的情況下,保留的舊內(nèi)核配置信息還要與新的配置信息進行比較:哪些舊信息需要覆蓋,哪些需要保留?下面來看一下幾種可能的情況: 

            

          舊值保存在include/config/下的.h文件中,新值保存在新生成的include/linux/autoconf.h文件中。split-include的代碼不僅描述了如何處理這五種情況,還描述了include/config/下文件和子目錄的生成過程。 



          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();