Modules

Modules

modules 的字面意思就是模組,在此指的是kernel modules;簡單來說,一個模組提供了一個功能,如 isofs、minix、nfs、lp 等等。傳統來講,模組化有兩個方法解決。設計者可以把各項功能分離到單獨的叫做執行緒的處理中去,或者是將核心以包含/排除一些功能的方式重新編譯。如果把功能分離到執行緒中去,那么核心就叫做“微核心”(micro-kernel),這種解決方法增加了執行緒間協調工作的通信開銷,就象名字暗示的那樣,這種解決方案的優點在於核心的大小。

基本信息

相關內容

Linux的解決方案是包含核心模組,這些模組是可以按需要隨時裝入和卸下的。這樣做可以使得核心的大小和通信量都達到最小。將模組從核心中獨立出來,不必預先『綁』在 kernel codes 中。這樣做有三種優點: 第一, 將來修改 kernel 時,不必全部重新 compile,可節省不少時間;第二, 若需要安裝新的 modules ,不必重新 compile kernel,只要插入 (通過insmode指令) 對應的 modules 即可;第三,減少核心對系統資源的占用,核心可以集中精力做最基本的事情,把一些擴展功能都交由modules實現。

模組也可以用來嘗試新的核心代碼而不需要每次都創建和重激活核心。但是,這樣做帶來的問題是:使用核心模組通常會輕微的增加性能和記憶體開支。一個可載入模組肯定會產生更多的代碼,這種代碼和額外的數據結構會占用更多一點的記憶體。另外因為間接訪問核心資源也讓模組的效率輕微降低。

模組化的思想已經被廣泛接受,主要的原因在於它可以擴展系統的功能,用戶可以靈活的配置系統。

載入方法

載入核心模組的方法有兩種。第一種使用insmod命令手工把它插入到核心。另一個更智慧型的方法是在需要的時候載入這個模組︰這叫做按需載入(demand loading)。當核心發現需要一個模組的時候,例如當用戶安裝一個不在核心的檔案系統的時候,核心會請求核心守護進程(kerneld)試圖載入合適的模組。

說到這裡就不能不提到核心守護進程kerneld了,它非常的聰明,能夠主動的把您需要的 modules 自動插入 kernel,將沒用到的 module 從kernel中清退。Kerneld由兩個獨立的部分構成:一部分工作於Linux的核心,負責向daemon傳送請求;另一部分工作於系統的用戶數據區,負責調入由核心請求指定的modules。若少了這個kerneld,就只能通過手工的方式,用insmode或modeprobe命令進行載入。

相關命令

與modules有關的命令有:

lsmode :列出已經被核心調入的模組

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 。完成之後,就編譯出一個沒有調入多餘模組的一個“乾淨的”核心映像檔案了。

手工載入方法

如果要以手工的方式載入模組, 建議最好使用 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模組載入成功了。

從記憶體中卸載

要卸載一個模組,首先用lsmod看看該模組是否確實已經載入上來,然後再做操作。除此之外,在碰到有依賴關係的模組時,從核心中卸載模組的過程與載入的過程恰好相反,它遵循“first in last out“的準則,即在一系列有依賴關係的模組中,必須先卸載最後載入進來的模組,最後卸載最先載入進來的模組。比如:如果要用 rmmod 移除正在使用中的模組(如上例,要卸載slhc, 但仍有PPP模組在使用它)會出現錯誤提示:Device or resource busy 。所以,在將PPP模組從記憶體中卸載後,才可能將slhc模組從記憶體中卸載。

總之,在卸載模組時,對於可能出現的模組間依賴性問題,Linux會給你提示足夠的信息,仔細查看這些信息,是能夠為你採取相應的操作並最終解決問題提供幫助的。

相關詞條

熱門詞條

聯絡我們