Linux課程設(shè)計任務(wù)書_第1頁
Linux課程設(shè)計任務(wù)書_第2頁
Linux課程設(shè)計任務(wù)書_第3頁
Linux課程設(shè)計任務(wù)書_第4頁
Linux課程設(shè)計任務(wù)書_第5頁
已閱讀5頁,還剩65頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

2010年操作系統(tǒng)課程設(shè)計教師:周正勇輔導(dǎo):周正勇內(nèi)容簡介課程設(shè)計目的課程設(shè)計內(nèi)容課程設(shè)計提示課程設(shè)計實施方法與要求課程設(shè)計時間安排課程設(shè)計目的掌握Linux操作系統(tǒng)的使用方法;了解Linux系統(tǒng)內(nèi)核代碼結(jié)構(gòu);掌握實例操作系統(tǒng)的實現(xiàn)方法。培養(yǎng)良好的自學(xué)習(xí)慣和能力課程設(shè)計內(nèi)容1掌握Linux操作系統(tǒng)的使用方法,包括鍵盤命令、系統(tǒng)調(diào)用;掌握Linux下的編程環(huán)境。

編一個C程序,其內(nèi)容為實現(xiàn)文件拷貝的功能;(3)編一個C程序,其內(nèi)容為分窗口同時顯示三個并發(fā)進(jìn)程的運行結(jié)果。要求用到Linux下的圖形庫。課程設(shè)計內(nèi)容(Cont.)?2掌握系統(tǒng)調(diào)用的實現(xiàn)過程,通過編譯內(nèi)核方法,添加一個新的系統(tǒng)功能調(diào)用,實現(xiàn)文件拷貝的功能。需編寫一個應(yīng)用程序,調(diào)用新添加的系統(tǒng)調(diào)用進(jìn)行測試。3掌握Linux下添加設(shè)備驅(qū)動程序的方法。以模塊的方式,實現(xiàn)一個虛擬的字符設(shè)備驅(qū)動程序。課程設(shè)計內(nèi)容(Cont.)?4.了解和掌握/proc文件的特點和使用方法(1)了解/proc文件的特點和使用方法;(2)監(jiān)控系統(tǒng)狀態(tài),顯示系統(tǒng)中假設(shè)干部件使用情況;

(3)用圖形界面實現(xiàn)系統(tǒng)監(jiān)控狀態(tài).課程設(shè)計內(nèi)容(Cont.)?5.設(shè)計并實現(xiàn)一個模擬的文件系統(tǒng)〔選做)。為LINUX設(shè)計一個簡單的二級文件系統(tǒng)。1〕可以實現(xiàn)以下幾條命令〔至少4條〕。目錄:Dir文件操作:創(chuàng)立,翻開,讀,寫,關(guān)閉,刪除2〕列目錄時要列出文件名、物理地址,讀寫屬性和文件長度。課程設(shè)計提示一.Linux內(nèi)核簡介內(nèi)核〔kernel〕是操作系統(tǒng)的內(nèi)部核心程序,它向外部提供了對計算機(jī)設(shè)備的核心管理調(diào)用。一個進(jìn)程的地址空間邏輯上可以分成兩個局部:內(nèi)核代碼和數(shù)據(jù)所在的地址空間稱作內(nèi)核空間;而用戶程序代碼和數(shù)據(jù)所占據(jù)的地址空間稱為用戶空間。當(dāng)執(zhí)行到內(nèi)核空間的代碼時,我們稱程序處于內(nèi)核態(tài),當(dāng)程序執(zhí)行到用戶空間代碼時,我們稱程序處于用戶態(tài)。

程序執(zhí)行在用戶模式下,它們不能直接訪問內(nèi)核態(tài)的數(shù)據(jù),也不能直接對硬件進(jìn)行操作。它們只能通過內(nèi)核提供的標(biāo)準(zhǔn)編程接口即系統(tǒng)調(diào)用請求內(nèi)核效勞,并切換到內(nèi)核態(tài)執(zhí)行。當(dāng)核完成用戶請求,再將用戶程序返回到用戶態(tài)。課程設(shè)計提示(Cont.)?Linux與大局部UNIX內(nèi)核一樣是單內(nèi)核體系結(jié)構(gòu)〔monolithickernel〕的,即它是由幾個邏輯功能上不同的局部組合而成的大程序,其模塊間的通訊是通過直接調(diào)用其他模塊中的函數(shù)實現(xiàn)的。與之相應(yīng)的是微內(nèi)核體系結(jié)構(gòu)〔microkernel〕,這種內(nèi)核只包括同步元語、簡單的進(jìn)程調(diào)度以及進(jìn)程間通信機(jī)制等功能,其他像內(nèi)存管理、設(shè)備驅(qū)動和系統(tǒng)調(diào)用功能是由在微內(nèi)核之上的一些系統(tǒng)進(jìn)程實現(xiàn)的。所以微內(nèi)核相對于單內(nèi)核來說要慢,但微內(nèi)核有模塊化、易于移植到其他體系結(jié)構(gòu)以及占用內(nèi)存比單一內(nèi)核少等優(yōu)點。Linux使用“模塊”〔module〕來有效彌補單一內(nèi)核的缺點,同時防止了引入微內(nèi)核而帶來的性能損失。課程設(shè)計提示(Cont.)?Linux內(nèi)核與用戶進(jìn)程及硬件之間的關(guān)系圖課程設(shè)計提示(Cont.)?二.Linux系統(tǒng)發(fā)行版本RedhatLinuxRedHatfedoracoreSlackwareGentooDebianUbuntuMandriva推薦:FC4,FC5,FC6(2.6內(nèi)核)?課程設(shè)計提示(Cont.)?課程設(shè)計提示(Cont.)?三.Linux文件系統(tǒng)的目錄結(jié)構(gòu)/dev:dev是device〔設(shè)備〕的縮寫。這個目錄下存放物理設(shè)備和提供這些設(shè)備操作接口的文件,如/dev/hda代表第一個物理IDE硬盤。/etc:這個目錄用來存放系統(tǒng)管理所需要的配置文件和子目錄。〔如fstab文件〕/lib:這個目錄里存放著系統(tǒng)最根本的動態(tài)鏈接共享庫,幾乎所有的應(yīng)用程序都需要用到這些共享庫。/usr:這是最龐大的目錄,我們要用到的應(yīng)用程序和文件幾乎都存放在這個目錄下。其中包含以下子目錄:1)/usr/include:Linux下開發(fā)和編譯應(yīng)用程序需要的頭文件;2)/usr/lib:存放一些常用的編程語言動態(tài)鏈接共享庫和靜態(tài)檔案庫;3)/usr/local:這是提供給一般用戶的目錄,在這里安裝軟件最適合;4)/usr/man:幫助文檔的存放目錄;5)/usr/src:Linux的源代碼在這個目錄下。課程設(shè)計提示(Cont.)?四.Linux內(nèi)核源代碼的文件組織Linux核心源代碼位于/usr/src/linux下,可以通過版本號區(qū)分內(nèi)核是穩(wěn)定版本還是開發(fā)測試版本。每個版本號都由點號分隔的三個數(shù)組成〔如〕。第二個數(shù)是偶數(shù)表示是穩(wěn)定的版本,否那么是開發(fā)測試版本。

核心源程序的文件按樹形結(jié)構(gòu)進(jìn)行組織,簡要介紹目錄結(jié)構(gòu)如下:課程設(shè)計提示(Cont.)?1)arch:arch子目錄包括了所有和CPU類型相關(guān)的核心代碼。它的每一個子目錄都代表一種支持的CPU類型,例如i386就是關(guān)于intelcpu及與之相兼容的體系結(jié)構(gòu)的子目錄,PC機(jī)一般都基于此目錄;2)drivers:放置系統(tǒng)所有的設(shè)備驅(qū)動程序,包括各種塊設(shè)備和字符設(shè)備的驅(qū)動程序;每種驅(qū)動程序又各占用一個子目錄,如/block下為塊設(shè)備驅(qū)動程序;3)include:include子目錄包括編譯核心所需要的大局部頭文件。與平臺無關(guān)的頭文件在include/linux子目錄下,與intelcpu相關(guān)的頭文件在include/asm-i386等子目錄下;課程設(shè)計提示(Cont.)?4)init:這個目錄包含核心的初始化代碼(注:不是系統(tǒng)的引導(dǎo)代碼),包含兩個文件main.c和version.c,這是研究核心如何工作的一個非常好的起點;5)mm:這個目錄包括所有獨立于cpu體系結(jié)構(gòu)的內(nèi)存管理代碼,如頁式存儲管理中內(nèi)存的分配和釋放等,而和體系結(jié)構(gòu)相關(guān)的內(nèi)存管理代碼那么位于arch/*/mm/;6)kernel:主要的核心代碼,此目錄下的文件實現(xiàn)了大多數(shù)Linux系統(tǒng)的內(nèi)核函數(shù),其中最重要的文件當(dāng)屬進(jìn)程調(diào)度sched.c,同樣,和體系結(jié)構(gòu)相關(guān)的代碼在arch/*/kernel中。課程設(shè)計提示(Cont.)?五.Linux/Unix終端圖形庫curses簡介介于簡單的文本行程序和全圖形化XWindow系統(tǒng)程序之間的過渡;提供高級的程序設(shè)計接口,方便繪制屏幕并自動處理終端控制的問題;〔如vi等全屏幕程序〕本次使用的是ncurses函數(shù)庫,專門為Linux設(shè)計的自由軟件函數(shù)庫,具有某些curses庫的擴(kuò)展功能。課程設(shè)計提示(Cont.)?1.Curses圖形庫的使用必須包含頭文件curses.h編譯命令gcctest.c–otest–lcurses或者gcc–I/usr/include/ncursestest.c–otest–lcurses課程設(shè)計提示(Cont.)?3)實例程序#include<curses.h>intmain()?{ initscr();

box(stdscr,ACS_VLINE,ACS_HLINE);

/*drawabox*/

move(LINES/2,COLS/2);

/*movethecursortothecenter*/

waddstr(stdscr,"Hello,world!");

refresh();

getch();

endwin();

return0;}課程設(shè)計提示(Cont.)?課程設(shè)計提示(Cont.)?2.注意1)在終端使用的屏幕模式是基于文本的。所以在開始使用curses前,需要用initscr()函數(shù)初始化屏幕。對應(yīng)的,程序結(jié)束需要調(diào)用endwin();函數(shù)來關(guān)閉curses狀態(tài)。2)屏幕分物理屏幕(我們所看到的)和邏輯屏幕(在內(nèi)存中的),我們調(diào)用函數(shù)時修改的是邏輯屏幕,它不會在當(dāng)前物理屏幕上顯示出來。所以現(xiàn)在屏幕上還是什么也沒有,需要調(diào)用refresh()把我們對邏輯屏幕的改動在物理屏幕(顯示器)上顯示出來。六.進(jìn)程并發(fā)fork()系統(tǒng)調(diào)用:把自己復(fù)制給子進(jìn)程,即新創(chuàng)立的子進(jìn)程是父進(jìn)程的一個副本。一旦調(diào)用fork()創(chuàng)立了子進(jìn)程,它將執(zhí)行它后面的所有語句。if〔pid==0〕的程序段被子進(jìn)程執(zhí)行,if(pid>0)的程序段被父進(jìn)程執(zhí)行,不加if語句控制的程序段,父子進(jìn)程都會執(zhí)行。子進(jìn)程調(diào)用exit來自我終止,進(jìn)入僵死狀態(tài),仍然保存task_struct結(jié)構(gòu)。課程設(shè)計提示(Cont.)?子進(jìn)程可以調(diào)用exec函數(shù),用一個新的程序來覆蓋子進(jìn)程的內(nèi)容空間。該調(diào)用不返回。課程設(shè)計提示(Cont.)?七.添加Linux系統(tǒng)調(diào)用1.Linux系統(tǒng)調(diào)用機(jī)制Linux系統(tǒng)中,系統(tǒng)調(diào)用是作為一種異常類型實現(xiàn)的,它將執(zhí)行相應(yīng)的機(jī)器代碼指令來產(chǎn)生異常信號。系統(tǒng)自動地切換為核心態(tài),并安排異常處理程序的執(zhí)行。系統(tǒng)調(diào)用完成,系統(tǒng)執(zhí)行另一組特征指令〔iret指令〕將系統(tǒng)返回到用戶態(tài),控制權(quán)返回給進(jìn)程。Linux用來實現(xiàn)系統(tǒng)調(diào)用異常的實際指令是:int$0x80課程設(shè)計提示(Cont.)?getpid()系統(tǒng)調(diào)用過程課程設(shè)計提示(Cont.)?2.Linux系統(tǒng)調(diào)用涉及的內(nèi)核代碼

系統(tǒng)調(diào)用處理函數(shù)名以“sys_”開頭,后跟該系統(tǒng)調(diào)用的名字。例如,系統(tǒng)調(diào)用fork()的處理函數(shù)是sys_fork()(見kernel/fork.c),文件include/asm/unisted.h為每個系統(tǒng)調(diào)用規(guī)定了唯一的編號。假設(shè)用name表示系統(tǒng)調(diào)用的名稱,系統(tǒng)調(diào)用號_NR_name。以系統(tǒng)調(diào)用號_NR_name作為下標(biāo),系統(tǒng)調(diào)用表sys_call_table(見arch/i386/kernel/entry.S)中對應(yīng)表項的內(nèi)容,正好是該系統(tǒng)調(diào)用的處理函數(shù)sys_name的入口地址。系統(tǒng)調(diào)用表sys_call_table記錄了各sys_name函數(shù)在表中的位置,課程設(shè)計提示(Cont.)?3.系統(tǒng)調(diào)用的過程總結(jié)(1)系統(tǒng)調(diào)用初始化:在traps.c中,系統(tǒng)在初始化程序trap_init()?中,通過調(diào)用set_system_gate(0x80,*system_call)完成中斷描述表的填充。這樣當(dāng)每次用戶執(zhí)行指令int0x80時,系統(tǒng)能把控制轉(zhuǎn)移到entry.S中的函數(shù)中去。

(2)系統(tǒng)調(diào)用執(zhí)行:system_call會根據(jù)用戶傳進(jìn)來系統(tǒng)調(diào)用號,在系統(tǒng)調(diào)用表system_call_table中尋找到相應(yīng)偏移地址的函數(shù),進(jìn)行相應(yīng)的處理。當(dāng)然在這個過程之前,要保存環(huán)境〔SAVE_ALL〕。

(3)系統(tǒng)調(diào)用的返回:系統(tǒng)調(diào)用處理完畢后,通過ret_from_sys_call返回。返回之前,程序會檢查一些變量,相應(yīng)地返回。不一定是返回到用戶進(jìn)程。真正返回到用戶空間時,要恢復(fù)環(huán)境〔RESTORE_ALL〕。課程設(shè)計提示(Cont.)?4.添加系統(tǒng)功能調(diào)用的實現(xiàn)方式要求采用編譯內(nèi)核的方式,把新的系統(tǒng)調(diào)用靜態(tài)地參加內(nèi)核。不能使用插入模塊的方式。課程設(shè)計提示(Cont.)?5.實現(xiàn)步驟1)在linux/kernel/sys.c中添加源代碼asmlinkageintsys_mySysCall(arg1,arg2…){……}Note:一定要有asmlinkage限定詞,通知編譯器僅從棧中取參數(shù)。2)定義系統(tǒng)調(diào)用號,在文件include/asm-i386/unistd.h中添加:#define__NR_mySysCall

XX

并修改:#define__NR_syscallsXX+1Note:一般為原系統(tǒng)調(diào)用號最大值加1,注意更新總的系統(tǒng)調(diào)用數(shù)3)修改系統(tǒng)調(diào)用表,在/arch/i386/kernel/下的entry.S或

syscall_table.S中添加:.longSYMBOL_NAME(sys_mySysCall)或 .longsys_mysyscall課程設(shè)計提示(Cont.)?

課程設(shè)計提示(Cont.)

4)重新編譯內(nèi)核并啟動新內(nèi)核5)編寫測試程序使用添加的系統(tǒng)調(diào)用函數(shù)6.注意

1)不能簡單套用第一題中的文件拷貝程序。系統(tǒng)調(diào)用是在內(nèi)核態(tài)運行的,所以只能使用內(nèi)核中定義的函數(shù)。在相應(yīng)的文件讀寫系統(tǒng)調(diào)用函數(shù)前加上sys_前綴就是相應(yīng)功能的內(nèi)核函數(shù)。內(nèi)核文件系統(tǒng)提供的文件讀寫函數(shù),期望是對用戶態(tài)程序效勞的,所以它會驗證讀寫緩沖區(qū)不超過用戶空間的上限。但現(xiàn)在內(nèi)核中要讀寫文件,緩沖區(qū)在內(nèi)核中即地址會超過用戶空間上限。所以應(yīng)該在調(diào)用文件讀寫內(nèi)核函數(shù)前把內(nèi)核空間包含在用戶空間可訪問的范圍內(nèi),并在調(diào)用返回后復(fù)原。實現(xiàn)方法是使用宏:get_fs()、set_fs()//獲取和設(shè)置用戶空間范圍get_ds()//獲取內(nèi)核空間范圍課程設(shè)計提示(Cont.)?編寫內(nèi)核程序時會用到的一些函數(shù):打印輸出函數(shù):printk()?用戶空間與內(nèi)核空間數(shù)據(jù)傳遞函數(shù):copy_from_user()/copy_to_user()?get_user()/put_user()?內(nèi)核態(tài)動態(tài)內(nèi)存分配函數(shù):kmalloc()/kfree()?

課程設(shè)計提示(Cont.)?2)在文件/usr/src/linux/arch/i386/kernel/syscall_table.S或entry.S中添加新的內(nèi)核函數(shù)的指針時,.longSYMBOL_NAME(sys_XXX)?必須加到所定義系統(tǒng)調(diào)用號對應(yīng)的那一行上。3)測試程序必須添加上定義系統(tǒng)調(diào)用號的那個宏,即#define__NR_nameNNN,或者將include/asm-i386/unistd.h包含到測試程序里面,同時要使用宏:_syscallX(returntype,name,type1,arg1,…),該宏是頭文件linux/unistd.h聲明。這樣測試程序才能找到新添加的系統(tǒng)調(diào)用。調(diào)用時使用新的系統(tǒng)調(diào)用的函數(shù)名。新版本的C庫中沒有宏_syscallX(),可以使用syscall()函數(shù),在文件sys/syscall.h中聲明。該函數(shù)至少要提供一個參數(shù),即系統(tǒng)調(diào)用號,假設(shè)系統(tǒng)調(diào)用函數(shù)有其他參數(shù),那么也要在syscall()函數(shù)的調(diào)用中逐一提供。課程設(shè)計提示(Cont.)?4)測試程序中必須定義一定大小的緩沖區(qū),供系統(tǒng)調(diào)用函數(shù)讀寫使用,否那么會出現(xiàn)段錯誤。5〕當(dāng)用戶程序中調(diào)用的系統(tǒng)調(diào)用的名字為:mysyscall時:系統(tǒng)調(diào)用的編號名字:__NR_mysyscall;內(nèi)核中系統(tǒng)調(diào)用的實現(xiàn)程序的名字:sys_mysyscall。課程設(shè)計提示(Cont.)?7.編譯內(nèi)核步驟(2.6內(nèi)核下的方法)?1)進(jìn)入核心源代碼目錄,去除目錄下所有配置文件和先前生成核心時產(chǎn)生的中間文件

cd/usr/src/linuxmakeclean課程設(shè)計提示(Cont.)?2)配置內(nèi)核

makeconfig基于文本的傳統(tǒng)配置界面makemenuconfig基于文本的菜單形式配置界面makexconfig基于圖形窗口模式的配置界面makeoldconfig使用原來的配置或作小的修改選擇一個配置命令,根據(jù)自己的要求進(jìn)行配置。

對每個配置選項,有三種選擇:“Y”——將該功能編譯進(jìn)內(nèi)核“N”——不將該功能編譯進(jìn)內(nèi)核“M”——將該功能編譯成可動態(tài)載入的內(nèi)核模塊課程設(shè)計提示(Cont.)?3)創(chuàng)立內(nèi)核和模塊make

安裝內(nèi)核模塊makemodules_install把編譯生成的模塊,移動到系統(tǒng)標(biāo)準(zhǔn)目錄下。〔〕安裝內(nèi)核makeinstall移動內(nèi)核映象文件到/boot/grub/,修改grub的啟動配置文件以及生成initrd.img等。課程設(shè)計提示(Cont.)?八.Linux設(shè)備驅(qū)動程序1.Linux設(shè)備驅(qū)動的概念設(shè)備驅(qū)動程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口,它為應(yīng)用程序屏蔽了硬件的細(xì)節(jié)。在應(yīng)用程序看來,硬件設(shè)備只是一個設(shè)備文件,應(yīng)用程序可以象操作普通文件一樣對硬件設(shè)備進(jìn)行操作。設(shè)備驅(qū)動程序是內(nèi)核的一局部,它完成以下的功能:〔1〕對設(shè)備初始化和釋放;〔2〕把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù);〔3〕讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)和回送應(yīng)用程序請求的數(shù)據(jù);〔4〕檢測和處理設(shè)備出現(xiàn)的錯誤。課程設(shè)計提示(Cont.)?在Linux操作系統(tǒng)下有兩類主要的設(shè)備類型,一種是字符設(shè)備,另一種是塊設(shè)備。在對字符設(shè)備發(fā)出讀/寫請求時,實際的硬件I/O一般就緊接著發(fā)生了,塊設(shè)備那么不然,它利用一塊系統(tǒng)內(nèi)存作緩沖區(qū),當(dāng)緩沖區(qū)的內(nèi)容能滿足用戶的要求,就返回請求的數(shù)據(jù),如果不能,就調(diào)用請求函數(shù)來進(jìn)行實際的I/O操作。塊設(shè)備是主要針對磁盤等慢速設(shè)備設(shè)計的,以免消耗過多的CPU時間來等待。

課程設(shè)計提示(Cont.)?

每個設(shè)備都有對應(yīng)的設(shè)備文件,文件屬性(c/b),表示是字符設(shè)備還是塊設(shè)備。另外每個文件都有兩個設(shè)備號,第一個是主設(shè)備號,標(biāo)識驅(qū)動程序,第二個是從設(shè)備號,標(biāo)識使用同一個設(shè)備驅(qū)動程序的不同的硬件設(shè)備,比方有兩個軟盤,就可以用從設(shè)備號來區(qū)分他們。設(shè)備文件的主設(shè)備號必須與設(shè)備驅(qū)動程序在登記時申請的主設(shè)備號一致,否那么用戶進(jìn)程將無法訪問到驅(qū)動程序。課程設(shè)計提示(Cont.)?2.設(shè)備驅(qū)動程序工作的根本原理

用戶進(jìn)程調(diào)用驅(qū)動程序時,系統(tǒng)進(jìn)入核心態(tài),這時不再是搶先式調(diào)度。也就是說,系統(tǒng)必須在你的驅(qū)動程序的子函數(shù)返回后才能進(jìn)行其他的工作。如果你的驅(qū)動程序陷入死循環(huán),你只有重新啟動機(jī)器了。由于用戶進(jìn)程是通過設(shè)備文件同硬件打交道,對設(shè)備文件的操作方式不外乎就是一些系統(tǒng)調(diào)用,如open,read,write,close.課程設(shè)計提示(Cont.)?3.設(shè)備號在內(nèi)核內(nèi)部的表示在內(nèi)核中,dev_t類型〔在<linux/types.h>中定義〕的變量用來保存設(shè)備編號——包括主設(shè)備號和次設(shè)備號。相關(guān)的宏:MAJOR(dev_tdev);//獲取設(shè)備的主設(shè)備號MINOR(dev_tdev);//獲取設(shè)備的次設(shè)備號MKDEV(intmajor,intminor);//把主次設(shè)備號轉(zhuǎn)換成dev_t類型課程設(shè)計提示(Cont.)?4.Linux系統(tǒng)實現(xiàn)驅(qū)動設(shè)備的功能的接口open接口:翻開設(shè)備準(zhǔn)備I/O操作。open子程序必須對將要進(jìn)行的I/O操作做好必要的準(zhǔn)備工作,如去除緩沖區(qū)等。close接口:關(guān)閉一個設(shè)備。當(dāng)最后一次使用設(shè)備終結(jié)后,調(diào)用close子程序。read接口:從設(shè)備上讀數(shù)據(jù)。write接口:往設(shè)備上寫數(shù)據(jù)。ioctl接口:執(zhí)行讀、寫之外的操作。select接口:檢查設(shè)備,看數(shù)據(jù)是否可讀或設(shè)備是否可用于寫數(shù)據(jù)。如果設(shè)備驅(qū)動程序沒有提供上述接口中的某一個,系統(tǒng)會用缺省的子程序來代替。對于不同的系統(tǒng),也還有一些其它的接口。課程設(shè)計提示(Cont.)?課程設(shè)計提示(Cont.)?int(*flush)(structfile*);int(*release)(structinode*,structfile*);int(*fsync)(structfile*,structdentry*,intdatasync);int(*fasync)(int,structfile*,int);int(*lock)(structfile*,int,structfile_lock*);ssize_t(*readv)(structfile*,conststructiovec*,unsignedlong,loff_t*);ssize_t(*writev)(structfile*,conststructiovec*,unsignedlong,loff_t*);ssize_t(*sendpage)(structfile*,structpage*,int,size_t,loff_t*,int);unsignedlong(*get_unmapped_area)(structfile*,unsignedlong,unsignedlong,unsignedlong,unsignedlong);

}#include</usr/src/linux/include/linux/fs.h>structfile_operations{

structmodule*owner;loff_t(*llseek)(structfile*,loff_t,int);ssize_t(*read)(structfile*,char*,size_t,loff_t*);

ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);int(*readdir)(structfile*,void*,filldir_t);unsignedint(*poll)(structfile*,structpoll_table_struct*);

int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);int(*mmap)(structfile*,structvm_area_struct*);int(*open)(structinode*,structfile*);5.設(shè)備驅(qū)動程序相關(guān)數(shù)據(jù)結(jié)構(gòu)課程設(shè)計提示(Cont.)?structfile結(jié)構(gòu)體代表一個翻開的文件,由內(nèi)核在open時創(chuàng)立,并傳遞給在該文件上進(jìn)行操作的所有函數(shù)。structfile{structfile_operations*f_op;……}structinode結(jié)構(gòu)體表示一個磁盤上的文件structinode{dev_ti_rdev;//真正的設(shè)備編號structcdev*i_cdev;//字符設(shè)備在內(nèi)核的內(nèi)部結(jié)構(gòu)……}6.Linux內(nèi)核模塊1)linux內(nèi)核是單一體系結(jié)構(gòu)的,引入了模塊機(jī)制,即動態(tài)地在內(nèi)核中添加或者刪除某些功能,以此增強內(nèi)核的可擴(kuò)展性。模塊一旦被插入內(nèi)核,可以像內(nèi)核其它局部一樣被使用。2)linux中的大局部驅(qū)動程序,是以模塊的形式編寫的,因而可以動態(tài)地加載和卸載。3)模塊的加載方式有兩種:一種是使用insmod命令手工加載,另一種是“按需裝入”,即在需要時自動加載,不需要時自動卸載,“按需裝入”需要運行modprobe程序。4)通過rmmod命令來卸載模塊。課程設(shè)計提示(Cont.)?7.Linux內(nèi)核模塊實現(xiàn)機(jī)制每一個內(nèi)核模塊必定包含兩個函數(shù):intinit_module()加載模塊時,調(diào)用它將本模塊插入內(nèi)核voidcleanup_module()卸載模塊時,調(diào)用它將本模塊從內(nèi)核中去除。注意:1.函數(shù)init_module〔〕在正常返回時,返回值應(yīng)為0,insmod在調(diào)用init_module〔〕后會檢查其返回值,假設(shè)為負(fù)值,那么不會加載模塊。2.可以為模塊的“開始”和“結(jié)束”函數(shù)起任意的名字,但要用宏module_init()和module_exit()指定且函數(shù)必須在宏的使用前定義。課程設(shè)計提示(Cont.)?8.以模塊方式實現(xiàn)設(shè)備驅(qū)動程序的方法〔1〕實現(xiàn)驅(qū)動程序的注冊與卸載 init_module()中實現(xiàn)設(shè)備注冊和相關(guān)數(shù)據(jù)結(jié)構(gòu)的申請;cleanup_module()中實現(xiàn)設(shè)備卸載和相關(guān)數(shù)據(jù)結(jié)構(gòu)空間釋放。Linux2.4內(nèi)核下的實現(xiàn)方法如:字符設(shè)備注冊函數(shù)register_chrdev()?字符設(shè)備卸載函數(shù)unregister_chrdev()?intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);//major:希望獲得的設(shè)備號,為0時,系統(tǒng)選擇一個沒有被占用的設(shè)備號返回。//name:設(shè)備名//fops:登記驅(qū)動程序?qū)嶋H執(zhí)行操作的函數(shù)的指針//登記成功,返回設(shè)備的主設(shè)備號,否那么,返回一個負(fù)值課程設(shè)計提示(Cont.)?intunregister_chrdev(unsignedintmajor,constchar*name);

//卸載字符設(shè)備 //major:要卸載設(shè)備的主設(shè)備號 //name:設(shè)備名Linux2.6內(nèi)核下的實現(xiàn)方法1)設(shè)備號的申請靜態(tài)方法:intregister_chrdev_region(dev_first,unsignedintcount,char*name);first:要分配的設(shè)備編號范圍的起始值;count:所請求的連續(xù)設(shè)備編號的個數(shù);name:與之關(guān)聯(lián)的設(shè)備名稱。動態(tài)方法:intalloc_chrdev_region(dev_t*dev,unsignedintfirstminor,unsignedintcount,char*name);課程設(shè)計提示(Cont.)?課程設(shè)計提示(Cont.)?dev:僅用于輸出的參數(shù),成功時保存分配范圍的第一個編號;firstminor:要使用的被請求的第一個次設(shè)備號,常為0;count和name參數(shù)與上一函數(shù)的意義相同。2〕字符設(shè)備在內(nèi)核的內(nèi)部結(jié)構(gòu)structcdev的分配和初始化structcdev可以在驅(qū)動程序中靜態(tài)定義或者在運行過程中調(diào)用structcdev*cdev_alloc()動態(tài)分配。初始化:voidcdev_init(structcdev*cdev,structfile_operations*fops);cdev->owner=THIS_MODULEcdev->ops=&scull_fops;//驅(qū)動程序的操作函數(shù)集結(jié)構(gòu)注冊結(jié)構(gòu)體:intcdev_add(structcdev*dev,dev_tnum,unsignedintcount);課程設(shè)計提示(Cont.)?3〕卸載方法的實現(xiàn)設(shè)備驅(qū)動程序的移除:voidcdev_del(structcdev*dev);設(shè)備號的釋放:intunregister_chrdev_region(dev_tfirst,unsignedintcount);注意:先移除字符設(shè)備,再注銷設(shè)備號!課程設(shè)計提示(Cont.)?〔2〕驅(qū)動程序操作函數(shù)集的實現(xiàn)

loff_t(*llseek)(structfile*,loff_t,int);ssize_t(*read)(structfile*,char*,size_t,loff_t*);ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);int(*release)(structinode*,structfile*);int(*open)(structinode*,structfile*);int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);…………課程設(shè)計提示(Cont.)?〔3〕驅(qū)動模塊的編譯

1〕在源代碼所在目錄建立Makefile文件如下:obj-m+=modulename.omodulename-objs:=file1.ofile2.o2〕在Makefile所在的目錄運行make命令:make–C/usr/src/linux-x.y.zSUBDIRS=$PWDmodules注意:模塊建立所依賴的內(nèi)核版本〔通過查看內(nèi)核源代碼中的頂層makefile中的定義〕與使用模塊內(nèi)核版本〔uname–r〕應(yīng)該一致,否那么就不能加載成功!〔3〕加載模塊insmod-fmydev.ko通過lsmod檢查模塊是否加載成功〔4〕生成設(shè)備文件在文件/proc/devices中查找增加的設(shè)備對應(yīng)的主設(shè)備號假設(shè)為254,生成設(shè)備文件的相應(yīng)的命令是:mknod/dev/mydevc2540其中254為主設(shè)備號,0為從設(shè)備號,c表示字符設(shè)備課程設(shè)計提示(Cont.)?〔5〕編寫驅(qū)動測試程序測試驅(qū)動程序的實現(xiàn)voidmain()?{……open();//翻開設(shè)備read();//讀設(shè)備write();//寫設(shè)備close();//關(guān)閉設(shè)備……}當(dāng)不再使用時可通過rmmod命令來卸載設(shè)備。課程設(shè)計提示(Cont.)?九.Linux的系統(tǒng)狀態(tài)-/proc文件系統(tǒng)通過在命令行運行該程序,可獲取以下信息:

1)

CPU類型、型號、內(nèi)核版本,當(dāng)前CPU使用率2)從系統(tǒng)啟動至今的時間等3)內(nèi)存總?cè)萘考爱?dāng)前可用內(nèi)存量4)系統(tǒng)平均負(fù)載5)支持的文件系統(tǒng)類型6)系統(tǒng)正在使用的module信息

參照WINDOWS的任務(wù)管理器,實現(xiàn)其中的幾個功能。課程設(shè)計提示(Cont.)?1.proc文件系統(tǒng)簡介proc文件系統(tǒng)是一個偽文件系統(tǒng),它只存在內(nèi)存當(dāng)中,而不占用外存空間。它以文件系統(tǒng)的方式為訪問系統(tǒng)內(nèi)核數(shù)據(jù)的操作提供接口。用戶和應(yīng)用程序可以通過proc得到系統(tǒng)狀態(tài)信息,并可以改變內(nèi)核的某些參數(shù)。1〕系統(tǒng)信息與進(jìn)程無關(guān),隨系統(tǒng)配置的不同而不同。命令procinfo可以顯示這些文件的大量信息。2〕進(jìn)程信息系統(tǒng)中正在運行的每一個用戶級進(jìn)程的信息。

課程設(shè)計提示(Cont.)?系統(tǒng)信息(/proc目錄下局部目錄說明

)

/proc/cpuinfo

關(guān)于CPU信息/proc/filesystems

支持的文件系統(tǒng)

/proc/loadavg

負(fù)載均衡

/proc/meminfo

內(nèi)存信息

/proc/modules

加載模塊列表

/proc/mounts

加載的文件系統(tǒng)

/proc/version

內(nèi)核版本

/proc/uptime

系統(tǒng)正常運行時間/proc/cmd/line內(nèi)核啟動的命令行/proc/statCPU的使用情況、磁盤、頁面、交換 、所有的中斷、最后一次的啟動時間等。課程設(shè)計提示(Cont.)?進(jìn)程信息進(jìn)程目錄

系統(tǒng)中當(dāng)前運行的每一個進(jìn)程都有對應(yīng)的一個目錄在/proc下,以進(jìn)程的PID號為目錄名,它們是讀取進(jìn)程信息的接口。

Mem

進(jìn)程的內(nèi)存被利用情況

Stat

進(jìn)程狀態(tài)

Status

進(jìn)程當(dāng)前狀態(tài),以可讀的方式顯示出來Cwd

當(dāng)前工作目錄的鏈接

Exe

指向該進(jìn)程的執(zhí)行命令文件

課程設(shè)計提示(Cont.)?課程設(shè)計提示(Cont.)?2.開發(fā)工具1〕QT2〕GTKGTK(GIMPToolkit)是一個用于創(chuàng)立圖形用戶界面的多平臺工具。它包含有根本的控件和一些很復(fù)雜的的控件

溫馨提示

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

評論

0/150

提交評論