Linux 驅動之模組參數--Linux裝置驅動程式

來源:互聯網
上載者:User

Linux 驅動之模組參數--Linux裝置驅動程式
模組參數

很多情況下,我們期望通過參數來控制我們的驅動的行為,比如由於系統的不同,而為了保證我們驅動有較好的移植性,我們有時候期望通過傳遞參數來控制我們驅動的行為,這樣不同的系統中,驅動可能有不同的行為控制。

為了滿足這種需求,核心允許對驅動程式指定參數,而這些參數可在載入驅動的過程中動態改變

參數的來源主要有兩個

使用insmod/modprobe ./xxx.ko時候在命令列後直接給出參數;

modprobe命令裝載模組時可以從它的設定檔/etc/modprobe.conf檔案中讀取參數值

這個宏必須放在任何函數之外,通常實在源檔案的頭部

模組參數傳遞的方式

對於如何向模組傳遞參數,Linux kernel 提供了一個簡單的架構。其允許驅動程式聲明參數,並且使用者在系統啟動或模組裝載時為參數指定相應值,在驅動程式裡,參數的用法如同全域變數。

使用下面的宏時需要包含標頭檔

module_param(name, type, perm)module_param_array(name, type, num_point, perm);module_param_named(name_out, name_in, type, perm);module_param_string(name, string, len, perm);
參數類型

核心支援的模組參數類型如下

參數 描述
bool 布爾類型(true/false),關聯的變數類型應該死int
intvbool bool的反值,例如賦值位true,但是實際值位false
int 整型
long 長整型
short 短整型
uint 無符號整型
ulong 無符號長整形型
ushort 無符號短整型
charp 字元指標類型,核心會為使用者提供的字串分配記憶體,並設定相應指標

關於數群組類型怎麼傳遞,我們後面會談到

注意

如果我們需要的類型不在上面的清單中,模組代碼中的鉤子可讓我們來指定這些類型。

具體的細節請參閱moduleparam.h檔案。所有的模組參數都應該給定一個預設值;

insmod只會在使用者明確設定了參數值的情況下才會改變參數的值,模組可以根據預設值來判斷是否一個顯示給定的值

存取權限

perm存取權限與linux檔案愛你存取權限相同的方式管理,

如0644,或使用stat.h中的宏如S_IRUGO表示。

我們鼓勵使用stat.h中存在的定義。這個值用來控制誰能夠訪問sysfs中對模組參數的表述。
如果制定0表示完全關閉在sysfs中相對應的項,否則的話,模組參數會在/sys/module中出現,並設定為給定的訪問許可。

如果指定S_IRUGO,則任何人均可讀取該參數,但不能修改
如果指定S_IRUGO | S_IWUSR 則允許root修改該值

注意

如果一個參數通過sysfs而被修改,則如果模組修改了這個參數的值一樣,但是核心不會以任何方式通知模組,大多數情況下,我們不應該讓模組參數是可寫的,除非我們打算檢測這種修改並做出相應的動作。

如果你只有ko檔案卻沒有源碼,想知道模組中到底有哪些模組參數,不著急,只需要用


modinfo -p ${modulename}

就可以看到個究竟啦。

對於已經載入到核心裡的模組,如果想改變這些模組的模組參數該咋辦呢?簡單,只需要輸入

echo -n ${value} > /sys/module/${modulename}/parameters/${param}

來修改即可。

樣本傳遞全域參數

在模組裡面, 聲明一個變數(全域變數),用來接收使用者載入模組時傳遞的參數

module_param(name, type, perm);
參數 描述
name 用來接收參數的變數名
type 參數的資料類型
perm 用於sysfs入口項系的訪問可見度掩碼
樣本–傳遞int

這些宏不會聲明變數,因此在使用宏之前,必須聲明變數,典型地用法如下:

static int value = 0;module_param(value, int, 0644);MODULE_PARM_DESC(value_int, "Get an value from user...\n");

使用

sudo insmod param.ko value=100 

來進行載入

樣本–傳遞charp
static char *string = "gatieme";module_param(string, charp, 0644);MODULE_PARM_DESC(string, "Get an string(char *) value from user...\n");

使用

sudo insmod param.ko string="hello" 
在模組內部變數的名字和載入模組時傳遞的參數名字不同

前面那種情況下,外部參數的名字和模組內部的名字必須一致,那麼有沒有其他的Binder 方法,可以是我們的參數傳遞更加靈活呢?

使模組源檔案內部的變 量名與外部的參數名有不同的名字,通過module_param_named()定義。

module_param_named(name_out, name_in, type, perm);
參數 描述
name_out 載入模組時,參數的名字
name_in 模組內部變數的名字
type 參數類型
perm 存取權限

使用

static int  value_in = 0;module_param_named(value_out, value_in, int, 0644);MODULE_PARM_DESC(value_in, "value_in named var_out...\n");

載入

sudo insmod param.ko value_out=200
傳遞字串

載入模組的時候, 傳遞字串到模組的一個全域字元數組裡面

module_param_string(name, string, len, perm);
參數 描述
name 在載入模組時,參數的名字
string 模組內部的字元數組的名字
len 模組內部的字元數組的大小
perm 存取權限
static char buffer[20] = "gatieme";module_param_string(buffer, buffer, sizeof(buffer), 0644);MODULE_PARM_DESC(value_charp, "Get an string buffer from user...\n");
傳遞數組

載入模組的時候, 傳遞參數到模組的數組中

module_param_array(name, type, num_point, perm);
參數 描述
name 模組的數組名,也是外部制定的數組名
type 模組數組的資料類型
num_point 用來擷取使用者在載入模組時傳遞的參數個數,為NULL時,表示不關心使用者傳遞的參數個數
perm 存取權限

使用

static int  array[3];int         num;module_param_array(array, int, &num, 0644);MODULE_PARM_DESC(array, "Get an array from user...\n");
param驅動源碼驅動源碼param.c
#include #include #include /* *  在模組裡面, 聲明一個變數(全域變數), *  用來接收使用者載入模組哦時傳遞的參數 * *  module_param(name, type, perm) **/static int value = 0;module_param(value, int, 0644);MODULE_PARM_DESC(value_int, "Get an value from user...\n");/* *  在模組內部變數的名字和載入模組時傳遞的參數名字不同 * *  module_param_named(name_out, name_in, type, perm) * *  @name_out    載入模組時,參數的名字 *  @name_in     模組內部變數的名字 *  @type        參數類型 *  @perm        存取權限 * */static int  value_in = 0;module_param_named(value_out, value_in, int, 0644);MODULE_PARM_DESC(value_in, "value_in named var_out...\n");/* *  載入模組的時候, 傳遞字串到模組的一個全域字元數組裡面 * *  module_param_string(name, string, len, perm) * *  @name   在載入模組時,參數的名字 *  @string 模組內部的字元數組的名字 *  @len    模組內部的字元數組的大小 *  #perm   存取權限 * * */static char *string = NULL;module_param(string, charp, 0644);MODULE_PARM_DESC(string, "Get an string(char *) value from user...\n");static char buffer[20] = "gatieme";module_param_string(buffer, buffer, sizeof(buffer), 0644);MODULE_PARM_DESC(value_charp, "Get an string buffer from user...\n");/* *  載入模組的時候, 傳遞參數到模組的數組中 * *  module_param_array(name, type, num_point, perm) * *  @name       模組的數組名,也是外部制定的數組名 *  @type       模組數組的資料類型 *  @num_point  用來擷取使用者在載入模組時傳遞的參數個數, *              為NULL時,表示不關心使用者傳遞的參數個數 *  @perm       存取權限 * * */static int  array[3];int         num;module_param_array(array, int, &num, 0644);MODULE_PARM_DESC(array, "Get an array from user...\n");int __init  param_module_init(void){    int index = 0;    printk("\n---------------------\n");    printk("value       : %d\n", value);    printk("value_in    : %d\n", value_in);    printk("string      : %s\n", string);    printk("buffer      : %s\n", buffer);    for(index = 0; index < num; index++)    {    printk("array[%2d]   :   %d\n", index, array[index]);    }    printk("---------------------\n");    return 0;}void __exit param_module_exit(void){    printk("\n---------------------\n");    printk("exit param dobule\n");    printk("---------------------\n");}module_init(param_module_init);module_exit(param_module_exit);
Makefile
obj-m := param.oKERNELDIR ?= /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)all:    make -C $(KERNELDIR) M=$(PWD) modulesclean:    make -C $(KERNELDIR) M=$(PWD) clean
參數傳遞過程
sudo insmod param.ko value=100 value_out=200 string="gatieme" buffer="Hello-World" array=100,200,300

dmesg查看

sudo rmmod param

使用modinfo查看參數
modinfo -p param.ko

動態修改模組參數

首先查看一下sysfs目錄下的本模組參數資訊

ls /sys/module/param/parameters

動態修改

聯繫我們

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