第9章 模塊的動(dòng)態(tài)加載和系統(tǒng)配置.ppt_第1頁(yè)
第9章 模塊的動(dòng)態(tài)加載和系統(tǒng)配置.ppt_第2頁(yè)
第9章 模塊的動(dòng)態(tài)加載和系統(tǒng)配置.ppt_第3頁(yè)
第9章 模塊的動(dòng)態(tài)加載和系統(tǒng)配置.ppt_第4頁(yè)
第9章 模塊的動(dòng)態(tài)加載和系統(tǒng)配置.ppt_第5頁(yè)
已閱讀5頁(yè),還剩70頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第9章模塊的動(dòng)態(tài)加載和系統(tǒng)配置 第9章模塊的動(dòng)態(tài)加載和系統(tǒng)配置 本章介紹了Linux內(nèi)核動(dòng)態(tài)加載功能模塊的工作原理 分析了Linux內(nèi)核中的系統(tǒng)配置結(jié)構(gòu) 解釋了Makefile和配置文件的格式以及配置語(yǔ)句的含義 最后給出一個(gè)簡(jiǎn)單的例子 說明如何將自行開發(fā)的代碼加入到Linux內(nèi)核中 9 1模塊的動(dòng)態(tài)加載 操作系統(tǒng)通常由內(nèi)核和一些系統(tǒng)服務(wù)程序 命令解釋 庫(kù)文件 鏈接和編譯程序等 組成 內(nèi)核是操作系統(tǒng)的靈魂 它為用戶進(jìn)程提供了一個(gè)虛擬機(jī)接口 用戶進(jìn)程可以并行運(yùn)行 公平的占用系統(tǒng)資源而互不干擾 9 1模塊的動(dòng)態(tài)加載 操作系統(tǒng)通常由內(nèi)核和一些系統(tǒng)服務(wù)程序 命令解釋 庫(kù)文件 鏈接和編譯程序等 組成 內(nèi)核是操作系統(tǒng)的靈魂 它為用戶進(jìn)程提供了一個(gè)虛擬機(jī)接口 用戶進(jìn)程可以并行運(yùn)行 公平的占用系統(tǒng)資源而互不干擾 從結(jié)構(gòu)上來(lái)分 可將操作系統(tǒng)分為微內(nèi)核結(jié)構(gòu)和單塊結(jié)構(gòu)兩類 WindowsNT和MINIX是典型的微內(nèi)核操作系統(tǒng) 而Linux則是單塊結(jié)構(gòu)的操作系統(tǒng) 微內(nèi)核結(jié)構(gòu)可方便地在系統(tǒng)中添加新的組件 而單塊結(jié)構(gòu)卻不容易做到這一點(diǎn) 為此 Linux系統(tǒng)使用可動(dòng)態(tài)加載和卸載的內(nèi)核模塊 LoadableKernelModules LKMs 可方便地在內(nèi)核中添加新的組件或卸載不再需要的內(nèi)核組件 Linux使用insmod來(lái)顯式加載內(nèi)核模塊 使用rmmod來(lái)卸載模塊 同時(shí)內(nèi)核自身也可以請(qǐng)求內(nèi)核后臺(tái)進(jìn)程kerneld來(lái)加載與卸載模塊 Linux模塊大多數(shù)是設(shè)備驅(qū)動(dòng)程序以及偽設(shè)備驅(qū)動(dòng)程序模塊 如網(wǎng)絡(luò)設(shè)備和文件系統(tǒng)等 動(dòng)態(tài)可加載代碼的優(yōu)點(diǎn)是可以讓內(nèi)核保持很小的尺寸并非常靈活 模塊機(jī)制可以無(wú)需重構(gòu)內(nèi)核并頻繁重新啟動(dòng)來(lái)嘗試運(yùn)行新內(nèi)核代碼 用戶可以根據(jù)自己系統(tǒng)的需要構(gòu)筑自己的私有內(nèi)核 Linux源碼的公開更是為改造其內(nèi)核 重建有特殊要求的操作系統(tǒng)提供了可能 模塊必須能夠找到其需要使用的內(nèi)核資源 例如模塊需要分配內(nèi)存時(shí) 要調(diào)用內(nèi)核的內(nèi)存分配例程kmalloc 但在構(gòu)造模塊時(shí)并不知道kmalloc 在內(nèi)存中何處 這樣內(nèi)核必須在使用這些模塊前修改模塊中對(duì)kmalloc 的引用地址 內(nèi)核在其內(nèi)核符號(hào)表中維護(hù)著一個(gè)內(nèi)核資源鏈表這樣當(dāng)加載模塊時(shí)它能夠解析出模塊中對(duì)內(nèi)核資源的引用 Linux還允許存在模塊堆棧 它在模塊之間相互調(diào)用時(shí)使用 例如 因?yàn)閂FAT VirtuaIFileAllocationTable 文件系統(tǒng)是從FAT FileAllocationTable 文件系統(tǒng)中擴(kuò)展而來(lái) VFAT文件系統(tǒng)模塊可能需要FAT文件系統(tǒng)模塊的服務(wù) 某個(gè)模塊對(duì)其他模塊的服務(wù)或資源的需求類似于模塊對(duì)內(nèi)核本身資源或服務(wù)的請(qǐng)求 不過此時(shí)所請(qǐng)求的服務(wù)是來(lái)自另外一個(gè)事先已加載的模塊 當(dāng)加載模塊時(shí) 內(nèi)核就把新近加載模塊輸出的所有資源和符號(hào)添加到內(nèi)核符號(hào)表 Kernel Symbol Table 中 在 proc ksyms 里面的每一個(gè)表項(xiàng)代表著一個(gè)公共的內(nèi)核符號(hào) 這就是內(nèi)核符號(hào)表 這些內(nèi)核符號(hào)是可以被LKM引用的 LKM中所存取的每一個(gè)符號(hào) 像函數(shù)名 也會(huì)被列在這個(gè)文件里面 在該文件中可以看到LKM到底可以調(diào)用那些函數(shù) 當(dāng)試圖卸載某個(gè)模塊時(shí) 內(nèi)核需要知道此模塊是否已經(jīng)沒有被使用 同時(shí)它需要有種方法來(lái)通知此將卸載模塊 模塊必須能夠在從內(nèi)核種刪除之前釋放其分配的所有系統(tǒng)資源 如內(nèi)核內(nèi)存或中斷 當(dāng)模塊被卸載時(shí) 內(nèi)核將從內(nèi)核符號(hào)表中刪除所有與之對(duì)應(yīng)的符號(hào) 但是 內(nèi)核模塊的引入也帶來(lái)了如下問題 但是 內(nèi)核模塊的引入也帶來(lái)了如下問題 1 有可能同時(shí)帶來(lái)與內(nèi)核模塊相關(guān)的性能與內(nèi)存損失 可加載模塊的代碼一般較長(zhǎng) 且額外的數(shù)據(jù)結(jié)構(gòu)可能會(huì)占據(jù)一些內(nèi)存 對(duì)內(nèi)核資源的間接使用也可能帶來(lái)效率方面的問題 對(duì)系統(tǒng)性能和內(nèi)存利用有負(fù)面影響 但是 內(nèi)核模塊的引入也帶來(lái)了如下問題 1 有可能同時(shí)帶來(lái)與內(nèi)核模塊相關(guān)的性能與內(nèi)存損失 可加載模塊的代碼一般較長(zhǎng) 且額外的數(shù)據(jù)結(jié)構(gòu)可能會(huì)占據(jù)一些內(nèi)存 對(duì)內(nèi)核資源的間接使用也可能帶來(lái)效率方面的問題 對(duì)系統(tǒng)性能和內(nèi)存利用有負(fù)面影響 2 一旦Linux模塊被加載 則和普通內(nèi)核代碼一樣成為內(nèi)核的一部分 具有與其他內(nèi)核代碼相同的權(quán)限與職責(zé) 因此 Linux內(nèi)核模塊也可以象所有內(nèi)核代碼和設(shè)備驅(qū)動(dòng)一樣使內(nèi)核崩潰 但是 內(nèi)核模塊的引入也帶來(lái)了如下問題 1 有可能同時(shí)帶來(lái)與內(nèi)核模塊相關(guān)的性能與內(nèi)存損失 可加載模塊的代碼一般較長(zhǎng) 且額外的數(shù)據(jù)結(jié)構(gòu)可能會(huì)占據(jù)一些內(nèi)存 對(duì)內(nèi)核資源的間接使用也可能帶來(lái)效率方面的問題 對(duì)系統(tǒng)性能和內(nèi)存利用有負(fù)面影響 2 一旦Linux模塊被加載 則和普通內(nèi)核代碼一樣成為內(nèi)核的一部分 具有與其他內(nèi)核代碼相同的權(quán)限與職責(zé) 因此 Linux內(nèi)核模塊也可以象所有內(nèi)核代碼和設(shè)備驅(qū)動(dòng)一樣使內(nèi)核崩潰 3 為了內(nèi)核模塊訪問所有內(nèi)核資源 內(nèi)核必須維護(hù)符號(hào)表 并在裝入和卸載模塊時(shí)修改這些符號(hào)表 但是 內(nèi)核模塊的引入也帶來(lái)了如下問題 1 有可能同時(shí)帶來(lái)與內(nèi)核模塊相關(guān)的性能與內(nèi)存損失 可加載模塊的代碼一般較長(zhǎng) 且額外的數(shù)據(jù)結(jié)構(gòu)可能會(huì)占據(jù)一些內(nèi)存 對(duì)內(nèi)核資源的間接使用也可能帶來(lái)效率方面的問題 對(duì)系統(tǒng)性能和內(nèi)存利用有負(fù)面影響 2 一旦Linux模塊被加載 則和普通內(nèi)核代碼一樣成為內(nèi)核的一部分 具有與其他內(nèi)核代碼相同的權(quán)限與職責(zé) 因此 Linux內(nèi)核模塊也可以象所有內(nèi)核代碼和設(shè)備驅(qū)動(dòng)一樣使內(nèi)核崩潰 3 為了內(nèi)核模塊訪問所有內(nèi)核資源 內(nèi)核必須維護(hù)符號(hào)表 并在裝入和卸載模塊時(shí)修改這些符號(hào)表 4 有些模塊要求利用其他模塊的功能 因此 內(nèi)核要維護(hù)模塊之間的依賴性 5 內(nèi)核必須能夠在卸載模塊時(shí)通知模塊 并且要釋放分配給模塊的內(nèi)存和中斷等資源 6 內(nèi)核版本和模塊版本的不兼容 也可能導(dǎo)致系統(tǒng)崩潰 因此 嚴(yán)格的版本檢查是必需的 9 1 1模塊的加載 9 1 1模塊的加載 有兩種方法可用來(lái)加載模塊 1 利用insmod命令手工將模塊插入內(nèi)核 9 1 1模塊的加載 有兩種方法可用來(lái)加載模塊 1 利用insmod命令手工將模塊插入內(nèi)核 2 由內(nèi)核在必要時(shí)加載模塊 稱為 需求加載 當(dāng)內(nèi)核發(fā)現(xiàn)有必要加載某個(gè)模塊時(shí) 如用戶安裝了內(nèi)核中不存在的文件系統(tǒng)時(shí) 內(nèi)核將請(qǐng)求內(nèi)核后臺(tái)進(jìn)程 kerneld 準(zhǔn)備加載適當(dāng)?shù)哪K 這個(gè)內(nèi)核后臺(tái)進(jìn)程僅僅是一個(gè)帶有超級(jí)用戶權(quán)限的普通用戶進(jìn)程 當(dāng)系統(tǒng)啟動(dòng)時(shí)它也被啟動(dòng)并為內(nèi)核打開了一個(gè)進(jìn)程間通訊 IPC 通道 內(nèi)核可以利用該通道向Kerneld進(jìn)程發(fā)送任務(wù)的執(zhí)行請(qǐng)求 Kerneld進(jìn)程的主要功能是加載和卸載模塊 另外 該進(jìn)程也負(fù)責(zé)其他一些任務(wù) 例如打開和關(guān)閉PPP鏈接等 kerneld自身并不執(zhí)行這些任務(wù) 它通過某些程序如insmod來(lái)做此工作 因此 該進(jìn)程實(shí)際是代表內(nèi)核進(jìn)行調(diào)度的代理 執(zhí)行insmod命令時(shí) 必須指定要加載模塊的位置 對(duì)需求加載的內(nèi)核模塊 通常保存在 lib modules kernel version 和系統(tǒng)的其他程序一樣 內(nèi)核模塊實(shí)際是經(jīng)連接的目標(biāo)文件 但模塊是可重定位的 也就是說 為了讓裝入的模塊和已有的內(nèi)核組件之間可以互相訪問 模塊不能連接為從特定地址執(zhí)行的映像文件 模塊可以是a out或elf格式的目標(biāo)文件 insmod利用一個(gè)特權(quán)系統(tǒng)調(diào)用 可找到內(nèi)核的導(dǎo)出符號(hào)表 符號(hào)成對(duì)出現(xiàn) 一個(gè)是符號(hào)名稱 另外一個(gè)是符號(hào)的值 例如符號(hào)的地址 內(nèi)核維護(hù)一個(gè)由module list指針指向的module鏈表 其中第一個(gè)module數(shù)據(jù)結(jié)構(gòu)保存有內(nèi)核的導(dǎo)出符號(hào)表 見圖9 1 并不是所有的內(nèi)核符號(hào)均在符號(hào)表中導(dǎo)出 而只有一些特殊的符號(hào)才被添加到符號(hào)表中 例如 request irq 是一個(gè)導(dǎo)出符號(hào) 它是一個(gè)內(nèi)核例程 可由驅(qū)動(dòng)程序申請(qǐng)控制某個(gè)特定的系統(tǒng)中斷 利用ksyms命令或查看 proc ksyms文件內(nèi)容 可非常方便地看到所有的內(nèi)核導(dǎo)出符號(hào)及其符號(hào)值 利用ksyms命令 不僅可以看到內(nèi)核的所有符號(hào) 也可以看到只由以加載模塊導(dǎo)出的符號(hào) insmod命令將模塊讀到它本身的虛擬內(nèi)存中 然后利用內(nèi)核導(dǎo)出的符號(hào)表 修正尚未解析的對(duì)內(nèi)核例程的引用 這種修正實(shí)際是對(duì)模塊在內(nèi)存中的映像進(jìn)行修正 insmod將符號(hào)的地址寫入模塊中適當(dāng)?shù)奈恢枚鴮?shí)現(xiàn)修正 圖9 1裝入VFAT和FAT之后的內(nèi)核模塊表 insmod命令修正模塊對(duì)內(nèi)核符號(hào)的引用之后 再次利用特權(quán)系統(tǒng)調(diào)用請(qǐng)求內(nèi)核分配足夠的物理內(nèi)存空間保存新的模塊 內(nèi)核將分配新的module數(shù)據(jù)結(jié)構(gòu)以及足夠的內(nèi)核內(nèi)存 并將新模塊添加在內(nèi)核模塊表的末尾 新的內(nèi)核模塊標(biāo)記為Uninitialized 未初始化 圖9 1是裝入VFAT和FAT模塊之后的內(nèi)核模塊表 圖中并沒有表示出第一個(gè)模塊 它實(shí)際是一個(gè)偽模塊 僅僅用來(lái)保存內(nèi)核的導(dǎo)出符號(hào)表 利用lsmod命令可列出所有已加載的內(nèi)核模塊以及它們的內(nèi)在依賴性 內(nèi)核為新模塊分配的內(nèi)核內(nèi)存映射到insmod進(jìn)程的地址空間中 這樣 insmod就可以將模塊復(fù)制到新分配的內(nèi)存中 insmod還對(duì)模塊進(jìn)行重新定位 經(jīng)重定位之后 新的模塊就可以從新分配的內(nèi)核地址開始運(yùn)行了 顯然 模塊不能期望自己能夠在不同的Linux系統(tǒng) 或前后兩次裝入時(shí)被加載到相同地址 重定位操作可通過對(duì)模塊映像中適當(dāng)?shù)牡刂愤M(jìn)行修正而解決這一問題 新的模塊也要向內(nèi)核導(dǎo)出符號(hào) 由insmod建立相應(yīng)的符號(hào)表 每個(gè)內(nèi)核模塊必須包含模塊的初始化和清除例程 這些例程作為每個(gè)模塊均具備的例程而不被導(dǎo)出 但insmod必須知道它們的地址 并將地址傳遞給內(nèi)核 insmod同樣利用特權(quán)系統(tǒng)調(diào)用將模塊的初始化和清除例程地址傳遞給內(nèi)核 新的模塊添加到內(nèi)核之后 它必須更新內(nèi)核符號(hào)集并修改使用新模塊的模塊 由其他模塊依賴的模塊必須在自身符號(hào)表的末尾維護(hù)一個(gè)引用表 并指向其他模塊的module結(jié)構(gòu) 例如 圖9 1表明VFAT文件系統(tǒng)模塊依賴于FAT文件系統(tǒng)模塊 因此 FAT模塊包含一個(gè)對(duì)VFAT模塊的引用 該引用在裝入VFAT模塊時(shí)添加 內(nèi)核成功調(diào)用模塊的初始化例程之后繼續(xù)模塊的安裝 最后 模塊狀態(tài)被設(shè)置為Running 運(yùn)行 模塊的清除例程保存在module數(shù)據(jù)結(jié)構(gòu)中 在卸載模塊時(shí)由內(nèi)核調(diào)用 9 1 2模塊的卸載 和模塊的加載類似 可利用rmmod命令手工卸載模塊 當(dāng)對(duì)需求加載的模塊則由kerneld在不再需要時(shí)自動(dòng)卸載 每次kerneld的空閑定時(shí)器到期時(shí) 它會(huì)利用系統(tǒng)調(diào)用將當(dāng)前不再使用的需求加載模塊從內(nèi)核中移走 啟動(dòng)kerneld時(shí)指定該定時(shí)器的時(shí)間 通常的時(shí)間為180秒 如果內(nèi)核的其他部分依賴于裝入的模塊時(shí) 該模塊不能卸載 例如 如果掛裝了FAT文件系統(tǒng) 則不能卸載已裝入的FAT文件系統(tǒng)模塊 lsmod命令的輸出會(huì)顯示已安裝模塊的使用計(jì)數(shù) 例如 Module pages Usedby msdos51vfat41 autoclean fat62 autoclean 使用計(jì)數(shù)就是依賴于該模塊的內(nèi)核實(shí)體個(gè)數(shù) 模塊的使用計(jì)數(shù)保存在模塊映像的第一個(gè)長(zhǎng)整型中 但是 這一長(zhǎng)整型中還包含有AUTOCLEAN和VISITED標(biāo)志 這兩個(gè)標(biāo)志均由需求加載的模塊使用 具有AUTOCLEAN標(biāo)志的模塊是系統(tǒng)認(rèn)為可以自動(dòng)卸載的模塊 具有VISITED標(biāo)志的模塊表明正由其他內(nèi)核組件使用 當(dāng)任何其他內(nèi)核組件使用該模塊是設(shè)置該標(biāo)志 當(dāng)kerneld請(qǐng)求系統(tǒng)移走不使用的需求加載模塊時(shí) 系統(tǒng)首先尋找可以移走的模塊 但系統(tǒng)只查看標(biāo)記為AUTOCLEAN 并且狀態(tài)處于RUNNING的模塊 如果上述模塊的VISITED標(biāo)志被清除 則系統(tǒng)將卸載該模塊 否則系統(tǒng)會(huì)清除VISITED標(biāo)志并查看下一個(gè)模塊 假定某個(gè)模塊是可卸載的 則系統(tǒng)調(diào)用其清除例程釋放分配該模塊的內(nèi)核資源 相應(yīng)的module數(shù)據(jù)結(jié)構(gòu)被標(biāo)志為DELETED并從內(nèi)核模塊鏈表中斷開 所有由該模塊依賴的模塊 系統(tǒng)會(huì)修改它們的引用表以便取消依賴性 最后 系統(tǒng)釋放模塊的內(nèi)核內(nèi)存 9 1 3內(nèi)核模塊的管理 9 1 3內(nèi)核模塊的管理 在Linux里 除了直接修改系統(tǒng)核心的源代碼 把設(shè)備驅(qū)動(dòng)程序加進(jìn)核心里以外 還可以把設(shè)備驅(qū)動(dòng)程序作為可加載的模塊 由系統(tǒng)管理員動(dòng)態(tài)地加載它 使之成為核心的一部分 也可以由系統(tǒng)管理員把已加載地模塊動(dòng)態(tài)地卸載下來(lái) Linux的模塊可以用C語(yǔ)言編寫 用gcc編譯成目標(biāo)文件 不進(jìn)行鏈接 作為 o文件存在 為此需要在gcc命令行里加上 c的參數(shù) 在編譯時(shí) 還應(yīng)該在gcc的命令行里加上這樣的參數(shù) D KERNEL DMODULE 由于在不鏈接時(shí) gcc只允許一個(gè)輸入文件 因此一個(gè)模塊的所有部分都必須在一個(gè)文件里實(shí)現(xiàn) 編譯好的模塊 o放 lib modules xxxx misc下 xxxx表示核心版本 如在核心版本為2 0 30時(shí)應(yīng)該為 lib modules 2 0 30 misc 然后用depmod a使此模塊成為可加載模塊 模塊用insmod命令加載 用rmmod命令來(lái)卸載 并可以用lsmod命令來(lái)查看所有已加載的模塊的狀態(tài) 利用insmod命令可手工裝入內(nèi)核模塊 利用lsmod可查看當(dāng)前裝入的內(nèi)核模塊以及需求加載模塊的使用計(jì)數(shù)及標(biāo)志信息 利用rmmod則可以卸載指定的模塊 編寫模塊程序的時(shí)候 必須提供兩個(gè)函數(shù) 一個(gè)是intinit module void 供insmod在加載此模塊的時(shí)候自動(dòng)調(diào)用 負(fù)責(zé)進(jìn)行設(shè)備驅(qū)動(dòng)程序的初始化工作 init module返回0以表示初始化成功 返回負(fù)數(shù)表示失敗 另一個(gè)函數(shù)是voidcleanup module void 在模塊被卸載時(shí)調(diào)用 負(fù)責(zé)進(jìn)行設(shè)備驅(qū)動(dòng)程序的清除工作 在成功的向系統(tǒng)注冊(cè)了設(shè)備驅(qū)動(dòng)程序后 調(diào)用register chrdev成功后 就可以用mknod命令來(lái)把設(shè)備映射為一個(gè)特別文件 其它程序使用這個(gè)設(shè)備的時(shí)候 只要對(duì)此特別文件進(jìn)行操作就行了 9 2Linux內(nèi)核配置系統(tǒng) 隨著Linux操作系統(tǒng)的廣泛應(yīng)用 特別是Linux在嵌入式領(lǐng)域的發(fā)展 越來(lái)越多的人開始投身到Linux內(nèi)核級(jí)的開發(fā)中 面對(duì)日益龐大的Linux內(nèi)核源代碼 開發(fā)者在完成自己的內(nèi)核代碼后 都將面臨著同樣的問題 即如何將源代碼融入到Linux內(nèi)核中 增加相應(yīng)的Linux配置選項(xiàng) 并最終被編譯進(jìn)Linux內(nèi)核 這就需要了解Linux的內(nèi)核配置系統(tǒng) Linux內(nèi)核是由分布在全球的Linux愛好者共同開發(fā)的 Linux內(nèi)核每天都面臨著許多新的變化 但是 Linux內(nèi)核的組織并沒有出現(xiàn)混亂的現(xiàn)象 反而顯得非常的簡(jiǎn)潔 而且具有很好的擴(kuò)展性 開發(fā)人員可以很方便的向Linux內(nèi)核中增加新的內(nèi)容 原因之一就是Linux采用了模塊化的內(nèi)核配置系統(tǒng) 從而保證了內(nèi)核的擴(kuò)展性 9 2 1配置系統(tǒng)的基本結(jié)構(gòu) 9 2 1配置系統(tǒng)的基本結(jié)構(gòu) Linux內(nèi)核的配置系統(tǒng)由三個(gè)部分組成 1 Makefile 分布在Linux內(nèi)核源代碼中的Makefile定義Linux內(nèi)核的編譯規(guī)則 2 配置文件 config in 給用戶提供配置選擇的功能 3 配置工具 包括配置命令解釋器 對(duì)配置腳本中使用的配置命令進(jìn)行解釋 和配置用戶界面 提供基于字符界面 基于Ncurses圖形界面以及基于Xwindows圖形界面的用戶配置界面 各自對(duì)應(yīng)于Makeconfig Makemenuconfig和Makexconfig 這些配置工具都是使用腳本語(yǔ)言 如Tcl TK Perl編寫的 也包含一些用C編寫的代碼 除非是配置系統(tǒng)的維護(hù)者 一般的內(nèi)核開發(fā)者無(wú)須了解配置系統(tǒng)的原理 只需要知道如何使用配置系統(tǒng) 如何編寫Makefile和配置文件就可以 所以 本節(jié)只對(duì)Makefile和配置文件進(jìn)行討論 凡是涉及到與具體CPU體系結(jié)構(gòu)相關(guān)的內(nèi)容 都以ARM為例 這樣不僅可以將討論的問題明確化 而且對(duì)內(nèi)容本身不產(chǎn)生影響 9 2 2Makefile Makefile的作用是根據(jù)配置的情況 構(gòu)造出需要編譯的源文件列表 然后分別編譯 并把目標(biāo)代碼鏈接到一起 最終形成Linux內(nèi)核二進(jìn)制文件 由于Linux內(nèi)核源代碼是按照樹形結(jié)構(gòu)組織的 所以Makefile也被分布在目錄樹中 Linux內(nèi)核中的Makefile以及與Makefile直接相關(guān)的文件有 Makefile 頂層Makefile 是整個(gè)內(nèi)核配置 編譯的總體控制文件 config 內(nèi)核配置文件 包含由用戶選擇的配置選項(xiàng) 用來(lái)存放內(nèi)核配置后的結(jié)果 如makeconfig arch Makefile 位于各種CPU體系目錄下的Makefile 如arch arm Makefile 是針對(duì)特定平臺(tái)的Makefile 各個(gè)子目錄下的Makefile 比如drivers Makefile 負(fù)責(zé)所在子目錄下源代碼的管理 Rules make 規(guī)則文件 被所有的Makefile使用 用戶通過makeconfig配置后 產(chǎn)生了 config 頂層Makefile讀入 config中的配置選擇 頂層Makefile有兩個(gè)主要的任務(wù) 產(chǎn)生vmlinux文件和內(nèi)核模塊 module 為了達(dá)到此目的 頂層Makefile遞歸的進(jìn)入到內(nèi)核的各個(gè)子目錄中 分別調(diào)用位于這些子目錄中的Makefile 至于到底進(jìn)入哪些子目錄 取決于內(nèi)核的配置 在頂層Makefile中 有一句 includearch ARCH Makefile 包含了特定CPU體系結(jié)構(gòu)下的Makefile 這個(gè)Makefile中包含了平臺(tái)相關(guān)的信息 位于各個(gè)子目錄下的Makefile同樣也根據(jù) config給出的配置信息 構(gòu)造出當(dāng)前配置下需要的源文件列表 并在文件的最后有include TOPDIR Rules make Rules make文件起著非常重要的作用 它定義了所有Makefile共用的編譯規(guī)則 比如 如果需要將本目錄下所有的c程序編譯成匯編代碼 需要在Makefile中有以下的編譯規(guī)則 s c CC CFLAGS S o 有很多子目錄下都有同樣的要求 就需要在各自的Makefile中包含此編譯規(guī)則 這會(huì)比較麻煩 而Linux內(nèi)核中則把此類的編譯規(guī)則統(tǒng)一放置到Rules make中 并在各自的Makefile中包含進(jìn)了Rules make includeRules make 這樣就避免了在多個(gè)Makefile中重復(fù)同樣的規(guī)則 對(duì)于上面的例子 在Rules make中對(duì)應(yīng)的規(guī)則為 s c CC CFLAGS EXTRA CFLAGS CFLAGS F CFLAGS S o Makefile中的變量頂層Makefile定義并向環(huán)境中輸出了許多變量 為各個(gè)子目錄下的Makefile傳遞一些信息 有些變量 比如SUBDIRS 不僅在頂層Makefile中定義并且賦初值 而且在arch Makefile還作了擴(kuò)充 常用的變量有以下幾類 1 版本信息版本信息有 VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION和KERNELRELEASE 版本信息定義了當(dāng)前內(nèi)核的版本 例如VERSION 2 PATCHLEVEL 4 SUBLEVEL 18 EXATAVERSION rmk7 它們共同構(gòu)成內(nèi)核的發(fā)行版本KERNELRELEASE 2 4 18 rmk7 2 CPU體系結(jié)構(gòu) ARCH在頂層Makefile的開頭 用ARCH定義目標(biāo)CPU的體系結(jié)構(gòu) 比如ARCH arm等 許多子目錄的Makefile中 要根據(jù)ARCH的定義選擇編譯源文件的列表 3 路徑信息 TOPDIR和SUBDIRSTOPDIR定義了Linux內(nèi)核源代碼所在的根目錄 例如 各個(gè)子目錄下的Makefile通過 TOPDIR Rules make就可以找到Rules make的位置 SUBDIRS定義了一個(gè)目錄列表 在編譯內(nèi)核或模塊時(shí) 頂層Makefile就是根據(jù)SUBDIRS來(lái)決定進(jìn)入哪些子目錄 SUBDIRS的值取決于內(nèi)核的配置 在頂層Makefile中SUBDIRS賦值為kerneldriversmmfsnetipclib 根據(jù)內(nèi)核的配置情況 在arch Makefile中擴(kuò)充了SUBDIRS的值 4 內(nèi)核組成信息 HEAD CORE FILES NETWORKS DRIVERS LIBSLinux內(nèi)核文件vmlinux是由以下規(guī)則產(chǎn)生的 vmlinux CONFIGURATION init main oinit version olinuxsubdirs LD LINKFLAGS HEAD init main oinit version o start group CORE FILES DRIVERS NETWORKS LIBS end group ovmlinux可以看出 vmlinux是由HEAD main o version o CORE FILES DRIVERS NETWORKS和LIBS組成的 這些變量 如HEAD 都是用來(lái)定義連接生成vmlinux的目標(biāo)文件和庫(kù)文件列表 其中 HEAD在arch Makefile中定義 用來(lái)確定被最先鏈接進(jìn)vmlinux的文件列表 例如 對(duì)于ARM系列的CPU HEAD定義為 HEAD arch arm kernel head PROCESSOR o arch arm kernel init task o表明head PROCESSOR o和init task o需要最先被鏈接到vmlinux中 PROCESSOR為armv或armo 取決于目標(biāo)CPU CORE FILES NETWORK DRIVERS和LIBS在頂層Makefile中定義 并且由arch Makefile根據(jù)需要進(jìn)行擴(kuò)充 CORE FILES對(duì)應(yīng)著內(nèi)核的核心文件 有kernel kernel o mm mm o fs fs o ipc ipc o 可以看出 這些是組成內(nèi)核最為重要的文件 同時(shí) arch arm Makefile對(duì)CORE FILES進(jìn)行了擴(kuò)充 arch arm Makefile Ifwehaveamachine specificdirectory thenincludeitinthebuild MACHDIR arch arm mach MACHINE ifeq MACHDIR wildcard MACHDIR SUBDIRS MACHDIR CORE FILES MACHDIR MACHINE o CORE FILES endifHEAD arch arm kernel head PROCESSOR o arch arm kernel init task oSUBDIRS arch arm kernelarch arm mmarch arm libarch arm nwfpeCORE FILES arch arm kernel kernel oarch arm mm mm o CORE FILES LIBS arch arm lib lib a LIBS 5 編譯信息 CPP CC AS LD AR CFLAGS LINKFLAGS在Rules make中定義的是編譯的通用規(guī)則 具體到特定的場(chǎng)合 需要明確給出編譯環(huán)境 編譯環(huán)境就是在以上的變量中定義的 針對(duì)交叉編譯的要求 定義了CROSS COMPILE 如 CROSS COMPILE arm linux CC CROSS COMPILE gccLD CROSS COMPILE ld CROSS COMPILE定義了交叉編譯器前綴arm linux 表明所有的交叉編譯工具都是以arm linux 開頭的 所以在各個(gè)交叉編譯器工具之前 都加入了 CROSS COMPILE 以組成一個(gè)完整的交叉編譯工具文件名 比如arm linux gcc CFLAGS定義了傳遞給C編譯器的參數(shù) LINKFLAGS是鏈接生成vmlinux時(shí) 由鏈接器使用的參數(shù) LINKFLAGS在arm Makefile中定義 如 arch arm MakefileLINKFLAGS p X Tarch arm vmlinux lds 6 配置變量CONFIG config文件中有許多的配置變量等式 用來(lái)說明用戶配置的結(jié)果 例如CONFIG MODULES y表明用戶選擇了Linux內(nèi)核的模塊功能 config被頂層Makefile包含后 就形成許多的配置變量 每個(gè)配置變量具有確定的值 y表示本編譯選項(xiàng)對(duì)應(yīng)的內(nèi)核代碼被靜態(tài)編譯進(jìn)Linux內(nèi)核 m表示本編譯選項(xiàng)對(duì)應(yīng)的內(nèi)核代碼被編譯成模塊 n表示不選擇此編譯選項(xiàng) 如果根本就沒有選擇 那么配置變量的值為空 2 Rules make變量Rules make是編譯規(guī)則文件 所有的Makefile中都會(huì)包括Rules make Rules make文件定義了許多變量 最為重要是那些編譯 鏈接列表變量 O OBJS L OBJS OX OBJS LX OBJS 本目錄下需要編譯進(jìn)Linux內(nèi)核vmlinux的目標(biāo)文件列表 其中OX OBJS和LX OBJS中的 X 表明目標(biāo)文件使用了EXPORT SYMBOL輸出符號(hào) M OBJS MX OBJS 本目錄下需要被編譯成可裝載模塊的目標(biāo)文件列表 同樣 MX OBJS中的 X 表明目標(biāo)文件使用了EXPORT SYMBOL輸出符號(hào) O TARGET L TARGET 每個(gè)子目錄下都有一個(gè)O TARGET或L TARGET Rules make首先從源代碼編譯生成O OBJS和OX OBJS中所有的目標(biāo)文件 然后使用 LD r把它們鏈接成一個(gè)O TARGET或L TARGET O TARGET以 o結(jié)尾 而L TARGET以 a結(jié)尾 3 Makefile子目錄 3 Makefile子目錄 子目錄Makefile用來(lái)控制本級(jí)目錄以下源代碼的編譯規(guī)則 下面通過一個(gè)例子來(lái)講解子目錄Makefile的組成 Makefileforthelinuxkernel Allofthe potential objectsthatexportsymbols Thislistcomesfrom grep lEXPORT SYMBOL hc export objs tc o Objectfilelists obj y obj m obj n obj obj CONFIG TC tc oobj CONFIG ZS zs oobj CONFIG VT lk201 olk201 map olk201 remap o Filesthatarebothresidentandmodular removefrommodular obj m filter out obj y obj m TranslatetoRules makelists L TARGET tc aL OBJS sort filter out export objs obj y LX OBJS sort filter export objs obj y M OBJS sort filter out export objs obj m MX OBJS sort filter export objs obj m include TOPDIR Rules make 1 注釋對(duì)Makefile的說明和解釋 由 開始 2 編譯目標(biāo)定義類似于obj CONFIG TC tc o的語(yǔ)句是用來(lái)定義編譯的目標(biāo) 是子目錄Makefile中最重要的部分 編譯目標(biāo)定義那些在本子目錄下 需要編譯到Linux內(nèi)核中的目標(biāo)文件列表 為了只在用戶選擇了此功能后才編譯 所有的目標(biāo)定義都融合了對(duì)配置變量的判斷 前面說過 每個(gè)配置變量取值范圍是 y n m和空 obj CONFIG TC 分別對(duì)應(yīng)著obj y obj n obj m obj 如果CONFIG TC配置為y 那么tc o就進(jìn)入了obj y列表 obj y為包含到Linux內(nèi)核vmlinux中的目標(biāo)文件列表 obj m為編譯成模塊的目標(biāo)文件列表 obj n和obj 中的文件列表被忽略 配置系統(tǒng)就根據(jù)這些列表的屬性進(jìn)行編譯和鏈接 export objs中的目標(biāo)文件都使用了EXPORT SYMBOL 定義了公共的符號(hào) 以便可裝載模塊使用 在tc c文件的最后部分 有 EXPORT SYMBOL search tc card 表明tc o有符號(hào)輸出 這里需要指出的是 對(duì)于編譯目標(biāo)的定義 存在著兩種格式 分別是老式定義和新式定義 老式定義就是前面Rules make使用的那些變量 新式定義就是obj y obj m obj n和obj Linux內(nèi)核推薦使用新式定義 不過由于Rules make不理解新式定義 需要在Makefile中的適配段將其轉(zhuǎn)換成老式定義 3 適配段適配段的作用是將新式定義轉(zhuǎn)換成老式定義 在上面的例子中 適配段就是將obj y和obj m轉(zhuǎn)換成Rules make能夠理解的L TARGET L OBJS LX OBJS M OBJS MX OBJS L OBJS sort filter out export objs obj y 定義了L OBJS的生成方式 在obj y的列表中過濾掉export objs tc o 然后排序并去除重復(fù)的文件名 這里使用到了GNUMake的一些特殊功能 具體的含義可參考Make的文檔 infomake 4 include TOPDIR Rules make 9 2 3配置文件 9 2 3配置文件 除了Makefile的編寫 另外一個(gè)重要的工作就是把新功能加入到Linux的配置選項(xiàng)中 提供此項(xiàng)功能的說明 讓用戶有機(jī)會(huì)選擇此項(xiàng)功能 所有的這些都需要在config in文件中用配置語(yǔ)言來(lái)編寫配置腳本 在Linux內(nèi)核中 配置命令有多種方式 以字符界面配置 makeconfig 為例 頂層Makefile調(diào)用scripts Configure 按照arch arm config in來(lái)進(jìn)行配置 命令執(zhí)行完后產(chǎn)生文件 config 其中保存著配置信息 下一次再做makeconfig將產(chǎn)生新的 config文件 原 config被改名為 config old 1 配置語(yǔ)言 1 頂層菜單mainmenu name prompt prompt 是用 或 包圍的字符串 與 的區(qū)別是 中可使用 引用變量的值 mainmenu name設(shè)置最高層菜單的名字 它只在makexconfig時(shí)才會(huì)顯示 2 詢問語(yǔ)句bool prompt symbol hex prompt symbol word int prompt symbol word string prompt symbol word tristate prompt symbol 詢問語(yǔ)句首先顯示一串提示符 prompt 等待用戶輸入 并把輸入的結(jié)果賦給 symbol 所代表的配置變量 不同的詢問語(yǔ)句的區(qū)別在于它們接受的輸入數(shù)據(jù)類型不同 比如bool接受布爾類型 y或n hex接受16進(jìn)制數(shù)據(jù) 有些詢問語(yǔ)句還有第三個(gè)參數(shù) word 用來(lái)給出默認(rèn)值 3 定義語(yǔ)句define bool symbol word define hex symbol word define int symbol word define string symbol word define tristate symbol word 不同于詢問語(yǔ)句等待用戶輸入 定義語(yǔ)句顯式的給配置變量 symbol 賦值 word 3 定義語(yǔ)句define bool symbol word define hex symbol word define int symbol word define string symbol word define tristate symbol word 不同于詢問語(yǔ)句等待用戶輸入 定義語(yǔ)句顯式的給配置變量 symbol 賦值 word 4 依賴語(yǔ)句dep bool prompt symbol dep dep mbool prompt symbol dep dep hex prompt symbol word dep dep int prompt symbol word dep dep string prompt symbol word dep dep tristate prompt symbol dep 與詢問語(yǔ)句類似 依賴語(yǔ)句也是定義新的配置變量 不同的是 配置變量 symbol 的取值范圍將依賴于配置變量列表 dep 這就意味著 被定義的配置變量所對(duì)應(yīng)功能的取舍取決于依賴列表所對(duì)應(yīng)功能的選擇 以dep bool為例 如果 dep 列表的所有配置變量都取值y 則顯示 prompt 用戶可輸入任意的值給配置變量 symbol 但是只要有一個(gè)配置變量的取值為n 則 symbol 被強(qiáng)制成n 不同依賴語(yǔ)句的區(qū)別在于它們由依賴條件所產(chǎn)生的取值范圍不同 5 選擇語(yǔ)句choice prompt word word choice語(yǔ)句首先給出一串選擇列表 供用戶選擇其中一種 比如LinuxforARM支持多種基于ARMcore的CPU Linux使用choice語(yǔ)句提供一個(gè)CPU列表 供用戶選擇 choice ARMsystemtype AnakinCONFIG ARCH ANAKIN Archimedes A5000CONFIG ARCH ARCA5K Cirrus CL PS7500FECONFIG ARCH CLPS7500 SA1100 basedCONFIG ARCH SA1100 SharkCONFIG ARCH SHARK RiscPCChoice首先顯示 prompt 然后將 word 分解成前后兩個(gè)部分 前部分為對(duì)應(yīng)選擇的提示符 后部分是對(duì)應(yīng)選擇的配置變量 用戶選擇的配置變量為y 其余的都為n 6 if語(yǔ)句if expr then statement fiif expr then statement else statement fiif語(yǔ)句對(duì)配置變量 或配置變量的組合 進(jìn)行判斷 并作出不同的處理 判斷條件 expr 可以是單個(gè)配置變量或字符串 也可以是帶操作符的表達(dá)式 操作符有 o a等 7 菜單塊 menublock 語(yǔ)句mainmenu optionnext commentcomment endmenu引入新的菜單 在向內(nèi)核增加新的功能后 需要相應(yīng)的增加新的菜單 并在新菜單下給出此項(xiàng)功能的配置選項(xiàng) Comment后帶的注釋就是新菜單的名稱 所有歸屬于此菜單的配置選項(xiàng)語(yǔ)句都寫在comment和endmenu之間 8 Source語(yǔ)句source word word 是文件名 source的作用是調(diào)入新的文件 2 默認(rèn)配置Linux內(nèi)核支持非常多的硬件平臺(tái) 對(duì)于具體的硬件平臺(tái)來(lái)說 有些配置是必需的 有些配置卻不是必需的 此外 新增加功能的正常運(yùn)行往往也需要一定的先決條件 因此 特定硬件平臺(tái)能夠正常運(yùn)行對(duì)應(yīng)著一個(gè)最小的基本配置 這就是默認(rèn)配置 Linux內(nèi)核中針對(duì)每個(gè)ARCH都會(huì)有一個(gè)默認(rèn)配置 在向內(nèi)核代碼增加了新的功能后 如果新功能對(duì)于這個(gè)ARCH是必需的 就要修改此ARCH的默認(rèn)配置 修改方法如下 在Linux內(nèi)核根目錄下 備份 config文件cparch arm deconfig config修改 configcp configarch arm deconfig恢復(fù) config如果新增的功能適用于許多的ARCH 只要針對(duì)具體的ARCH 重復(fù)上面的步驟就可以了 3 幫助信息在配置Linux內(nèi)核時(shí) 遇到不懂含義的配置選項(xiàng) 可以查看它的幫助 從中可得到選擇的建議 下面介紹如何給一個(gè)配置選項(xiàng)增加幫助信息 所有配置選項(xiàng)的幫助信息都在Documentation Configure help中 它的格式為 給出本配置選項(xiàng)的名稱 對(duì)應(yīng)配置變量 對(duì)應(yīng)配置幫助信息 在幫助信息中 首先簡(jiǎn)單描述此功能 其次說明選擇了此功能后會(huì)有什么效果 不選擇又有什么效果 最后 不要忘了寫上 如果不清楚 選擇N 或者 Y 給不知所措的用戶以提示 9 2 4配置實(shí)例 9 2 4配置實(shí)例 對(duì)于一個(gè)開發(fā)者來(lái)說 將自己開發(fā)的內(nèi)核代碼加入到Linux內(nèi)核中 需要有三個(gè)步驟 首先確定把自己開發(fā)代碼放入到內(nèi)核的位置 其次 把自己開發(fā)的功能增加到Linux內(nèi)核的配置選項(xiàng)中 使用戶能夠選擇此功能 最后 構(gòu)建子目錄Makefile 根據(jù)用戶的選擇 將相應(yīng)的代碼編譯到最終生成的Linux內(nèi)核中去 下面通過一個(gè)簡(jiǎn)單的例子 testdriver 說明如何向Linux內(nèi)核中增加新的功能 1 目錄結(jié)構(gòu)testdriver放置在drivers test 目錄下 cddrivers test tree Config in Makefile cpu Makefile cpu c test c test client c test ioctl c test proc c test queue c test Makefile test c 2 配置文件 1 drivers test Config in TESTdriverconfiguration mainmenu optionnext commentcomment TESTDriver bool TESTsupport CONFIG TESTif CONFIG TEST y thentristate TESTuser spaceinterface CONFIG TEST USERbool TESTCPU CONFIG TEST CPUfiEndmenu由于testdriver對(duì)于內(nèi)核來(lái)說是新的功能 所以首先創(chuàng)建一個(gè)菜單TESTDriver 然后 顯示 TESTsupport 等待用戶選擇 接下來(lái)判斷用戶是否選擇了TESTDriver 如果是 CONFIG TEST y 則進(jìn)一步顯示子功能 用戶接口與CPU功能支持 由于用戶接口功能可以被編譯成內(nèi)核模塊 所以這里的詢問語(yǔ)句使用了tristate 因?yàn)閠ristate的取值范圍包括y n和m m就是對(duì)應(yīng)著模塊 2 配置文件 2 arch arm config in在文件的最后加入 sourcedrivers test Config in 將TESTDriver子功能的配置納入到Linux內(nèi)核的配置中 3 Makefile 1 drivers test Makefile drivers test Makefile MakefilefortheTEST SUB DIRS MOD SUB DIRS SUB DIRS ALL SUB DIRS SUB DIRS cpuL TARGET test aexport objs test otest client oobj CONFIG TEST test otest queue otest client oobj CONFIG TEST USER test ioctl oobj CONFIG PROC FS test proc osubdir CONFIG TEST CPU cpuinclude TOPDIR Rules makeclean fordirin ALL SUB DIRS domake C dirclean donerm f oa flags d

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論