Modules的概念及使用
2004-04-23 15:18 pm
作者:作者
來自:Linux知識寶庫
現載:http://www.douzhe.com/linuxtips/42.html
地址:無名
一、什麼是 modules?
modules 的字面意思就是模塊,在此指的是 kernel modules;簡單來說, 一個模塊提供
了一個功能,如 isofs、minix、nfs、lp 等等。傳統來講,模塊化有兩個方法解決: 設計者
可以把各項功能分離到單獨的叫做線程的處理中去, 或者是將內核以包含/排除一些功能的方
式重新編譯。如果把功能分離到線程中去,那麼內核就叫做“微內核”(micro-kernel),這種解
決方法增加了線程間協調工作的通信開銷。就象名字暗示的那樣,這種解決方案的優點在於內
核的大小。
linux的解決方案是包含內核模塊,這些模塊是可以按需要隨時裝入和卸下的。 這樣做可
以使得內核的大小和通信量都達到最小。將模塊從內核中獨立出來,不必預先『綁』在
kernel codes 中。這樣做有三種優點: 第一, 將來修改 kernel 時,不必全部重新compile,
可節省不少時間;第二, 若需要安裝新的 modules ,不必重新 compile kernel,只要插入
(通過insmode指令) 對應的 modules 即可;第三,減少內核對系統資源的占用, 內核可以集
中精力做最基本的事情,把一些擴展功能都交由modules實現。
模塊也可以用來嘗試新的內核代碼而不需要每次都創建和重激活內核。但是,這樣做帶來
的問題是:使用內核模塊通常會輕微的增加性能和內存開支。一個可加載模塊肯定會產生更多
的代碼,這種代碼和額外的數據結構會占用更多一點的內存。另外因為間接訪問內核資源也讓
模塊的效率輕微降低。
模塊化的思想已經被廣泛接受,主要的原因在於它可以擴展系統的功能,用戶可以靈活的
配置系統。Apache也采取了這種功能擴展方式,在本文中主要討論是內核的模塊安裝與卸載,
Apache模塊的安裝請參照Apapce的相關文檔。
二、如何加載模塊?
加載內核模塊的方法有兩種。第一種使用insmod命令手工把它插入到內核。另一個更智能
的方法是在需要的時候加載這個模塊︰這叫做按需加載(demand loading)。當內核發現需要
一個模塊的時候,例如當用戶安裝一個不在內核的文件系統的時候,內核會請求內核守護進程
(kerneld)試圖加載合適的模塊。說到這裡就不能不提到內核守護進程kerneld了,它非常的
聰明,能夠主動的把您需要的modules 自動插入 kernel, 將沒用到的 module 從kernel中清
退。Kerneld由兩個獨立的部分構成:一部分工作於linux的內核,負責向daemon發送請求;另
一部分工作於系統的用戶數據區,負責調入由內核請求指定的modules。若少了這個kerneld,
就只能通過手工的方式,用insmode或modeprobe命令進行加載。
三、modules的相關命令介紹
與modules有關的命令有:
lsmod : 列出已經被內核調入的模塊
insmod : 將某個module插入到內核中
rmmod :將某個module從內核中卸載
depmod : 生成依賴文件,告訴將來的 insmod 要從哪兒調入 modules。這個依賴文件就在
/lib/modules/[您的kernel版本]/modules.dep。
Kerneld:負責自動的將模塊調入內核和把模塊從內核中卸載。
四、編譯一個最小的linux內核
模塊一般用來支持那些不經常使用的功能。例如,通常情況下你僅使用撥號網絡,因此網
絡功能並不是任何時候都需要的,那麼就應該使用可裝入的模塊來提供這個功能。僅在你進行
撥號聯接的時候,該模塊才被裝入。而在你斷掉連接的時候它會被自動卸下。這樣會使內核使
用內存的量最小,減小系統的負荷。
當然,那些象硬盤訪問這樣時時刻刻都需要的功能,則必須作在內核裡。如果你搭一台網
絡工作站或web服務器,那麼網絡功能是時刻都需要的, 你就應該考慮把網絡功能編譯到內核
裡。另外一個方法是在啟動的時候就裝入網絡模塊。這種方法的優點是你不需要重新編譯內核。
而缺點是網絡功能不能特別高效。
按照以上的原則,我們首先列出一張清單,看看 kernel 中哪些選項是非有不可的,也就
是說,這些東西是必須被編譯到內核中的。將那些非必需的模塊剔除到內核以外。
第一個是root所在的硬盤配置。哪果您的硬盤是IDE接口,就把 ide 的選項標記下來。如
果是SCSI接口,請把您的接口參數及 SCSI id 記標下來。
第二個是選擇使用哪一個文件系統。linux的默認文件系統是是 ext2 , 那麼就一定要把
它標記下來。如果機器中還其它的操作系統,如win98或windows NT,您還會可能選擇FAT32或
NTFS的支持,不過後面你可以通過手工加載的方式來加入新的模塊支持。
第三個是選擇linux所支持的可執行文件格式。這裡有兩種格式可供選擇:
elf:這是當前linux普遍支持的可執行文件格式,必須編譯到內核中 。
a.out: 這是舊版的linux的可執行文件各函數庫的格式, 如果你確認肯定用不到這種格
式的可執行文件,那麼就可以不把它編譯到內核當中。
以上這些內容,是必須要編譯到內核中的。其它的內容凡是所有選項中m提示的,都選擇m,
這樣可以通過手工的方式添加該模塊。
** Loadable module support*Enable loadable module support (CONFIG_MODULES) [Y/n/?]Set version
information on all symbols for modules (CONFIG_MODVERSIONS) [N/y/?]Kernel daemon support (e.g.
autoload of modules) (CONFIG_KERNELD) [Y/n/?]
分別回答 Y,N,Y 。其中 CONFIG_KERNELD 的 default 值是 N, 所以要注意選擇Y。
make config 完後,仍舊是 make dep; make clean。
接下來要 make zlilo 或 make zImage。
然後 make modules ; make modules_install 。完成之後, 就編譯出一個沒有調入多余
模塊的一個“干淨的”內核映像文件了。
五、如何手工加載Modules?
如果要以手工的方式加載模塊, 建議最好使用 modprobe, 因為它可以解決模塊之間的依
賴性問題,以聲卡的部分來說,以sound blaster 為例其總共有以下模塊:
sb 33652 0 (autoclean)
uart401 6160 0 (autoclean) [sb]
sound 56492 0 (autoclean) [sb uart401]
soundcore 2372 5 (autoclean) [sb sound]
這些模塊都要加載上來,整個聲卡才能工作,而且它們之間是有依賴性關系的。最核心的
soundcore必須首先裝入, 最後裝入sb。但一般人是不知道其先後順序的。因此, modprobe
就是用來解決這個問題用的。
通常我們只要
modprobe sb
它就會自動的找出 sb 用到的所有的模塊, 將它們一一的加載進來,故一般使用者就不用
去傷腦筋了。
那麼內核是怎麼知道這些模塊間的依賴性關系的呢?原來,在系統啟動腳本裡有一條
'depmod -a'命令,會給系統中的所有可用的模塊創建一個依賴關系的列表。而
'modprobe module-name'會使用這個列表,在裝入指定的
模塊前先裝入那些事先裝入的模塊。如果在這個從屬列表中找不到'module-name'的話,
它會給出相應的出錯信息。
但若使用 insmod, 它可不會自動完成其它模塊的調入。比如說,我們要加入PPP模塊,用這個命令:
root/root>insmod ppp
root/root>
如果操作成功,系統出現操作提示符。如果沒有成功,可能出現下列信息:
/lib/modules/2.2.10.net/ppp.o: unresolved symbol slhc_init_Rsmp_1ca65fca
/lib/modules/2.2.10/net/ppp.o: unresolved symbol slhc_compress_Rsmp_cfd3a418
/lib/modules/2.2.10/net/ppp.o: unresolved symbol slhc_free_Rsmp_b99033d9
/lib/modules/2.2.10/net/ppp.o: unresolved symbol slhc_toss_Rsmp_a152cec0
/lib/modules/2.2.10/net/ppp.o: unresolved symbol slhc_remember_Rsmp_07972313
/lib/modules/2.2.10/net/ppp.o: unresolved symbol slhc_uncompress_Rsmp_3bb36b01
[root /root]#
這說明,PPP模塊沒有加載成功,錯誤提示中的unresolved symbol說明, PPP模塊所需要
的一些模塊還沒有載入。錯誤提示第一行的內容是:slhc_init_Rsmp_1ca65fca ,這是哪個模
塊?這其中可能需要一些經驗來做判斷,它是以slhc開頭的,就試試slhc吧。
root/root>insmod slhc 一切正常,然後我們再加載PPP模塊
root/root>insmod ppp
root/root>
這回沒有什麼返回信息,說明PPP模塊加載成功了。
六、從內存中卸載一個Modules.
要卸載一個模塊,首先用lsmod看看該模塊是否確實已經加載上來,然後再做操作。 除此
之外,在碰到有依賴關系的模塊時,從內核中卸載模塊的過程與載入的過程恰好相反,它遵循
“first in last out“的准則,即在一系列有依賴關系的模塊中, 必須先卸載最後加載進來的
模塊,最後卸載最先加載進來的模塊。比如:如果要用 rmmod 移除正在使用中的模塊(如上例,
要卸載slhc, 但仍有PPP模塊在使用它)會出現錯誤提示:Device or resource busy 。所以,
在將PPP模塊從內存中卸載後,才可能將slhc模塊從內存中卸載。
總之,在卸載模塊時,對於可能出現的模塊間依賴性問題,linux會給你提示足夠的信息,
仔細查看這些信息,是能夠為你采取相應的操作並最終解決問題提供幫助的。