標籤: 暫無標籤

Modules的字面意思就是模塊,在此指的是kernel modules;簡單來說,一個模塊提供了一個功能。

1 Modules -什麼是 modules?

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

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

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

  模塊化的思想已經被廣泛接受,主要的原因在於它可以擴展系統的功能,用戶可以靈活的配置系統。Apache也採取了這種功能擴展方式,在本文中主要討論是內核的模塊安裝與卸載,Apache模塊的安裝請參照Apapce的相關文檔。

2 Modules -如何載入模塊?

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

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

3 Modules -modules的相關命令介紹

  與modules有關的命令有:

  lsmode :列出已經被內核調入的模塊

  insmode:將某個module插入到內核中

  rmmod:將某個module從內核中卸載

  depmod: 生成依賴文件,告訴將來的 insmod 要從哪兒調入 modules。這個依賴 文件就在/lib/modules/[您的kernel版本]/modules.dep。

  Kerneld:負責自動的將模塊調入內核和把模塊從內核中卸載。

4 Modules -編譯一個最小的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 。完成之後,就編譯出一個沒有調入多餘模塊的一個「乾淨的」內核映像文件了。

5 Modules -如何手工載入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模塊載入成功了。

6 Modules -從內存中卸載一個Modules.

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

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

上一篇[做派]    下一篇 [哲學範式]

相關評論

同義詞:暫無同義詞