- 論壇徽章:
- 0
|
一、什么是 modules?
modules 的字面意思就是模塊,在此指的是 kernel modules;簡(jiǎn)單來說,一個(gè)模塊提供了一個(gè)功能,如
isofs、minix、nfs、lp
等等。傳統(tǒng)來講,模塊化有兩個(gè)方法解決:設(shè)計(jì)者可以把各項(xiàng)功能分離到單獨(dú)的叫做線程的處理中去,或者是將內(nèi)核以包含/排除一些功能的方式重新編譯。如果把
功能分離到線程中去,那么內(nèi)核就叫做“微內(nèi)核”(micro-kernel),這種解決方法增加了線程間協(xié)調(diào)工作的通信開銷。就象名字暗示的那樣,這種解
決方案的優(yōu)點(diǎn)在于內(nèi)核的大小。
Linux的解決方案是包含內(nèi)核模塊,這些模塊是可以按需要隨時(shí)裝入和卸下的。這樣做可以使得內(nèi)核的大小和通信量都達(dá)到最小。將模塊從內(nèi)核中獨(dú)立出
來,不必預(yù)先『綁』在 kernel codes 中。這樣做有三種優(yōu)點(diǎn): 第一, 將來修改 kernel
時(shí),不必全部重新compile,可節(jié)省不少時(shí)間;第二, 若需要安裝新的 modules ,不必重新 compile kernel,只要插入
(通過insmode指令) 對(duì)應(yīng)的 modules
即可;第三,減少內(nèi)核對(duì)系統(tǒng)資源的占用,內(nèi)核可以集中精力做最基本的事情,把一些擴(kuò)展功能都交由modules實(shí)現(xiàn)。
模塊也可以用來嘗試新的內(nèi)核代碼而不需要每次都創(chuàng)建和重激活內(nèi)核。但是,這樣做帶來的問題是:使用內(nèi)核模塊通常會(huì)輕微的增加性能和內(nèi)存開支。一個(gè)可加
載模塊肯定會(huì)產(chǎn)生更多的代碼,這種代碼和額外的數(shù)據(jù)結(jié)構(gòu)會(huì)占用更多一點(diǎn)的內(nèi)存。另外因?yàn)殚g接訪問內(nèi)核資源也讓模塊的效率輕微降低。
模塊化的思想已經(jīng)被廣泛接受,主要的原因在于它可以擴(kuò)展系統(tǒng)的功能,用戶可以靈活的配置系統(tǒng)。Apache也采取了這種功能擴(kuò)展方式,在本文中主要討論是內(nèi)核的模塊安裝與卸載,Apache模塊的安裝請(qǐng)參照Apapce的相關(guān)文檔。
二、如何加載模塊?
加載內(nèi)核模塊的方法有兩種。第一種使用insmod命令手工把它插入到內(nèi)核。另一個(gè)更智能的方法是在需要的時(shí)候加載這個(gè)模塊︰這叫做按需加載
(demand
loading)。當(dāng)內(nèi)核發(fā)現(xiàn)需要一個(gè)模塊的時(shí)候,例如當(dāng)用戶安裝一個(gè)不在內(nèi)核的文件系統(tǒng)的時(shí)候,內(nèi)核會(huì)請(qǐng)求內(nèi)核守護(hù)進(jìn)程(kerneld)試圖加載合適
的模塊。說到這里就不能不提到內(nèi)核守護(hù)進(jìn)程kerneld了,它非常的聰明,能夠主動(dòng)的把您需要的modules 自動(dòng)插入 kernel,將沒用到的
module
從kernel中清退。Kerneld由兩個(gè)獨(dú)立的部分構(gòu)成:一部分工作于Linux的內(nèi)核,負(fù)責(zé)向daemon發(fā)送請(qǐng)求;另一部分工作于系統(tǒng)的用戶數(shù)據(jù)
區(qū),負(fù)責(zé)調(diào)入由內(nèi)核請(qǐng)求指定的modules。若少了這個(gè)kerneld,就只能通過手工的方式,用insmode或modeprobe命令進(jìn)行加載。
三、modules的相關(guān)命令介紹
與modules有關(guān)的命令有:
引用:
lsmode :列出已經(jīng)被內(nèi)核調(diào)入的模塊
insmode:將某個(gè)module插入到內(nèi)核中
rmmod:將某個(gè)module從內(nèi)核中卸載
depmod: 生成依賴文件,告訴將來的 insmod 要從哪兒調(diào)入 modules。這個(gè)依賴文件就在/lib/modules/[您的kernel版本]/modules.dep。
Kerneld:負(fù)責(zé)自動(dòng)的將模塊調(diào)入內(nèi)核和把模塊從內(nèi)核中卸載。
四、編譯一個(gè)最小的Linux內(nèi)核
模塊一般用來支持那些不經(jīng)常使用的功能。例如,通常情況下你僅使用撥號(hào)網(wǎng)絡(luò),因此網(wǎng)絡(luò)功能并不是任何時(shí)候都需要的,那么就應(yīng)該使用可裝入的模塊來提供
這個(gè)功能。僅在你進(jìn)行撥號(hào)聯(lián)接的時(shí)候,該模塊才被裝入。而在你斷掉連接的時(shí)候它會(huì)被自動(dòng)卸下。這樣會(huì)使內(nèi)核使用內(nèi)存的量最小,減小系統(tǒng)的負(fù)荷。
當(dāng)然,那些象硬盤訪問這樣時(shí)時(shí)刻刻都需要的功能,則必須作在內(nèi)核里。如果你搭一臺(tái)網(wǎng)絡(luò)工作站或web服務(wù)器,那么網(wǎng)絡(luò)功能是時(shí)刻都需要的,你就應(yīng)該考
慮把網(wǎng)絡(luò)功能編譯到內(nèi)核里。另外一個(gè)方法是在啟動(dòng)的時(shí)候就裝入網(wǎng)絡(luò)模塊。這種方法的優(yōu)點(diǎn)是你不需要重新編譯內(nèi)核。而缺點(diǎn)是網(wǎng)絡(luò)功能不能特別高效。
按照以上的原則,我們首先列出一張清單,看看 kernel 中哪些選項(xiàng)是非有不可的,也就是說,這些東西是必須被編譯到內(nèi)核中的。將那些非必需的模塊剔除到內(nèi)核以外。
第一個(gè)是root所在的硬盤配置。哪果您的硬盤是IDE接口,就把 ide 的選項(xiàng)標(biāo)記下來。如果是SCSI接口,請(qǐng)把您的接口參數(shù)及 SCSI id 記標(biāo)下來。
第二個(gè)是選擇使用哪一個(gè)文件系統(tǒng)。Linux的默認(rèn)文件系統(tǒng)是是 ext2
,那么就一定要把它標(biāo)記下來。如果機(jī)器中還其它的操作系統(tǒng),如win98或windows
NT,您還會(huì)可能選擇FAT32或NTFS的支持,不過后面你可以通過手工加載的方式來加入新的模塊支持。
第三個(gè)是選擇Linux所支持的可執(zhí)行文件格式。這里有兩種格式可供選擇:
elf:這是當(dāng)前Linux普遍支持的可執(zhí)行文件格式,必須編譯到內(nèi)核中 。
a.out: 這是舊版的Linux的可執(zhí)行文件各函數(shù)庫(kù)的格式,如果你確認(rèn)肯定用不到這種格式的可執(zhí)行文件,那么就可以不把它編譯到內(nèi)核當(dāng)中。
以上這些內(nèi)容,是必須要編譯到內(nèi)核中的。其它的內(nèi)容凡是所有選項(xiàng)中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 。完成之后,就編譯出一個(gè)沒有調(diào)入多余模塊的一個(gè)“干凈的”內(nèi)核映像文件了。
五、如何手工加載Modules?
如果要以手工的方式加載模塊, 建議最好使用 modprobe, 因?yàn)樗梢越鉀Q模塊之間的依賴性問題,以聲卡的部分來說,以sound blaster 為例其總共有以下模塊:
引用:
sb 33652 0 (autoclean)
uart401 6160 0 (autoclean) [sb]
sound 56492 0 (autoclean) [sb uart401]
soundcore 2372 5 (autoclean) [sb sound]
這些模塊都要加載上來,整個(gè)聲卡才能工作,而且它們之間是有依賴性關(guān)系的。最核心的 soundcore必須首先裝入, 最后裝入sb。但一般人是不知道其先后順序的。因此, modprobe 就是用來解決這個(gè)問題用的。
通常我們只要 :modprobe sb
它就會(huì)自動(dòng)的找出 sb 用到的所有的模塊, 將它們一一 的加載進(jìn)來,故一般使用者就不用去傷腦筋了。
那么內(nèi)核是怎么知道這些模塊間的依賴性關(guān)系的呢?原來,在系統(tǒng)啟動(dòng)腳本里有一條'depmod -a'命令,會(huì)給系統(tǒng)中的所有可用的模塊創(chuàng)建一個(gè)依賴關(guān)系的列表。而 'modprobe module-name'會(huì)使用這個(gè)列表,在裝入指定的
模塊前先裝入那些事先裝入的模塊。如果在這個(gè)從屬列表中找不到'module-name'的話,它會(huì)給出相應(yīng)的出錯(cuò)信息。
但若使用 insmod, 它可不會(huì)自動(dòng)完成其它模塊的調(diào)入。比如說,我們要加入PPP模塊,用這個(gè)命令:
代碼:
root/root>insmod ppp
root/root>
如果操作成功,系統(tǒng)出現(xiàn)操作提示符。如果沒有成功,可能出現(xiàn)下列信息:
引用:
/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模塊沒有加載成功,錯(cuò)誤提示中的unresolved
symbol說明,PPP模塊所需要的一些模塊還沒有載入。錯(cuò)誤提示第一行的內(nèi)容是:slhc_init_Rsmp_1ca65fca
,這是哪個(gè)模塊?這其中可能需要一些經(jīng)驗(yàn)來做判斷,它是以slhc開頭的,就試試slhc吧。
代碼:
root/root>insmod slhc 一切正常,然后我們?cè)偌虞dPPP模塊
root/root>insmod ppp
root/root>
這回沒有什么返回信息,說明PPP模塊加載成功了。
六、從內(nèi)存中卸載一個(gè)Modules
要卸載一個(gè)模塊,首先用lsmod看看該模塊是否確實(shí)已經(jīng)加載上來,然后再做操作。除此之外,在碰到有依賴關(guān)系的模塊時(shí),從內(nèi)核中卸載模塊的過程與載
入的過程恰好相反,它遵循“first in last
out“的準(zhǔn)則,即在一系列有依賴關(guān)系的模塊中,必須先卸載最后加載進(jìn)來的模塊,最后卸載最先加載進(jìn)來的模塊。比如:如果要用 rmmod
移除正在使用中的模塊(如上例,要卸載slhc, 但仍有PPP模塊在使用它)會(huì)出現(xiàn)錯(cuò)誤提示:Device or resource busy
。所以,在將PPP模塊從內(nèi)存中卸載后,才可能將slhc模塊從內(nèi)存中卸載。
總之,在卸載模塊時(shí),對(duì)于可能出現(xiàn)的模塊間依賴性問題,Linux會(huì)給你提示足夠的信息,仔細(xì)查看這些信息,是能夠?yàn)槟悴扇∠鄳?yīng)的操作并最終解決問題提供幫助的。
本文來自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/3166/showart_24370.html |
|