局域網(wǎng)網(wǎng)站建設(shè)需要什么條件市場推廣和銷售的區(qū)別
訪問【W(wǎng)RITE-BUG數(shù)字空間】_[內(nèi)附完整源碼和文檔]
1 總體設(shè)計(jì)思路
Linux內(nèi)核是單體式結(jié)構(gòu),相對于微內(nèi)核結(jié)構(gòu)而言,其運(yùn)行效率高,但是系統(tǒng)的可維護(hù)性和可擴(kuò)展性較差。為此,Linux提供了內(nèi)核模塊(module)機(jī)制,它不僅可以彌補(bǔ)單體式內(nèi)核相對于微內(nèi)核的一些不足,而不影響系統(tǒng)性能。內(nèi)核模塊的全稱是動(dòng)態(tài)可加載內(nèi)核模塊(Loadabe Kernel Module,KLM),簡稱為模塊。模塊是一個(gè)目標(biāo)文件,能完成某種獨(dú)立的功能,但其自身不是一個(gè)獨(dú)立的進(jìn)程,不能單獨(dú)運(yùn)行,可以動(dòng)態(tài)載入內(nèi)核,使其成為內(nèi)核代碼的一部分,與其他內(nèi)核代碼的地位完全相同,當(dāng)不需要某模塊功能時(shí),可以動(dòng)態(tài)卸載。實(shí)際上,Linux中大多數(shù)設(shè)備驅(qū)動(dòng)程序或文件系統(tǒng)都以模塊方式實(shí)現(xiàn),因?yàn)樗鼈償?shù)目繁多,體積龐大,不適合直接編譯在內(nèi)核中,而是通過模塊機(jī)制,需要時(shí)臨時(shí)加載。使用模塊機(jī)制的另一個(gè)好處是,修改模塊代碼后只需要重新編譯和加載模塊,不必重新編譯整個(gè)內(nèi)核和引導(dǎo)系統(tǒng),減少了更新系統(tǒng)功能的復(fù)雜度。
一個(gè)模塊通常有一組函數(shù)和數(shù)據(jù)結(jié)構(gòu)組成,用來實(shí)現(xiàn)某種功能,如實(shí)現(xiàn)一種文件系統(tǒng)、一個(gè)驅(qū)動(dòng)模塊或其他內(nèi)核上層的功能。模塊自身不是一個(gè)獨(dú)立的進(jìn)程,當(dāng)前集成運(yùn)行過程中調(diào)用到模塊代碼時(shí),可以認(rèn)為該段代碼就代表當(dāng)前進(jìn)程在核心態(tài)運(yùn)行。
模塊編程可以使用內(nèi)核的一些全局變量和函數(shù),內(nèi)核符號表就是用來存放所有模塊都可以訪問的符號及相應(yīng)地址的表,存放在/proc/kallsyms文件中,可以使用“cat /proc/kallsyms”命令查看當(dāng)前環(huán)境下導(dǎo)出的內(nèi)核符號。
通常情況下,一個(gè)模塊只需實(shí)現(xiàn)自己的功能,而無需導(dǎo)出任何符號;但如果其他模塊需要調(diào)用這個(gè)模塊的函數(shù)或數(shù)據(jù)結(jié)構(gòu)時(shí),該模塊也可以導(dǎo)出符號。這樣,其他模塊可以使用由該模塊導(dǎo)出的符號,利用現(xiàn)成的代碼實(shí)現(xiàn)更加復(fù)雜的功能,這種技術(shù)也被稱為模塊層疊技術(shù),當(dāng)前已經(jīng)使用在很多主流的內(nèi)核源代碼中。
2 主要函數(shù)的接口設(shè)計(jì)
module1:設(shè)計(jì)一個(gè)模塊,要求列出系統(tǒng)中所有內(nèi)核線程的程序名、PID、進(jìn)程狀態(tài)、進(jìn)程優(yōu)先級、父進(jìn)程的PID
module2:設(shè)計(jì)一個(gè)帶參數(shù)的模塊,其參數(shù)為某個(gè)進(jìn)程的PID號,模塊的功能時(shí)列出該進(jìn)程的家族信息,包括父進(jìn)程、兄弟進(jìn)程和子進(jìn)程的程序名、PID號、進(jìn)程狀態(tài)
模塊中包括兩個(gè)函數(shù):
定義module_init()函數(shù)初始化模塊、定義module_exit()函數(shù)卸載模塊
對于需要傳遞參數(shù)的模塊,我們使用module_param()來傳遞參數(shù)
task_struct是Linux內(nèi)核的一種數(shù)據(jù)結(jié)構(gòu),它會被裝載到RAM中并且包含著進(jìn)程的信息。每個(gè)進(jìn)程都把它的信息放在 task_struct 這個(gè)數(shù)據(jù)結(jié)構(gòu)體,task_struct 包含了這些內(nèi)容:
標(biāo)示符 : 描述本進(jìn)程的唯一標(biāo)識符,用來區(qū)別其他進(jìn)程
狀態(tài) :任務(wù)狀態(tài),退出代碼,退出信號等
優(yōu)先級 :相對于其他進(jìn)程的優(yōu)先級
程序計(jì)數(shù)器:程序中即將被執(zhí)行的下一條指令的地址
內(nèi)存指針:包括程序代碼和進(jìn)程相關(guān)數(shù)據(jù)的指針,還有和其他進(jìn)程共享的內(nèi)存塊的指針
上下文數(shù)據(jù):進(jìn)程執(zhí)行時(shí)處理器的寄存器中的數(shù)據(jù)
I/O狀態(tài)信息:包括顯示的I/O請求,分配給進(jìn)程的I/O設(shè)備和被進(jìn)程使用的文件列表
記賬信息:可能包括處理器時(shí)間總和,使用的時(shí)鐘數(shù)總和,時(shí)間限制,記賬號等
有關(guān)進(jìn)程信息還有以下三點(diǎn)需要了解:
保存進(jìn)程信息的數(shù)據(jù)結(jié)構(gòu)叫做 task_struct,可以在 include/linux/sched.h 中找到它
所有運(yùn)行在系統(tǒng)中的進(jìn)程都以 task_struct 鏈表的形式存在內(nèi)核中
進(jìn)程的信息可以通過 /proc 系統(tǒng)文件夾查看。要獲取PID為400的進(jìn)程信息,你需要查看 /proc/400 這個(gè)文件夾。大多數(shù)進(jìn)程信息同樣可以使用top和ps這些用戶級工具來獲取