




已閱讀5頁,還剩9頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
電子與信息工程學院 題目 LINUX操作系統(tǒng)內(nèi)核編譯 姓 名 孟長庚 學 號 20111309031 專 業(yè) 信息工程11級1班 指導老師 杜景林 二一四年 一月 一 日目錄1課程設計簡介31.1 課程設計的目的31.2 相關原理介紹31.3Linux內(nèi)核模塊程序結(jié)構(gòu)31.4內(nèi)核模塊的編譯32 設計實現(xiàn)42.1內(nèi)核線程查看 42.2帶參模塊的實現(xiàn)42.3 Makefile文件的編寫53測試總結(jié)63.1內(nèi)核線程查看測試63.2帶參模塊的實現(xiàn)測試74 總結(jié)9一課程設計簡介1.1 課程設計目的實現(xiàn)內(nèi)核編譯相關操作1.2 相關原理介紹內(nèi)核,是一個操作系統(tǒng)的核心。它負責管理系統(tǒng)的進程、內(nèi)存、設備驅(qū)動程序、文件和網(wǎng)絡系統(tǒng),決定著系統(tǒng)的性能和穩(wěn)定性。Linux的一個重要的特點就是其源代碼的公開性, Linux修補漏洞速度快以及對最新軟件技術的利用方便,而Linux的內(nèi)核則是這些特點的最直接的代表。擁有了內(nèi)核的源程序我們可以了解系統(tǒng)是如何工作的,通過通讀源代碼,我們就可以了解系統(tǒng)的工作原理。其次,我們可以針對自己的情況,量體裁衣,定制適合自己的系統(tǒng),當然這樣就需要重新編譯內(nèi)核。在不需要對內(nèi)核進行重新編譯的情況下,內(nèi)核模塊可以動態(tài)的載入內(nèi)核或從內(nèi)核移出改變內(nèi)核,極大縮短了驅(qū)動編寫和內(nèi)核開發(fā)的時間。1.3 Linux內(nèi)核模塊程序結(jié)構(gòu)一個Linux內(nèi)核模塊主要由如下幾個部分組成:(1) 模塊加載函數(shù)通過insmod或modprobe命令加載內(nèi)核模塊時,模塊的加載函數(shù)會自動被內(nèi)核執(zhí)行,完成本模塊的相關初始化工作。(2) 模塊卸載函數(shù)當通過rmmod命令卸載某模塊時,模塊的卸載函數(shù)會自動被內(nèi)核執(zhí)行,完成與模塊加載函數(shù)相反的功能。(3) 模塊許可證聲明許可證(LICENSE)聲明描述內(nèi)核模塊的許可權(quán)限,這一部分是必須聲明的,如果不聲明LICENSE,模塊被加載時,將收到內(nèi)核被污染(module license unspecified taints kernel)的警告。在Linux 2.6內(nèi)核中,可接受的LICENSE有“GPL”、“GPL v2”、“GPL and additional rights”、“Dual BSD/GPL”、“Dual MPL/GPL”和“Proprietary”。大多數(shù)情況下,內(nèi)核模塊應遵循GPL兼容許可權(quán)。其中最常用的許可是GPL和DualBSD/GPL。(4) 其他可選部分模塊參數(shù),模塊參數(shù)是模塊被加載的時候可以被傳遞給它的值,它本身對應模塊內(nèi)部的全局變量;模塊導出符號,內(nèi)核模塊可以導出符號(symbol,對應于函數(shù)或變量),這樣其它模塊可以使用本模塊中的變量或函數(shù);模塊作者等信息聲明。1.4 內(nèi)核模塊的編譯在Linux 2.6內(nèi)核中,模塊的編譯需要配置過的內(nèi)核源代碼;編譯過程首先回到內(nèi)核目錄下讀取頂層的Makefile文件,然后返回模塊源碼所在目錄,經(jīng)過編譯、鏈接后生成的內(nèi)核模塊文件的后綴為.ko。故內(nèi)核模塊的編譯需要自己寫Makefile文件,當在命令行中執(zhí)行make命令時,將調(diào)用Makefile文件。二設計實現(xiàn)21 內(nèi)核線程查看設計一個模塊,該模塊功能是列出系統(tǒng)中所有內(nèi)核線程的程序名、PID號和進程狀態(tài)。該內(nèi)核模塊的功能類似于命令ps,只不過該模塊專查看內(nèi)核線程信息。首先在文件開始聲明一下模塊的許可證,即在文件中加入:MODULE_LICENSE(GPL);根據(jù)內(nèi)核模塊編程的模式,一個內(nèi)核模塊應該至少包含兩個函數(shù)。一個初始化函數(shù) ,還有一個退出(干一些收尾清理的工作)的函數(shù),當內(nèi)核模塊被rmmod卸載時被執(zhí)行。從內(nèi)核版本2.3.13開始,可以為初始化和結(jié)束函數(shù)起任意的名字。 在該模塊內(nèi)。兩個函數(shù)分別命名為:static int kernel_thread_init(void)和static void kernel_thread_exit(void)。調(diào)用宏module_init()和module_exit()去注冊初始化和退出這兩個函數(shù),即:module_init(kernel_thread_init);module_exit(kernel_thread_exit);到此內(nèi)核模塊基本框架基本完成。為了獲取到所有的內(nèi)核線程,可以使用宏for_each_process()。在內(nèi)核中有內(nèi)核線程組長鏈表,每個線程組長通過task_struc結(jié)構(gòu)的tasks成員加入該鏈表中。利用for_each_process()可以訪問到鏈表中的每一個進程。具體實現(xiàn)如下:struct task_struct *p;for_each_process(p) /相關函數(shù)及操作對遍歷到的每一個線程,讀取它的線程號、線程名稱以及線程狀態(tài)并輸出。當線程狀態(tài)為0時輸出runnale,為-1時輸出unrunnable,為其他時則輸出stopped。在這里輸出函數(shù)并不能使用printf,printf是用戶空間的輸出函數(shù),內(nèi)核空間使用的是printk,因為內(nèi)核沒有鏈接標準的C 函數(shù)庫。而實際上printk和printf的功能類似,printk是在內(nèi)核中運行的向控制臺輸出顯示的函數(shù)。printk日志輸出的級別一共有8個,由高到低分別為:KERN_EMERG、KERN_ALERT、KERN_CRIT、KERN_ERR、KERN_WARNING、KERN_NOTICE、KERN_INFO、KERN_DEBUG,默認采用的級別是 DEFAULT_ MESSAGE_LOGLEVEL(這個默認級別一般為,即與KERN_WARNING在一個級別上)。22 帶參模塊的實現(xiàn)設計一個帶參數(shù)的模塊,參數(shù)為進程的PID號,功能是列出進程的家族信息,包括父進程、兄弟進程和子進程的程序名、PID號。該模塊的基本框架和上一個模塊類似,聲明模塊許可證,注冊初始化和結(jié)束函數(shù)。不同之處是在該模塊中涉及到了模塊參數(shù)。在Linux操作系統(tǒng)內(nèi)核中提供了一種模塊帶參數(shù)的機制,是模塊的編寫者可以在加載模塊的時候提供一下信息,這些參數(shù)對于模塊來說都是一個全局變量。定義一個模塊參數(shù)可通過module_param()實現(xiàn):module_param(name,type,perm);參數(shù)name是用戶可見的參數(shù)名,也是模塊中存放模塊參數(shù)的變量名。參數(shù)type代表參數(shù)的類型,它可以是byte、short、int、long等類型。最后一個參數(shù)perm制定了模塊在sysfs文件系統(tǒng)下對應的文件權(quán)限,可以使八進制的,也可以是S_Ifoo的定義形式,如S_RUGO|S_IWUSR等。在該模塊中,定義一個進程的PID作為參數(shù),以實現(xiàn)任意進程家族信息的查詢,默認進程號為1,即在不添加參數(shù)情況下查看進程號為1的進程家族信息,具體實現(xiàn)如下:static int pid=1;module_param(pid,int,0644);為找到指定PID的進程,可以使用for_each_process(p)遍歷內(nèi)核所有進程,查找進程號為PID的進程。找到具體進程后,獲取進程的名稱。接下來判斷進程的父進程是否存在,若存在,在輸出父進程信息:if(p-real_parent=NULL) printk(No Parentn); else printk(Parent : %d %sn,p-real_parent-pid,p-real_parent-comm);下一步就是該搜索線程號為PID線程的兄弟進程及子進程。在Linux中采用多個鏈表確保有效查找系統(tǒng)里的進程,雙向鏈表list_head內(nèi)核中廣泛的使用。因為list_head一般嵌入到嚙合數(shù)據(jù)結(jié)構(gòu)中,為了便于訪問鏈表中的數(shù)據(jù),內(nèi)核提供了一系列的宏來實現(xiàn)鏈表的常規(guī)操作2。在這里使用list_for_each()和list_entry()來實現(xiàn)兄弟進程和子進程的查找。在上一步中得到了要查找的進程,可以由此進程得到他父進程的所有子進程組成的鏈表p-real_parent-children和此進程子進程的鏈表p-children。定義一個list_head結(jié)構(gòu)體用于list_entry()中:struct list_head *pp;宏list_for_each(pp,&p-real_parent-children)遍歷p-real_parent-children鏈表,每次pp指向一個對象成員,而宏list_entry(pp,struct task_struct,sibling);進一步得到該對象的指針。具體實現(xiàn)兄弟進程和子進程遍歷如下:struct task_struct *p,*psibling;list_for_each(pp,&p-real_parent-children) psibling=list_entry(pp,struct task_struct,sibling); printk(sibling %d %s n,psibling-pid,psibling-comm);list_for_each(pp,&p-children) psibling=list_entry(pp,struct task_struct,sibling); printk(children %d %s n,psibling-pid,psibling-comm);上述過程將輸出得到的兄弟進程和子進程的pid號和進程名稱。23 Makefile文件的編寫Make工具最主要也是最基本的功能就是通過makefile文件來描述源程序之間的相互關系并自動維護編譯工作。而makefile 文件需要按照某種語法進行編寫,文件中需要說明如何編譯各個源文件并連接生成可執(zhí)行文件,并要求定義源文件之間的依賴關系。makefile 文件是許多編譯器-包括 Windows NT 下的編譯器-維護編譯信息的常用方法,只是在集成開發(fā)環(huán)境中,用戶通過友好的界面修改 makefile 文件而已。在Linux內(nèi)核模塊編程中,Makefile文件模版都類似,具體結(jié)構(gòu)如下:ifneq ($(KERNELRELEASE),)obj-m :=目標文件.oelseKDIR :=/lib/modules/$(shell uname -r)/buildPWD :=$(shell pwd)default:$(MAKE) -C $(KDIR) M=$(PWD) modulesclean:$(MAKE) -C $(KDIR) M=$(PWD) cleanendifKERNELRELEASE是在內(nèi)核源碼的頂層Makefile中定義的一個變量,在第一次讀取執(zhí)行此Makefile時,KERNELRELEASE沒有被定義,所以make將讀取執(zhí)行else之后的內(nèi)容。如果make的目標是clean,直接執(zhí)行clean操作,然后結(jié)束。當make的目標為all時,-C $(KDIR) 指明跳轉(zhuǎn)到內(nèi)核源碼目錄下讀取那里的Makefile;M=$(PWD)表明然后返回到當前目錄繼續(xù)讀入、執(zhí)行當前的Makefile。當從內(nèi)核源碼目錄返回時,KERNELRELEASE已被被定義,此時第一行的ifneq成功,make將繼續(xù)讀取else之前的內(nèi)容。ifneq的內(nèi)容為kbuild語法的語句,指明模塊源碼中各文件的依賴關系,以及要生成的目標模塊名。三 測試總結(jié)3.1內(nèi)核線程查看測試(1) 切換到內(nèi)核模塊所在路徑kernel_threads,在命令行中輸入make,得到如下結(jié)果:(2) 輸入ls 列出當前目錄文件,可以看已生成kernel_threads.ko文件(3) 用命令insmod kernel_threads.ko載入模塊,并用lsmod查看模塊是否已載入,由下圖結(jié)果看以看到內(nèi)核已經(jīng)被載入。(4) 此時在控制臺無法看到內(nèi)核模塊輸出的信息,可以用dmesg查看內(nèi)核輸出信息,可以看到內(nèi)核已經(jīng)將搜索到的內(nèi)核線程信息輸出。(5) 最后用命令rmmod kernel_threads.ko將已加載的內(nèi)核卸載32 帶參模塊的實現(xiàn)測試(1) 切換到內(nèi)核模塊所在路徑thread_pid,在命令行中輸入make,得到如下結(jié)果:(2) 輸入ls 列出當前目錄文件,可以看已生成thread_pid.ko文件(3) 用命令insmod thread_pid.ko載入模塊,并用lsmod查看模塊是否已載入,由下圖結(jié)果看以看到內(nèi)核已經(jīng)被載入。(4) 此時在控制臺無法看到內(nèi)核模塊輸出的信息,可以用dmesg查看內(nèi)核輸出信息,可以看到內(nèi)核已經(jīng)將搜索到的內(nèi)核線程信息輸出。(5) 最后用命令rmmod thread_pid.ko將已加載的內(nèi)核卸載四 總結(jié)Linux模塊是在內(nèi)核空間運行的程序,實際上是一種目標對象文件,沒有鏈接,不能獨立運行,但是可以裝載到系統(tǒng)中作為內(nèi)核的一部分運行,從而可以動態(tài)擴充內(nèi)核的功能。Linux提供了內(nèi)核模塊這種功能強大的擴展方式,它不僅彌補了單內(nèi)核的一些不足,而且對性能沒有影響。通過內(nèi)核模塊機制,可以方便的進行內(nèi)核開發(fā)和驅(qū)動開發(fā),而事實上Linux中大多數(shù)驅(qū)動和文件系統(tǒng)都是已內(nèi)核模塊方式實現(xiàn)的。在內(nèi)核模塊機制下,可以隨時在需要的情況下加載新的內(nèi)核模塊,而不需要重新編譯內(nèi)核和引導系統(tǒng)。當內(nèi)核被加載到系統(tǒng)中時,他就成為內(nèi)核源
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 民企退休人員管理辦法
- 體檢信息保密管理辦法
- 目標設定:投資發(fā)展部績效考核指標
- 北京首個露營管理辦法
- 工程突發(fā)事件應急處理
- 生產(chǎn)經(jīng)營單位事故隱患排查治理情況
- 畜牧業(yè)安全生產(chǎn)
- 加大安全生產(chǎn)考核力度
- 安全生產(chǎn)質(zhì)量標準化考核辦法
- 護理查對規(guī)章制度
- 身份證地區(qū)對應碼表
- 湖南長沙長郡中學高一分班考試化學試卷
- 衡水市武強縣事業(yè)單位考試歷年真題
- 髖臼周圍截骨術治療成人髖關節(jié)發(fā)育不良
- 各科門診診所技術操作規(guī)程
- 新教材人教版高中化學選擇性必修1全冊課時練習及章末檢測含解析
- 浙江省建設工程施工費用定額相關費用計算程序表及費用取費費率換算表【實用文檔】doc
- 《Windows網(wǎng)絡操作系統(tǒng)》教學教案
- GB/T 23280-2009開式壓力機精度
- GB/T 20041.21-2008電纜管理用導管系統(tǒng)第21部分:剛性導管系統(tǒng)的特殊要求
- GB/T 17213.4-2015工業(yè)過程控制閥第4部分:檢驗和例行試驗
評論
0/150
提交評論