linux下的模組載入

來源:互聯網
上載者:User

轉載自百度百科 一、什麼是 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有關的命令有:
lsmode :列出已經被核心調入的模組
insmode:將某個module插入到核心中
modeprobe:將某個module載入到核心中
rmmod:將某個module從核心中卸載
depmod: 產生依賴檔案,告訴將來的 insmod 要從哪兒調入 modules。這個依賴檔案就在/lib/modules/[您的kernel版本]/modules.dep。

Kerneld:負責自動的將模組調入核心和把模組從核心中卸載。 modeprobe和insmode都可以安裝庫,但是,modeprobe會議靠分析庫之間的依賴關係,然後又先後順序的載入必需的庫,然後再載入當前的庫,而insmode就只會載入你所制定的這個庫,一旦他有一些依賴關係,那麼你就無從下手了,會出錯的。

  庫之間的依賴關係並不是modeprobe自己檢測出來的,是depmode檢測書來的,並寫在了類似/lib/modules/2.6.xx/modules.dep 得檔案裡面了。  而/etc/conf.modules或者/etc/modules.conf檔案裡面描述了一些庫的別名,載入庫之前/之後要執行的命令,或者庫之間的先後依賴關係,以及在載入庫的時候提供的參數等資訊,還可以制定一些路徑作為載入某種庫的時候的搜尋路徑。但是有個問題,depmode是通過讀取/etc/modules.conf檔案來擷取庫之間的依賴關係的嗎?應該說可以肯定的是/etc/modules.conf會對modeprobe和depmode的行為有影響,如對庫的搜尋路徑就有影響。    /etc/modules.conf會影響depmode和modeprobe,而depmode的結果又會為modeprobe所用。   下面是對/etc/modules.conf的幾個簡單常用的statement:    1. alias iso9660 isofs 是我們可以用insmode iso9660來代替isofs,這樣可以使用更為易懂的名字。    2. define VARIABLE WORD可以定義VARIABLE=WORD,即將其加入環境變數中,這個變數在整個session有效。    3. include PATH_ TO_ CONFIG_ FILE
    可以include別的config檔案。結合if else 命令可以做到有條件的include,從而提高移植性。    4. insmod_ opt=GENERIC_ OPTIONS_ TO_ INSMOD
     如果你需要為每次insmode的調用都提供一些公用的option,就可以加在這裡。    5. path[TAG]=A_ PATH
    path裡面記錄了一些路徑,我們可以加上個tag來講路徑分類,比如boot相關的庫的路徑就可以用path[boot]來制定,這樣我們再modeprobe的時候就可以這樣一下載入boot目錄下的所有庫:      modprobe -t net
              Load one of the modules that are stored in the directory  tagged
              "net".  Each module are tried until one succeeds.

       modprobe -a -t boot
              All modules that are stored in directories tagged "boot" will be
              loaded.     6. [add] probe name module_list

       [add] probeall name module_list      意思不是很清楚,基本上就是說,當要載入name時,就在module_list裡面一個一個載入,第一種會在找到一個成功載入之後停止,第2中知道把所有的載入一個遍。add的含義不是很清楚。     7。[add] above module module_list        [add] below module module_list
        上述2個就是指明了module和module_list裡的所有module之間的依賴順序,這個可以具體察看man手冊。linux採用了module stack的概念來描述載入的先後順序。     8.下面幾種是在載入庫,卸載庫前後要執行commande的情況。       pre-install module command
              Execute command before installing the specified module.  See the
              below directive as well.
       install module command
              Execute command instead of the default  insmod  when  installing
              the specified module.
       post-install module command
              Execute  command after installing the specified module.  See the
              above directive as well.
       pre-remove module command
              Execute command before removing the specified module.   See  the
              above directive as well.
       remove module command
              Execute  command  instead  of  the default (built-in) rmmod when
              removing the specified module.
       post-remove module command
     9。 此外,在etc/modules.conf裡面是可以使用shell的原字元的,meta-character,如可以使用`command`。
四、編譯一個最小的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會給你提示足夠的資訊,仔細查看這些資訊,是能夠為你採取相應的操作並最終解決問題提供協助的

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.