linux 核心模組(1)
成於堅持,敗於止步
linux 核心模組簡介
linux 核心的整體結構非常龐大,其包含的元件也非常多。我們怎樣把需要的部分都包含在核心中呢?
一種方法是把所有需要的功能都編譯到 linux 核心。這會導致兩個問題,一是生成的核心會很大,二是如果我們要在現有的核心中新增或刪除功能,將不得不重新編譯核心。
有沒有一種機制使得編譯出的核心本身並不需要包含所有功能,而在這些功能需要被使用的時候,其對應的**可被動態地載入到核心中呢?
linux 提供了這樣的一種機制,這種機制被稱為模組(module),可以實現以上效果。模組具有以下特點。
模組本身不被編譯入核心映像,從而控制了核心的大小。
模組一旦被載入,它就和核心中的其他部分完全一樣。
為了使讀者對模組建立初步的感性認識,我們先來看乙個最簡單的核心模組「hello world」,如**所示:
1 #include
2 #include
3 module_license(「dual bsd/gpl」);
4 static int hello_init(void)
5 9 static void hello_exit(void)
10 13 module_init(hello_init);
14 module_exit(hello_exit);
1516 module_author(「song baohua」);
17 module_description(「a ****** hello world module」);
18 module_alias(「a ******st module」);
這個最簡單的核心模組只包含核心模組載入函式、解除安裝函式和對 dual bsd/gpl許可許可權的宣告以及一些描述資訊。編譯它會產生 hello.ko 目標檔案,通過「insmod ./hello.ko」命令可以載入它,通過「rmmod hello」命令可以解除安裝它,載入時輸出「hello world enter」,解除安裝時輸出「hello world exit」。 核心模組中用於輸出的函式是核心空間的 printk()而非使用者空間的 printf(),printk()的用法和 printf()相似,但前者可定義輸出級別。printk()可作為一種最基本的核心除錯手段。
在 linux 系統中,使用 lsmod 命令可以獲得系統中載入了的所有模組以及模組間的依賴關係,例如:
[root@localhost driver_study]# lsmod
module size used by
hello 1568 0
ohci1394 32716 0
ide_scsi 16708 0
ide_cd 39392 0
cdrom 36960 1 ide_cd
lsmod 命令實際上讀取並分析/proc/modules 檔案,與上述 lsmod 命令結果對應的/proc/modules 檔案如下:
[root@localhost driver_study]# cat /proc/modules
hello 1568 0 - live 0xc8859000
ohci1394 32716 0 - live 0xc88c8000
ieee1394 94420 1 ohci1394, live 0xc8840000
ide_scsi 16708 0 - live 0xc883a000
ide_cd 39392 0 - live 0xc882f000
cdrom 36960 1 ide_cd, live 0xc8876000
核心中已載入模組的資訊也存在於/sys/module 目錄下,載入 hello.ko 後,核心中將包含/sys/module/hello 目錄,該目錄下又包含乙個 refcnt 檔案和乙個 sections 目錄,在/sys/module/hello 目錄下執行「tree –a」得到如下目錄樹:
[root@localhost hello]# tree -a
.|-- refcnt
'-- sections
|-- .bss
|-- .data
|-- .gnu.linkonce.this_module
|-- .rodata
|-- .rodata.str1.1
|-- .strtab
|-- .symtab
|-- .text
'-- _ _versions
modprobe 命令比 insmod 命令要強大,它在載入某模組時會同時載入該模組所依賴的其他模組。使用 modprobe 命令載入的模組若以「modprobe -r filename」的方式解除安裝將同時解除安裝其依賴的模組。
使用 modinfo 《模組名》命令可以獲得模組的資訊,包括模組的作者、模組的說明、模組所支援的引數以及 vermagic,如下所示:
[root@localhost driver_study]# modinfo hello.ko
filename: hello.ko
license: dual bsd/gpl
author: song baohua
description: a ****** hello world module
alias: a ******st module
vermagic: 2.6.15.5 686 gcc-3.2
depends:
linux 核心模組的程式結構
乙個 linux 核心模組主要由以下幾個部分組成。
模組載入函式(必須)。
當通過 insmod 或 modprobe 命令載入核心模組時,模組的載入函式會自動被核心執行,完成本模組的相關初始化工作。
模組解除安裝函式(必須)。
當通過 rmmod 命令解除安裝某模組時,模組的解除安裝函式會自動被核心執行,完成與模組載入函式相反的功能。
模組許可證宣告(必須)。
模組許可證(license)宣告描述核心模組的許可許可權,如果不宣告 license,模組被載入時,將收到核心被汙染 (kernel tainted)的警告。 在 linux 2.6 核心中,可接受的 license 包括「gpl」、「gpl v2」、「gpl and additional rights」、「dual bsd/gpl」、「dual mpl/gpl」和「proprietary」。 大多數情況下,核心模組應遵循 gpl 相容許可權。linux 2.6 核心模組最常見的是以 module_license( 「dual bsd/gpl」 ) 語句 聲 明模 塊採用 bsd/gpl 雙license。
模組引數(可選)。
模組引數是模組被載入的時候可以被傳遞給它的值,它本身對應模組內部的全域性變數。
模組匯出符號(可選)。
核心模組可以匯出符號(symbol,對應於函式或變數),這樣其他模組可以使用本模組中的變數或函式。
模組作者等資訊宣告(可選)。
就到這裡了,o(∩_∩)o~
Linux核心模組
核心模組 在整個啟動的過程中,是否能成功的驅動我們主句的硬體裝置,是核心完成的工作,而核心一般都是壓縮文件,在使用之前核心之前必須要將核心減壓到的記憶體中。為了應對日新月異的硬體,目前核心都具有可讀取模組化驅動程式的功能,也就是所謂的 modules模組化 所謂模組化。核心與核心模組放在 核心 bo...
Linux核心模組
1 核心模組註冊登出 塊載入函式有返回值,模組解除安裝函式無返回值。兩者都是無參函式,載入函式用 init修飾,解除安裝函式用 exit修飾。define init attribute section init.text define exit atrribute section exit,text...
Linux 核心模組
linux 核心模組程式結構 1 模組載入函式 2 模組解除安裝函式 3 模組許可證宣告 4 模組引數 5 模組匯出符號 6 模組作者等資訊宣告 模組載入函式 一般以 init 標識 在 linux 中,所有標識為 init 的函式如果直接編譯進核心,成為核心映象的一部分,在連線的時候都會放在 in...