Linux 核心模組 1

2021-09-20 02:57:49 字數 3398 閱讀 4407

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...