Linux核心模組使用指南

來源:互聯網
上載者:User

轉自:http://doc.linuxpk.com/41555.html

 

作者:sss

  一、模組簡介

 
 Windows
NT是一種微核心的結構,其核心的功能塊被劃分成獨立的模組,在這些功能塊之間有嚴格的通訊機制;而Linux則不同,它是一種monolithic(單
一大塊)結構,也就是說,整個核心是一個單獨的、非常大的程式。在這種結構中,組件的添加和刪除都相當麻煩,需要重新編譯核心。為瞭解決這個問題,不知道
從哪個版本的核心開始,Linux引入了一種稱為module(模組)的技術,可以把某些功能代碼作為模組動態裝載到核心中使用。

  模
塊是一種目標對象檔案,需要在核心空間執行,可以把它看作是一組已經編譯好而且已經連結成可執行檔的程式。在需要的時候,核心就會實用某種方法調用這些
程式來執行特定的操作,實現特定的功能。核心在核心符號表中維護了一個模組的鏈表,每個符號表對應一個模組,在把模組載入進核心時正確地對其進行解釋,並
將模組作為核心的一部分來執行;載入進核心中的模組具有所有的核心許可權。模組可以在系統啟動時載入到系統中,也可以在系統啟動並執行任何時刻載入;在不需要
時,可以將模組動態卸載。這樣就不用每次修改系統的配置時都要重新編譯核心了。

  二、模組的優缺點

  核心模組的這種動態裝載特性具有以下的優點:

  1、可以把核心映像檔案保持在最小。在編譯核心時可以選擇把一部分內容當成模組進行編譯,這樣在最終產生的核心映像檔案中就可以不包含這部分內容,從而產生最小的核心映像檔案。

  2、靈活性好。如果需要實用新的模組,不必重新編譯核心,只要把新的模組編譯後裝載進系統中就可以了。如果對核心來源程式進行了修改,也不需要重新編譯整個核心,只需要修改對應的部分就可以了。

  但是,核心模組的引入也帶來了一些問題:

  1、這種動態載入的特性不利於系統的效能和記憶體的利用,會帶來負面的影響。

  2、裝入核心的模組和其他核心部分一樣具有最高的許可權,使用不當就可能引起系統的崩潰。

  3、核心版本和模組版本的不相容也會導致系統的崩潰,因此必須進行嚴格的版本檢查,這樣就使模組的編寫變得更加複雜了。

  4、有些模組要使用其他模組(例如VFAT就要使用FAT)的內容,模組之間存在一定的依賴關係,這樣模組的實用就複雜化了。

 
 由於模組的這種動態裝載/卸載的特性,在Linux中大部分裝置驅動程式都是使用模組來編寫的,例如檔案系統(minix、msdos、isofs、
smbms、nfs、proc等等)、SCSI裝置驅動程式、乙太網路驅動程式、CD-ROM驅動程式等等。下面讓我們介紹一下模組的使用方法。

  三、模組的使用

  1、模組的查詢

  我們可以使用lsmod命令來瞭解系統中現在裝載進來了哪些模組。例如,在筆者機器上執行的結果為(注意,以下介紹的這些命令(包括lsmod)只有超級使用者才可以執行):

  Module Size Used by

  lockd 30344 1 (autoclean)

  sunrpc 52132 1 (autoclean) [lockd]

  rtl8139 11748 1 (autoclean)

  其中Module列是模組的名字,Size是顯示的模組的大小,Used by列表示引用次數,圓括弧中的autoclean表示該模組可以在空閑時自動卸載,中括弧中的[lockd]表示模組lockd會引用sunrpc模組的內容。

  2、模組的裝載

  模組的裝載有兩種方法:一種是實用insmod命令手工載入模組,第二種方法是使用核心守護進程kerneld在需要的時候動態裝載。insmod命令的格式為:

  insmod //modulename.o

  值得注意的是,insmod命令需要知道模組存放的位置,這樣才能在核心符號表中進行解析。模組可以位於當前路徑中,也可以在insmod命令中指明絕對路徑,另外還有幾個相關的設定檔可以說明模組的位置(見後文中的介紹)。

 
 kerneld是一個標準的守護進程,具有超級使用者的許可權,其主要功能是載入和卸載核心模組, 但是它還可以執行其他任務,
如通過串列線路建立PPP串連並在適當時候關閉它。kerneld自身並不執行這些任務,它通過某些程式如insmod來做此工作。它只是核心的代理,為
核心進行調度。這個守護進程僅僅是一個帶有超級使用者權限的普通使用者進程。當系統啟動時它也被啟動並為核心開啟了一個進程間通訊(IPC)通道,核心需要執
行各種任務時就實用這個IPC來向kerneld發送訊息。例如,如果核心請求現在還沒有裝載到系統中的檔案系統,那麼就通知kerneld裝載這個檔案
系統,然後核心就可以使用這個檔案系統了。在模組空閑時(即沒有其他進程使用這個模組時),kerneld還可以動態卸載這個模組。

  需要注意的是,如果模組之間有某種參考關聯性,那麼裝載模組時必須遵循一定的次序。例如,上面lsmod顯示的結果中lockd模組要引用sunrpc的內容,那麼必須首先裝載sunrpc之後才能裝載lockd,否則就會出錯。

  3、模組的卸載

  我們可以使用rmmod命令把模組從系統中卸載出去,該命令的格式為:

  rmmod modulename

 
 需要注意的是,模組只有在空閑時才能夠從系統中卸載出去。lsmod輸出結果中的Used
by一列就說明了模組當前的狀態。如果該值不為0,說明模組正忙,不能卸載;否則該值為0,說明模組空閑,可以從系統中卸載出去。對於繁忙的裝置,我們首
先得斷開對應裝置的串連,然後才能刪除對應的模組。例如,我們要卸載模組rtl8139(這個模組是筆者機器中rtl8139的乙太網路卡對應的模組),我
們首先要斷開網路連接:

  ifdown eth0 /* eth0是筆者機器中的第一塊網卡*/

  現在再執行lsmod命令的輸出結果為:

  Module Size Used by

  lockd 30344 1 (autoclean)

  sunrpc 52132 1 (autoclean) [lockd]

  rtl8139 11748 0 (autoclean)

  說明已經沒有裝置再使用rtl8139了,我們可以使用

  rmmod rtl8139

  命令將其從系統中卸載出去。

 
 標誌為autoclean(見有關lsmod的介紹)的模組可以自動卸載。前面我們已經提到,模組之間可能會有參考關聯性。如果A模組引用了B模組的內
容,那麼必須先裝載B模組之後才能成功裝載A模組;在卸載B模組之前也要首先卸載A模組,否則就會導致系統的崩潰(當然,如果模組來源程式編寫的正確,在卸
載A模組之前,B模組是無法卸載的)。

  4、模組工具 + 生產力

  以上我們介紹的lsmod、insmod、rmmod是
一組工具 + 生產力所提供的三個命令,這組工具 + 生產力一般是和核心版本對應的,其1.3.57版本名為modules(modules-
1.3.57.tar.gz),高一點的版本名為modutils(例如modutils-2.4.2.tar.gz)。最好保證你的系統中的模組實用工
具的版本號碼(可以使用modinfo -V命令來查看)不低於核心版本號碼(可以使用uname
-r來查看)。1.3.57版本的modules內容包括modprobe、depmod、genksyms、makecrc32、insmod、
rmmod、lsmod、ksyms、kerneld等命令。其中modprobe和insmod命令類似,不過它要依賴於相關的設定檔;depmod
用於產生模組依賴檔案/lib/modules/kernel-version/modules.dep;genksyms和ksyms與核心功能的版本
號有關(由於核心的不斷更新,各個版本的核心功能各有不同,為了不會引起系統的崩潰,核心來源程式中要對核心功能的版本號碼進行嚴格地控制)。在以後版本的實
用工具中,使用kmod來取代了kerneld。kmod的功能和kerneld類似,但是它不能自動卸載模組。之所以採用kmod的原因在於
kerneld是使用IPC通道實現的,相當於多經過了一層處理,另外kerneld的代碼也比較複雜,kmod的代碼數量也比kerneld少得多。

  5、與模組有關的核心編譯選項和過程

  在使用make confing / make menuconfig / make xconfig對核心進行配置時,和模組有關的選項有:

  Code maturity level options -->

  Prompt for development and/or incomplete code/drivers

 
 此選項為代碼的成熟程度。所有新的設計與改進都首先在開發版(版本號碼為x.y.z,其中y是奇數)中試用,經過驗證技術可行之後再在穩定版(版本號碼為
x.y.z,其中y是偶數)中正式引入。尚不成熟或不完善的技術在預設的情況中是不會編譯到核心中的,如果你希望實驗這些內容(例如2.4.*版本中的
khttpd、IPV6等),就要選中這個選項。

  >

  Loadable module support -->

  Enable module support

  Set version information on all module symbols

  Kernel module loader

  此選項是對可裝載核心的支援以及對模組符號的版本號碼、核心模組裝載程式支援的選項。對於其他大部分選項來說,你可以將相應的代碼編譯到核心中(使用build-in方式),也可以將他們編譯成模組(使用module)方式。

  如果你選用了模組方式,那麼在編譯核心的過程中,你除了要使用

  make; make install

  命令來編譯/安裝核心之外,還要使用

  make modules; make modules_install

  來編譯/安裝核心模組。編譯好的模組被安裝到/lib/modules/kernel-version/目錄中。

  編譯過程中還要運行一個

  depmod -a

  命令。這個命令產生模組依賴檔案,也就是/lib/modules/kernel-version/modules.dep,該檔案格式為:

  /lib/modules/2.2.14-5.0/fs/autofs.o:

  /lib/modules/2.2.14-5.0/fs/binfmt_aout.o:

  /lib/modules/2.2.14-5.0/fs/binfmt_java.o:

  /lib/modules/2.2.14-5.0/fs/binfmt_misc.o:

  /lib/modules/2.2.14-5.0/fs/coda.o:

  /lib/modules/2.2.14-5.0/fs/fa

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.