摘要:隨著嵌入式系統(tǒng)越來越廣泛的應用,Linux由于其自身的特點成為最受歡迎的嵌入式操作系統(tǒng)之一。該文闡述了Linux在嵌入式系統(tǒng)中的應用,重點介紹了Linux可加載內核模塊機制的基本原理和特點,以及編寫和加載內核模塊基本方法。
關鍵詞:嵌入式Linux內核;可加載
中圖分類號:TP316文獻標識碼:A文章編號:1009-3044(2008)26-1759-02
1 引言
一直以來,Linux操作系統(tǒng)以其開源性、穩(wěn)定性、安全性和漏洞少等優(yōu)良性能受到很多專業(yè)技術人員和公司的好評。而隨著嵌入式技術的發(fā)展及廣泛應用,Linux也由于其體積小、易于裁減、運行速度高和網(wǎng)絡性能良好等優(yōu)點成為嵌入式系統(tǒng)常用的操作系統(tǒng)之一,其中它的可加載內核模塊機制體現(xiàn)出了強大的功能。
2 Linux在嵌入式系統(tǒng)中的應用
嵌入式系統(tǒng)(Embedded Systems)是計算機的一種應用形式,它是指“以具體應用為中心,以計算機和信息技術的發(fā)展為基礎,將用戶所需的特點功能嵌入到產(chǎn)片、裝置或大型系統(tǒng)中,軟硬件可裁剪,從而能夠適應實際應用中對功能、可靠性、成本、體積、功耗等嚴格要求的專用計算機系統(tǒng)”。
正是由于嵌入式系統(tǒng)的應用特點,它對操作系統(tǒng)的要求并不同于一般的計算機系統(tǒng)。首先不同的宿主設備對嵌入式系統(tǒng)的要求都不一樣,因此嵌入式操作系統(tǒng)的功能要足夠強大,才能應付各種各樣不同場合的使用。同時由于系統(tǒng)資源非常有限,嵌入式操作系統(tǒng)又必須滿足精簡高效、占用資源少、響應速度快的特點。對于設備控制系統(tǒng),還有很重要的一個要求就是安全性和穩(wěn)定性要好,不允許在控制過程中經(jīng)常出現(xiàn)故障。
作為真正的32位操作系統(tǒng),Linux能夠很好地滿足嵌入式系統(tǒng)的需要。Linux的可加載內核模塊機制,支持設計人員可以根據(jù)不同嵌入式系統(tǒng)的需要,在不同的場合動態(tài)地選擇不同功能的內核模塊進行加載,內核可控制在100KB以內,這樣既可實現(xiàn)對不同需求的支持,又可以一定程度上保證系統(tǒng)內核的精簡,更好地實現(xiàn)操作系統(tǒng)功能專一而高效、高度節(jié)約資源、啟動速度快、節(jié)省開發(fā)成本等目標。
3 Linux可加載內核模塊機制
內核是Linux操作系統(tǒng)的核心,它負責管理系統(tǒng)的進程、內存、設備驅動程序、文件和網(wǎng)絡系統(tǒng),決定著系統(tǒng)的性能和穩(wěn)定性。
當Linux系統(tǒng)要實現(xiàn)對某種特定功能的支持時,可以把相應部分編譯到內核中,也可以把該部分編譯成模塊。如果編譯到內核中,在內核啟動時就可以自動支持相應部分的功能,但是會使內核變得龐大起來。如果編譯成模塊,就會生成對應的.ko文件,在需要使用時進行動態(tài)加載,這樣就不會使內核過分龐大。所以通常將經(jīng)常使用的部分直接編譯到內核中,偶爾需要使用的部分作為動態(tài)可加載內核模塊使用。
使用這種可加載內核模塊機制,內核模塊在需要時才加載到內核空間,不需要的時候可以釋放內存資源,這樣可以使內核更小更精簡,從而避免占據(jù)太多的內核空間。而當需要添加內核功能時,只需要添加編譯模塊代碼就可以了,不需要對基本內核進行頻繁的改動。
對這種可加載內核模塊的訪問主要是通過內核中的一個全局變量module_list實現(xiàn)的。每當用戶將一個模塊加載到內核中時,這個模塊就會被添加到由module_list形成的鏈表中。每當內核要使用到這個模塊所提供的函數(shù)時,內核就會檢索這個鏈表,找到相應的模塊中的函數(shù)或變量。內核將資源登記在符號表中,模塊可通過符號表使用核心資源。當模塊加載入內核時,系統(tǒng)將新加載模塊提供的資源和符號加到內核符號表中,通過這種通信機制,模塊之間可以實現(xiàn)資源的互相訪問。
4 內核模塊的實現(xiàn)
4.1 內核模塊的編寫
一個內核模塊至少要包含兩個函數(shù):用于加載時的模塊初始化函數(shù)init_module()和用于卸載的模塊結束函數(shù)cleanup_module()。實際應用中這兩個函數(shù)可以用任意函數(shù)名代替,但是必須在函數(shù)定義后用宏module_init()和module_exit()進行聲明,如:
static int __init lcd_init(void){…}
static void __exit lcd_exit(void){…}
module_init(lcd_init );
module_exit(lcd_exit);
4.2 內核模塊的編譯
編譯時需要通過一個Makefile文件來完成,其具體內容可參考下面生成lcd.ko的Makefile文件:
obj -m +=lcd.ko
KDIR :=/usr/arc/linux-2.6
PWD :=$(shell pwd)
Default:
$(MAKE) -C $(KDIR)SUBDIRS=$(PWD) modules
Makefile文件必須跟目標源文件放在同一個目錄下,執(zhí)行Make命令來完成該模塊的編譯,生成相應的.ko文件。
4.3 內核模塊的加載和卸載
當需要使用某個模塊的功能時,可以使用insmod命令進行加載。此時模塊從用戶態(tài)進入到內核態(tài),insmod程序找到要求加載的內核模塊,首先將其輸出符號在內核中的相應地址進行修改,然后為新模塊申請足夠的內核內存空間,并更新其符號表,然后內核調用模塊的初始化函數(shù)完成模塊的安裝。
模塊使用完后可以用rmmod命令卸載,此模塊占用的內核內存將被回收。但是內核中其他部分還在使用的模塊是不能被卸載的。
5 結束語
對于Linux的可加載內核模塊機制及應用,涉及到的知識非常廣泛,并不是這里簡單的幾句話就能夠深入分析清楚。本文在介紹了Linux內核機制的基本原理的基礎上,簡單說明了內核模塊的編寫和編譯過程,供廣大愛好者為更好地進一步學習Linux打下良好的基礎。
參考文獻:
[1] 陳莉君.深入分析Linux源碼[M].北京:中國電力出版社,2004.
[2] 李善平,劉文峰.Linux與嵌入式系統(tǒng)[M].北京:清華大學出版社,2003.
[3] 周應華.對Linux可加載內核模塊應用框架的研究[J].計算機系統(tǒng)應用,2007,(4):69-72,76.
[4] 陳剛,盧顯良.基于Linux-2.6內核模塊程序設計[J].福建電腦,2004,(6):16-17.
[5] 劉天華,陳梟.Linux可加載內核模塊機制的研究與應用[J].微計算機信息,2007,(20):55-56,134.