4.1 核心模組程式結構

  • 載入:insmodmodprobe(同時載入模組的依賴模組)
  • 卸載:rmmod
  • 查看已載入的模組及模組間的依賴關係:lsmod,實際上是分析/proc/modules
  • 已載入的模組資訊放在/sys/module目錄下,沒載入一個模組就會在該目錄下生成一個以模組名命名的目錄,“tree -a”可獲取目錄樹
  • 模組許可聲明:申明許可許可權,否則將收到核心被污染警告,一般申明為MODULE_LICENSE(“GPL v2”)語句申明採用GPL v2.
  • 模組參數(可選):模組被載入的時候可以傳遞給它的值,它本身對對應模組的內部的全域變數
  • 模組匯出符(可選):其他模組可以使用模組匯出的函數和變數
  • 模組作者等資訊聲明

4.2 模組載入函數

  • Linux核心模組載入函數一般以__init標識申明,如

static int __init initialization_function(void)

{

    /*初始化程式碼*/

}

module_init(initialization_function);

初始化成功返回0,否則返回錯誤碼。

  • request_module(const char* fmt, …):靈活載入核心模組
  • 資料也可以定義為__initdata,只是在初始化的階段需要的資料,結束後釋放佔用的記憶體

4.4 模組卸載函數

一般以__exit標識申明,如

static void __exit cleanup_function(void)

{

    /*釋放程式碼*/

}

module_exit(cleanup_function);

被直接編譯進核心的模組的卸載函數會被省略,不編譯進核心,因為模組被內置了,也就不會被卸載。

4.5 模組參數

  • module_param(參數名,參數類型,參數讀寫許可權):為模組定義一個參數,如下定義一個int參數和char指標參數

static char *book_name = "dissecting Linux Deice Driver";

module_param(book_name, char, S_IRUGO);

 

static int book_num = 4000;

module_param(book_num, int, S_IRUGO);

 “insmod (modprobe) 模組名 參數名 = 參數值,不傳遞則用缺省值,模組被內置時用bootloader通過bootargs裡設置模組名.參數 = 給內置模組傳遞參數。

  • 參數陣列:module_param_array(陣列名稱,陣列類別,陣列長度,參數讀寫許可權)
  • /sys/module下有已載入模組命名的目錄,當參數讀寫許可權0,則此參數不存在sysfs檔案系統下對應的節點,否則此模組的目錄下會出現parameter目錄,其中包含以參數名命令的檔節點,檔許可權與設定的許可權一致。
  • 允許insmodmodprobe命令時,用逗號隔開輸入的陣列元素
  • 例:定義兩個參數的模組

/*======================================================================

    A kernel module: book

    This example is to introduce module params

 

    The initial developer of the original code is Baohua Song

    <author@linuxdriver.cn>. All Rights Reserved.

======================================================================*/

#include <linux/init.h>                               

#include <linux/module.h>                               

MODULE_LICENSE("Dual BSD/GPL");                               

 

static char *book_name = "dissecting Linux Device Driver";             

static int num = 4000;                               

 

static int book_init(void)                               

{                               

    printk(KERN_INFO " book name:%s\n",book_name);                       

    printk(KERN_INFO " book num:%d\n",num);                              

    return 0;                                

}                               

static void book_exit(void)                               

{                               

    printk(KERN_INFO " Book module exit\n ");                           

}                                

module_init(book_init);                               

module_exit(book_exit);                               

module_param(num, int, S_IRUGO);                               

module_param(book_name, charp, S_IRUGO);

 

MODULE_AUTHOR("Song Baohua, author@linuxdriver.cn");

MODULE_DESCRIPTION("A simple Module for testing module params");

MODULE_VERSION("V1.0");

通過insmod加參數和不加參數實驗,在/var/log/messages檔中查看核心的輸出
/sys/module/book/parameters目錄下輸入tree查看參數檔節點

4.6 匯出符號

  • /proc/kallsyms檔記錄了符號及符號所在的記憶體位址
  • 匯出符號:EXPORT_SYSBOL(符號名)EXPORT_SYSBOL_GPL(符號名)(只適用於包含GPL許可權的模組)
  • 例:

/*======================================================================

    A simple kernel module to introduce export symbol

 

    The initial developer of the original code is Baohua Song

    <author@linuxdriver.cn>. All Rights Reserved.

======================================================================*/

#include <linux/init.h>                               

#include <linux/module.h>                               

MODULE_LICENSE("Dual BSD/GPL");                               

 

int add_integar(int a,int b)                               

{                               

    return a+b;                            

}

 

int sub_integar(int a,int b)                               

{                                

    return a-b;                            

}                           

 

EXPORT_SYMBOL(add_integar);

EXPORT_SYMBOL(sub_integar);

4.7 模組申明與描述

  • MODULE_AUTHOR(author);
  • MODULE_DESCRIPTION(description);
  • MODULE_VERSION(version_string);
  • MODULE_DEVICE_TABLE(table_info);
  • MODULE_ALIAS(alternate_name);
  • 對於USB, PCI等設備驅動,通常建立一個MODULE_DEVICE_TABLE來表明驅動模組支援的設備

4.8 模組的使用計數

  • try_module_get(&module)module_put(&module):模組計數管理介面
  • try_module_get(&module):增加模組使用計數,返回0,呼叫失敗,希望使用的的模組不存在或正在被卸載
  • module_put(&module):減少模組使用計數
  • 模組的使用計數一般不由模組本身管理,由核心更底層的程式碼(匯流排驅動或者此類設備共用的核心模組)來實現,以簡化驅動開發
  • 當設備正在使用的時候,模組不可以被卸載

4.9 模組編譯

  • Makefile
  • 模組包含多個.c文件,則Makefile寫法

obj-m := modulename.o

modulename-objs := file1.o file2.o ...

arrow
arrow
    文章標籤
    Linux 模組
    全站熱搜

    立你斯 發表在 痞客邦 留言(0) 人氣()