本章節筆記主要理解內核模塊代碼框架和原理,分析一個簡單的內核模塊例子。
須要明確的是模塊和驅動是兩回事。html
內核,是一個操做系統的核心。是基於硬件的第一層軟件擴充,提供操做系統的最基本的功能, 是操做系統工做的基礎,決定着整個操做系統的性能和穩定性。
內核按照體系結構分爲:微內核和宏內核。linux
提升系統靈活性,在調試驅動的時候不須要從新編譯內核,也不須要從新啓動內核,只須要插入須要調試的驅動便可。
內核模塊的特色:框架
內核模塊編譯後會獲得一個 .ko 的 ELF 文件。(ELF 文件能夠百度一下,也能夠參考野火的內核模塊章節。)
ELF 文件:這類文件包含了代碼和數據,能夠被用來連接成可執行文件或共享目標文件,靜態連接庫也能夠歸爲這一類。函數
必須內容可分爲如下幾點:性能
非必須內容:ui
hello_module.c操作系統
/** @file hello_module.c * @brief 簡要說明 * @details 詳細說明 * @author lzm * @date 2021-02-21 18:08:07 * @version v1.0 * @copyright Copyright By lizhuming, All Rights Reserved * ********************************************************** * @LOG 修改日誌: ********************************************************** */ #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> // 入口函數:安裝驅動時調用的函數 static int __init hello_init(void) { printk(KERN_EMERG "[ KERN_EMERG ] Hello Module Init\n"); printk( "[ default ] Hello Module Init\n"); return 0; } // 出口函數:卸載驅動時調用的函數 static void __exit hello_exit(void) { printk("[ default ] Hello Module Exit\n"); } module_init(hello_init); module_exit(hello_exit); //MODULE_LICENSE("GPL2"); MODULE_AUTHOR("embedfire "); MODULE_DESCRIPTION("hello world module"); MODULE_ALIAS("test_module");
insmod:插入模塊:insmod+模塊完整路徑
。
modprobe:插入模塊,insmod具有一樣的功能,一樣能夠將模塊加載到內核中,除此之外modprobe還能檢查模塊之間的依賴關係, 而且按照順序加載這些依賴,能夠理解爲按照順序屢次執行insmod。
depmod:建立模塊依賴文件。modprobe是怎麼知道一個給定模塊所依賴的其餘的模塊呢?在這個過程當中,depmod起到了決定性做用,當執行modprobe時, 它會在模塊的安裝目錄下搜索module.dep文件,這是depmod建立的模塊依賴關係的文件。
rmmod:刪除模塊:insmod+模塊名稱
。
lsmod:查看全部模塊。
modinfo:顯示模塊中的幾個宏的定義。如協議、做者等等。指針
讓系統自動加載模塊須要用到命令depmod和modprobe。調試
首先須要將咱們想要自動加載的模塊統一放到 /lib/modules/內核版本 目錄下,內核版本使用 uname -r
查詢;
其次使用depmod創建模塊之間的依賴關係,命令 depmod -a
;
這個時候咱們就能夠在modules.dep中看到模塊依賴關係,可使用以下命令查看:日誌
cat /lib/modules/內核版本/modules.dep | grep calculation
最後在/etc/modules加上咱們本身的模塊。
實際上,符號指的就是內核模塊中使用 EXPORT_SYMBOL 聲明的函數和變量。當模塊被裝入內核後,它所導出的符號都會記錄在公共內核符號表中。可供給其它模塊使用。
導出方法:
EXPORT_SYMBOL(name) EXPORT_SYMBOL_GPL(name) // name爲要導出的標誌
調用方法(例子):
extern int name;
模塊參數:模塊參數是模塊被加載時,能夠傳值給模塊中的參數。
Linux內核提供一個宏來實現模塊的參數傳遞:
#define module_param(name, type, perm) module_param_named(name, name, type, perm) #define module_param_array(name, type, nump, perm) module_param_array_named(name, name, type, nump, perm)
對應用戶 | 字符 | 說明 |
---|---|---|
當前用戶 | S_IRUSR | 用戶具備讀權限 |
當前用戶 | S_IWUSR | 用戶具備寫權限 |
當前用戶組 | S_IRGRP | 當前用戶組的其它用戶擁有讀權限 |
當前用戶組 | S_IWGRP | 當前用戶組的其它用戶擁有寫權限 |
其它用戶 | S_IROTH | 其它用戶具備讀權限 |
其它用戶 | S_IWOTH | 其它用戶具備寫權限 |
模塊參數使用示例
模塊源碼:
static int nameA=0; module_param(nameA,int,0); static bool nameB=0; module_param(nameB,bool,0644);
加載模塊後,會在路徑 /sys/module/模塊名/parameters 下存在以模塊參數爲名的文件。(注:若文件權限爲0,則沒法查看該文件,也不會顯示在該路徑)