2020-8-8 星期六 北京 悶熱天
總結linux內核基礎和設定編譯原理,分兩部分總結。僅作爲技術積累,方便日後查閱。參考了網上的一些筆記。
第一部分:內核基礎
2.14.1.內核和發行版的區別
2.14.2.內核和驅動的關聯
2.14.3.內核和應用程式、根檔案系統的關聯
2.14.4.linux內核的模組化設計
2.14.5.選擇合適版本的內核
第二部分:內核設定和編譯原理
2.15.1.linux內核原始碼目錄結構1
2.15.2.linux內核原始碼目錄結構2
2.15.3.內核設定和編譯體驗
2.15.4.內核的設定原理1
2.15.5.menuconfig的使用和演示
2.15.6.menuconfig的工作原理
2.15.7.Kconfig檔案詳解1
2.15.8.Kconfig檔案詳解2
2.15.9.menuconfig的實驗學習思路
第一部分:內核基礎
2.14.1.內核和發行版的區別
1、到底什麼是操作系統
(1)linux、windows、android、ucos就是操作系統
(2)操作系統本質上是一個程式,由很多個原始檔構成,需要編譯連線成操作系統程式(vmlinz、zImage)
(3)操作系統的主要作用就是管理計算機硬體,給應用程式提供一個執行環境。
2、操作系統核心功能:
(1)記憶體管理。如果沒有操作系統,記憶體是需要程式自己來管理的。譬如在uboot中要使用記憶體的哪裏是自己隨便用的,沒有註冊也沒有限制。這時候如果程式自己不小心把同一塊記憶體重複用了就會出現程式邏輯錯誤。系統大了之後(記憶體多了)記憶體管理非常麻煩;有了操作系統之後,操作系統負責管控所有的記憶體,所有的應用程式需要使用記憶體時都要向操作系統去申請和註冊,由操作系統的記憶體管理模組來分配記憶體給你使用,這樣好處是可以保證記憶體使用不會衝突。
(2)進程排程。操作系統下支援多個應用程式同時執行(所以可以一邊聊QQ一邊看電影···),這是宏觀上的並行。實際上在單核心CPU上微觀上是不能並行的,宏觀上的並行就是操作系統提供的分時複用機制 機製。操作系統的進程排程模組負責在各個進程之間進行切換。
(3)硬體裝置管理。沒有操作系統時要控制任何硬體都要自己寫程式碼,有了操作系統後操作系統本身會去控制各個硬體,應用程式就不用考慮硬體的具體細節了。操作系統的硬體裝置管理模組就是驅動模組。
(4)檔案系統。檔案系統是管理儲存裝置的一種方式。儲存裝置是由很多個磁區組成的,每個磁區有512/1024/2048/4096位元組,儲存裝置要以磁區爲單位進行讀寫。如果沒有檔案系統,程式要自己去讀寫磁區,就得記得哪個檔案在哪個磁區。有了檔案系統之後我們人不用再關注磁區,人只用關注檔案系統中的目錄和檔名,而不用管這個檔案在物理磁碟的哪個磁區。
3、操作系統擴充套件功能:
(1)協定棧
(2)有用的應用程式包。應用程式本身不屬於操作系統內核的一部分,應用程式是給人用的,面向某種功能的。譬如ping程式用來測試網路是否聯通,ifconfig程式用來設定網絡卡。
4、內核和發行版的區別
區別:內核是操作系統內核的簡稱,內核負責實現操作系統的核心功能(資源管理模組,譬如記憶體管理、排程系統······),內核不包括應用程式。所以說只有內核人是沒法用的,因爲人做任何事情都是通過相應的應用程式來完成的。所以賣操作系統的人把內核和一些常用的應用程式打包在一起提供給普通使用者,這就是操作系統的發行版(也就是普通意義上的操作系統)。
(1)內核只有一個。www.kernel.org
(2)發行版有很多。譬如ubuntu、redhat、suse、centos······
2.14.2.內核和驅動的關聯
1、學習linux的思路
(1)對龐大的整體要有個認識。學習路線就是先建立框架和整體,然後逐漸去學習各個細節部分,逐步細化。
(2)對各分層的作用要清楚。
(3)對層次間的關聯和互相呼叫要理解。
2、驅動屬於內核的一部分
(1)驅動就是內核中的硬體裝置管理模組
(2)驅動工作在內核態。
(3)驅動程式故障可能導致整個內核崩潰
(4)驅動程式漏洞會使內核不安全
2.14.3.內核和應用程式、根檔案系統的關聯
1、應用和內核的關係
(1)應用程式不屬於內核,而是在內核之上的
(2)應用程式工作在使用者態,是受限制的。
(3)應用程式故障不會導致內核崩潰
(4)應用程式通過內核定義的API介面來呼叫內核工作
(5)總結1:應用程式是最終目標
(6)總結2:內核就是爲應用程式提供底層資源管理的服務員
2、內核和根檔案系統
(1)根檔案系統提供根目錄。
(2)進程1存放在根檔案系統中(內核啓動時建立的進程1處於內核態,內核態的進程1做了:掛載根檔案系統並通過exec來從內核態的進程1 進入使用者態的進程1 )
(3)內核啓動最後會去裝載根檔案系統。
(4)總結:根檔案系統爲操作系統啓動提供了很多必備的資源:根目錄、使用者態進程1
2.14.4.linux內核的模組化設計
1、什麼是模組化設計
(1)因爲linux內核很龐大,程式碼量很大、東西很多,如果設計時完全設計成一體(各個檔案、各個函數之間緊耦合),複雜度超出了人所能理解的範圍。所以模組化設計也是一種必要。
(2)模組化設計就是內核中各個功能模組在程式碼上是彼此獨立的,譬如說排程系統和記憶體管理系統之間並沒有全域性變數的互相參照,甚至函數互相呼叫也很少,就算有也是遵循一個介面規範的。模組化設計的目的就是實現功能模組的松耦合。
2、模組化設計的體現
(1)設定時可裁剪。linux內核在編譯之前可以進行設定,設定時可以選擇將組成內核的成千上萬個模組每一個要或者不要。要了之後還有更多的一些細節的設定。
(2)模組化編譯和安裝。爲了操作方便,逐漸從靜態的升級變成了動態的升級(不需要重新啓動系統,更不需要重新燒錄系統)。這種動態的升級也是由模組化來支援的。
(3)原始碼中使用條件編譯。這種在uboot中已經見過了。
3、模組化設計的好處
(1)功能可裁剪、靈活性
(2)可延伸性(動態安裝解除安裝、新硬體支援)
(3)利於共同作業
4、模組化設計是一種普遍性的系統設計原則
2.14.5.選擇合適版本的內核
1、linux內核版本變遷簡史
(1)linux0.01。初版
(2)linux0.11。很多講linux內核原始碼解析的書都是以這個版本爲原本來講。《圖解linux內核設計的藝術》
(3)linux2.4。比較接近現代的版本,很多經典的書都是以2.4版本內核爲參照的,譬如《LDD3》。linux2.4的晚期內核在前幾年還會經常碰到有用的。
(4)linux2.6早期。2.6的早期和2.4晚期內核挺像的。
(5)linux2.6晚期。2.6的晚期內核較早期內核有一些改變,尤其是驅動相關的部分和一些標頭檔案的位置。2.6的晚期內核目前還算是比較主流。
(6)linux3.x 4.x
2、如何選擇合適的內核版本
(1)並不是越新版本的內核越好
(2)選擇SoC廠家移植版本會減少工作量
3、S5PV210適用的內核版本
(1)2.6.35.7+android2.3/QT4.8.3
(2)3.0.8+android4.0
4、我們使用2.6.35.7版本內核進行開發
第二部分:內核設定和編譯原理
2.15.1.linux內核原始碼目錄結構1
1、原始碼從哪裏來
(1)我們使用2.6.35.7版本的內核。這個版本的內核有三種:第一種是kernel.org上的官方版本,第二種是三星移植過的,第三種是九鼎X210的移植版本。我們使用第三種內核來講解,後面使用第二種內核來移植。
(2)原始碼在開發板光碟中有。可以自己去linux下解壓然後make distclean清理然後再次打包傳輸到windows下去解壓分析;也可以直接去我網路硬碟中下載我打包好的。
(3)解壓後最終在windows下得到了一個kernel的原始碼目錄樹,這個原始碼目錄就是九鼎以三星移植過的內核爲原材料自己針對X210移植後的內核版本。
2、分析原始碼目錄下的單個檔案
(1)Kbuild,Kbuild是kernel build的意思,就是內核編譯的意思。這個檔案就是linux內核特有的內核編譯體系需要用到的檔案。
(2)Makefile,這個是linux內核的總makefile,整個內核工程用這個Makefile來管理的。
(3)mk,是九鼎在移植時自己新增的,不是linux內核本身的東西。九鼎新增這個檔案的作用是用這個檔案來管理kernel目錄的設定和編譯
3、簡單講一下linux內核的設定體系。
(1)linux內核很龐大,裏面模組很多,而且可設定性非常高。所以linux原始碼的設定是一個很複雜的事情,必須要有一套很複雜的機制 機製來保證linux內核可以被正確的設定。(對比一下uboot,uboot的設定項都是在xxx.h中,用宏定義來表示的。uboot的這種方式很依賴於人的水平,因爲uboot的設定體系很簡單。)
(2)linux內核本身設定項有上千個,光靠人眼睛去看腦袋去記根本不可能,所以內核發明了一種體系用來幫助人進行簡單化的設定。這種體系就是我們本課程中重點要研究的東西。
(3)Kbuild、Kconfig等檔案,都是和內核的設定體系有關的。
2.15.2.linux內核原始碼目錄結構2
(1)arch。arch是architecture的縮寫,意思是架構。arch目錄下是好多個不同架構的CPU的子目錄,譬如arm這種cpu的所有檔案都在arch/arm目錄下,X86的CPU的所有檔案都在arch/x86目錄下。
(2)block。英文是塊的意思,在linux中block表示塊裝置(以塊(多個位元組組成的整體,類似於磁區)爲單位來整體存取),譬如說SD卡、iNand、Nand、硬碟等都是塊裝置。你幾乎可以認爲塊裝置就是儲存裝置。block目錄下放的是一些linux儲存體系中關於塊裝置管理的程式碼。
(3)crypto。英文意思是加密。這個目錄下放了一些各種常見的加密演算法的C語言程式碼實現。譬如crc32、md5、sha1等。
(4)Documentation。裏面放了一些文件。
(5)drivers。驅動目錄,裏面分門別類的列出了linux內核支援的所有硬體裝置的驅動原始碼。
(6)firmware。韌體。什麼是韌體?韌體其實是軟體,不過這個軟體是固話到IC裏面執行的叫韌體。就像S5PV210裡的iROM程式碼。
(7)fs。fs就是file system,檔案系統,裏面列出了linux支援的各種檔案系統的實現。
(8)include。標頭檔案目錄,公共的(各種CPU架構共用的)標頭檔案都在這裏。每種CPU架構特有的一些標頭檔案在arch/arm/include目錄及其子目錄下。
(9)init。init是初始化的意思,這個目錄下的程式碼就是linux內核啓動時初始化內核的程式碼。
(10)ipc。ipc就是inter process commuication,進程間通訊,裏面都是linux支援的IPC的程式碼實現。
(11)kernel。kernel就是內核,就是linux內核,所以這個資料夾下放的就是內核本身需要的一些程式碼檔案。
(12)lib。lib是庫的意思,這裏面都是一些公用的有用的庫函數,注意這裏的庫函數和C語言的庫函數不一樣的。在內核程式設計中是不能用C語言標準庫函數,這裏的lib目錄下的庫函數就是用來替代那些標準庫函數的。譬如在內核中要把字串轉成數位用atoi,但是內核程式設計中只能用lib目錄下的atoi函數,不能用標準C語言庫中的atoi。譬如在內核中要列印資訊時不能用printf,而要用printk,這個printk就是我們這個lib目錄下的。
(13)mm。mm是memory management,記憶體管理,linux的記憶體管理程式碼都在這裏。
(14)net。該目錄下是網路相關的程式碼,譬如TCP/IP協定棧等都在這裏。
(15)scripts。指令碼,這個目錄下全部是指令碼檔案,這些指令碼檔案不是linux內核工作時使用的,而是用來輔助對linux內核進行設定編譯生產的。我們並不會詳細進入分析這個目錄下的指令碼,而是通過外圍來重點學會設定和編譯linux內核即可。
(16)security。安全相關的程式碼。不用去管。
(17)sound。音訊處理相關的。
(18)tools。linux中用到的一些有用工具
(19)usr。目錄下是initramfs相關的,和linux內核的啓動有關,暫時不用去管。
(20)virt。內核虛擬機器相關的,暫時不用管。
總結:這麼多目錄跟我們關係很緊密的就是arch和drivers目錄,然後其他有點相關的還有include、block、mm、net、lib等目錄。
2.15.3.內核設定和編譯體驗
1、先確認Makefile
(1)主要是檢查交叉編譯工具鏈有沒有設定對。CROSS_COMPILE ?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
(2)確認ARCH = arm。主要目的是爲了編譯時能找到arch/arm目錄。
2、make x210ii_qt_defconfig
(1)最後只要出現:configuration written to .config這句話,就證明我們的操作是正確的。如果沒有出現這句話,就有錯誤。
(1)可能出現的錯誤1:名字敲錯了。名字是字串匹配的,一定要正確。
注意:如果這一步設定沒有得到.config檔案,是不能進行到下一步的。實際測試時沒有.config也可以make menuconfig,但是這樣做出來的內核編譯和燒寫執行應該是有問題的。
make menuconfig
(1)可能出現的錯誤1:ncurses庫沒裝
錯誤資訊:
*** Unable to find the ncurses libraries or the
*** required header files.
*** 'make menuconfig' requires the ncurses libraries.
***
*** Install ncurses (ncurses-devel) and try again.
解決方案: apt-get install libncurses5-dev (參考了:http://blog.csdn.net/yao_qinwei/article/details/8805101)
(2)可能出現的錯誤2:螢幕太小
錯誤資訊:
Your display is too small to run Menuconfig!
It must be at least 19 lines by 80 columns.
解決方案:全螢幕,或者是把字型調小。
總結:make menuconfig是第二步設定,具體的用法和設定意義在後面課程講。我們這裏因爲是九鼎已經移植過的,所以第二步設定是可以不做的,直接退出即可。
用鍵盤的向右方向鍵移動到EXIT,按回車退出。
3、make
(1)可能出現的錯誤1:莫名其妙的錯誤,可以試試先make distclean
(2)程式碼本身的錯誤:具體問題具體分析
(3)編譯完成後得到的內核映象不在原始碼樹的根目錄下,在arch/arm/boot這個目錄下。得到的映象名是zImage
2.15.4.內核的設定原理1
1、燒寫測試
2、設定的關鍵是得到.config檔案
(1).config以.開頭,是一個隱藏檔案,需要ls -a來看
(2)當我們make distclean後(也就是說預設情況下)是沒有.config檔案的,我們設定的兩步過程就是爲了得到內容合適的.config檔案
(3).config檔案是linux內核在編譯過程中很重要的一個檔案,其作用類似與uboot中的include/configs/x210_sd.h,內核在編譯過程中會讀取.config中的設定項,並且用這些設定項去指導整個編譯鏈接過程。
(4).config檔案的格式類似於指令碼檔案,其中內容爲類似於於:CONFIG_ARM=y的一個一個的設定項。這些設定項就類似於指令碼檔案中定義的一個一個變數,所以這一行可以被理解爲定義了一個變數CONFIG_ARM,這個變數的值爲y。
(5).config檔案中每一行都是一個設定項,從.config檔案的規模可以看出linux內核的可設定項有兩三千個。所以linux內核是高度可設定的,而且linux內核的所有設定項很難全部搞明白。因爲linux內核的設定項太多太繁雜超出了人的大腦能夠記憶和處理的數量級,因此linux內核不像uboot那樣直接手工設定,而是發明了一個圖形化的設定工具menuconfig。
3、make xx_defconfig和make menuconfig相配合
(1)我們爲了對.config檔案中的兩三千個設定項做逐一合適的設定,專門發明了兩步結合的設定方式。
(2)其實只要人的記憶足夠好,大腦足夠厲害,完全可以手工去書寫/修改.config檔案完成內核設定,最終只要.config中內容是正確的,就不影響編譯過程。
(3)第一步:make xxx_defconfig解決的問題是大部分的設定項(這一步結束後99%的設定項就已經正確了),下來就是對個別不同的針對我們的開發板進行細節調整,細節調整就通過make menuconfig來完成。
(4)make xxx_defconfig這一步其實是參考別人已經做好的,這樣做有很多好處:減少很多工作量,避開了很多自己不懂的設定項(譬如對記憶體管理的、排程系統的等模組的設定項),我們只用管自己需要管的。
(5)make menuconfig其實就是讀取第一步得到的.config,然後給我們一個圖形化的介面,讓我們可以更加容易的找到自己想要修改的設定項,然後更改設定他。
4、make xx_defconfig到底做了什麼?
(1)make x210ii_qt_defconfig其實相當於:cp arch/arm/configs/x210ii_qt_defconfig .config
(2)arch/arm/configs目錄下的這麼多個xxx_defconfig哪裏來的?其實這些檔案都是別人手工設定好適合一定的開發板的.config檔案後自己把.config檔案儲存過去的。譬如說我們用S5PV210這個SoC,針對這個SoC的開發板的最初設定肯定是三星的工程師去做的。
2.15.5.menuconfig的使用
1、使用說明解釋
(1)make ,menuconfig中本身自帶的提示就有所有的用法,這裏只要全部理解就可以了。
(2)menuconfig中間的選擇區中有很多個選擇項,每個選擇項對應.config檔案中的一個設定項,每一個選擇項都可以被選擇和設定操作,選擇區中的每一項都是有子目錄的,將遊標放在選擇項上按Enter鍵可以進入子目錄(子目錄可能還會有子目錄)。選擇區太短放不下所有的一個目錄層級的選項,可以用箭頭按鍵的向上箭頭和向下箭頭來上翻和下翻。
注:在menuconfig中操作相關的幾個鍵盤按鍵,主要是;Enter、ESC、四個方向箭頭按鍵。還有一些特殊字元按鍵,如/ ?
向上和向下箭頭,主要用來在選擇項選單中目錄瀏覽時上下翻
回車,主要作用是選中並且執行select/exit/help。
ESC,主要作用是返回上一層
向左和向右箭頭,主要作用是在選單選項(select、exit、help)間切換。
(3)用法翻譯:
箭頭按鍵導航整個選單,回車按鍵選擇子選單(注意選項後面有 --->的選項纔是有子選單的,沒有這個標識的沒有子選單),高亮的字母是熱鍵(快捷鍵),鍵盤按鍵Y、N、M三個按鍵的作用分別是將選中模組編入、去除、模組化。雙擊ESC表示退出,按下?按鍵可以顯示幫助資訊,按下/按鍵可以輸入搜尋內容來全域性搜尋資訊(類似於vi中的搜尋),[]不可以模組化,<>的纔可以模組化。
注:linux內核中一個功能模組有三種編譯方法:一種是編入、一種去去除、一種是模組化。所謂編入就是將這個模組的程式碼直接編譯連線到zImage中去,去除就是將這個模組不編譯鏈接到zImage中,模組化是將這個模組仍然編譯,但是不會將其鏈接到zImage中,會將這個模組單獨鏈接成一個內核模組.ko檔案,將來linux系統內核啓動起來後可以動態的載入或解除安裝這個模組。
在menuconfig中選項前面的括號裡,*表示編入,空白表示去除,M表示模組化
2.15.6.menuconfig的工作原理
1、menuconfig本身由一套軟體支援
(1)linux爲了實現圖形化介面的設定,專門提供了一套設定工具menuconfig。
(2)ncurses庫是linux中用來實現文字式的圖形介面,linux內核中使用了ncurses庫來提供menuconfig
(3)scripts\kconfig\lxdialog目錄下的一些c檔案就是用來提供menuconfig的那些程式原始碼。
2、menuconfig讀取Kconfig檔案
(1)menuconfig本身的軟體只負責提供menuconfig工作的這一套邏輯(譬如在menuconfig中通過上下左右箭頭按鍵來調整遊標,Enter ESC鍵等按鍵按下的響應),而並不負責提供內容(選單裡的專案)。
(2)menuconfig顯示的選單內容(一方面是選單的目錄結構,另一方面是每一個選單專案的細節)是由內核原始碼樹各個目錄下的Kconfig檔案來支援的。Kconfig檔案中按照一定的格式包含了一個又一個的設定項,每一個設定項在make menuconfig中都會成爲一個選單專案。而且menuconfig中顯示的選單目錄結構和原始碼目錄中的Kconfig的目錄結構是一樣的。
(3)在相應的Kconfig檔案中刪除一個config項,則再次make menuconfig時這個專案已經看不到了。
3、menuconfig讀取/寫入.config檔案
(1)剛纔已經知道menuconfig的選單內容來自於Kconfig檔案,但是每一個選單的選擇結果(Y、N、M)卻不是儲存在Kconfig檔案中的。Kconfig檔案是不變的,Kconfig檔案只是決定有沒有這個選單項,並不管這個選單項的選擇結果。
(2)menuconfig工作時在我們make menuconfig開啓時,他會讀取.config檔案,並且用.config檔案中的設定選擇結果來初始化menuconfig中各個選單項的選擇值。
總結:選單項的專案內容從Kconfig檔案來,選單項的選擇值從.config檔案來
(3)當我們每次退出make menuconfig時,menuconfig機制 機製會首先檢查我們有沒有更改某些設定項的值,如果我們本次沒有更改過任意一個設定專案的值那直接退出;如果我們有改動設定項的值則會提示我們是否儲存。此時如果點儲存,則會將我們更改過的設定重新寫入.config檔案中記錄,下一次再次開啓make menuconfig時會再次載入.config,最終去編譯內核時編譯連線程式會考慮.config中的設定值指導整個編譯連線過程。
總結:主要內容就是:menuconfig和Kconfig和.config的關係。
2.15.7.Kconfig檔案詳解1
1、Kconfig的格式
(1)Kconfig按照一定的格式來書寫,menuconfig程式可以識別這種格式,然後從中提取出有效資訊組成menuconfig中的選單項。
(2)將來在做驅動移植等工作時,有時需要自己新增Kconfig中的一個設定項來將某個裝置驅動新增到內核的設定專案中,這時候就需要對Kconfig的設定項格式有所瞭解,否則就不會新增。
(3)#開頭的行是註釋行
(4)menuconfig表示選單(本身屬於一個選單中的專案,但是他又有子選單專案)、config表示選單中的一個設定項(本身並沒有子選單下的專案)。
(5)menuconfig或者config後面空格隔開的大寫字母表示的類似於 NETDEVICES 的就是這個設定項的設定項名字,這個字串前面新增CONFIG_後就構成了.config中的設定項名字。
(6)一個menuconfig後面跟着的所有config項就是這個menuconfig的子選單。這就是Kconfig中表示的目錄關係。
(7)內核原始碼目錄樹中每一個Kconfig都會source引入其所有子目錄下的Kconfig,從而保證了所有的Kconfig專案都被包含進menuconfig中。這個也告訴我們:如果你自己在linux內核中新增了一個資料夾,一定要在這個資料夾下建立一個Kconfig檔案,然後在這個資料夾的上一層目錄的Kconfig中source引入這個資料夾下的Kconfig檔案。
2、tristate和bool的含義
(1)tristate意思是三態(3種狀態,對應Y、N、M三種選擇方式),bool是要麼真要麼假(對應Y和N)。所以tristate的意思就是這個設定項可以被三種選擇,bool的意思是這個設定項只能被2種選擇。
2.15.8.Kconfig檔案詳解2
2.15.8.1、depends的含義
(1)depends中文意思是「取決於」或者「依賴於」,所以depends在這裏的意思是:本設定項依賴於另一個設定項。如果那個依賴的設定項爲Y或者M,則本設定項纔有意義;如果依賴的哪個設定項本身被設定爲N,則本設定項根本沒有意義。
(2)depends專案會導致make menuconfig的時候找不到一些設定項。所以你在menuconfig中如果找不到一個選項,但是這個選項在Kconfig中卻是有的,則可能的原因就是這個設定項依賴的一個設定項是不成立的。
(3)depends並不要求依賴的設定項一定是一個,可以是多個,而且還可以有邏輯運算。這種時候只要依賴專案運算式子的裸機結果爲真則依賴就成立。
2.15.8.2、help
(1)幫助資訊,告訴我們這個設定項的含義,以及如何去設定他。
2.15.8.3、Kconfig和.config檔案和Makefile三者的關聯
(1)設定項被設定成Y、N、M會影響.config檔案中的CONFIG_XXX變數的設定值。
(2)這個.config中的設定值(=y、=m、沒有)會影響最終的編譯鏈接過程。如果=y則會被編入(built-in),如果=m會被單獨連線成一個ko模組,如果沒有則對應的程式碼不會被編譯。那麼這麼是怎麼實現的?都是通過makefile實現的。
(3)obj-$(CONFIG_DM9000) += dm9000.o
如果CONFIG_DM9000變數值爲y,則obj += dm9000.o,因此dm9000.c會被編譯;如果CONFIG_DM9000變數未定義,則dm9000.c不會被編譯。如果CONFIG_DM9000變數的值爲m則會被連線成ko模組(這個是在linux內核的Makefile中定義的規則)
總結:把menuconfig中的選單項、Kconfig中的設定項、.config中的一行、 Makefile中的一行,這4個東西結合起來理解,則整個linux內核的設定體系就明瞭了。
2.15.9.menuconfig的實驗學習思路
1、驗證menuconfig和.config的關係
(1)make menuconfig時,會讀取.config中的設定值來初始化menuconfig中的設定項。
驗證:如果理論正確的,那麼我自己手工修改了.config的設定後,再次make menuconfig時看到的初始值就應該是我手工修改的。
(2)menuconfig中修改了(按Y、N、M)設定項的值,然後退出時儲存,則這個儲存結果會修改.config檔案中的相應行。
驗證:如果結論是正確的,那麼在menucofig中修改了設定後儲存退出,再次去手工開啓.config檔案則可以看到相應設定的一行內容被修改了。
2、驗證menuconfig和Kconfig的關係
(1)menuconfig讀取Kconfig的內容作爲選單專案內容。
驗證1:在Kconfig中刪除一個config項,則再次make menuconfig時就看不到這個專案了。(上課時已經驗證過了)
驗證2:在Kconfig中自己新增建立一個config項,則再次make menuconfig時就能看到多了一個專案。
3、驗證驗證menuconfig和Makefile的關係
(1)我找一個模組,
把他配製成y,然後去make編譯連線,最後得到的zImage中這個模組就應該被編譯連線進去到zImage中了。
驗證:
方法一:去這個模組對應的原始碼目錄看一下這個原始碼有沒有被編譯
方法二:去zImage對應的elf格式的vmlinux中檢視符號
方法三:將vmlinux反編譯(objdump)後得到的檔案中找模組對應的符號
方法四:將zImage下載到開發板中啓動,啓動後看你的模組能不能工作