Linux裝置驅動第 2 章之 模組引數

2021-08-21 08:52:26 字數 4012 閱讀 4481

2.8. 模組引數

由於系統的不同,驅動程式需要的引數也許會發生變化。這包括裝置編號以及其它一些用來控制驅動程式操作方式的引數。例如,scsi介面卡的驅動程式經常要處理一些選項,這些選項用來控制標記命令佇列的使用,而整合裝置電路驅動程式允許使用者控制dma操作。如果驅動程式用來控制一些早期的硬體,也許需要明確告訴驅動程式硬體的io埠或者io記憶體位址的位置。為滿足這種需求,核心允許對驅動程式指定引數,而這些引數可以在載入驅動程式模組時改變。

這些引數的值可在執行insmod或modprobe命令載入模組時賦值,而modprobe可以從它的配置檔案中讀取引數值。這兩個命令可在命令列接受幾種引數型別的賦值。例如,新增兩個引數:乙個是整數值howmany,另乙個是字串who。可用下面的命令列來載入核心模組:

insmod hello.ko howmany=10 who="andyliu"

這個命令的效果會讓hello列印10次「hello,andyliu」。

在insmod改變模組引數之前,模組必須讓這些引數對insmod命令可見。引數必須使用module_param巨集來宣告,這個巨集在linux/moduleparam.h中定義。

#define module_param(name, type, perm)                          \

module_param_named(name, name, type, perm)

module_param需要三個引數:變數的名稱、型別以及用於sysfs入口項的訪問許可掩碼。這個巨集必須放在任何函式之外,通常是在原始檔的頭部。這樣,通過下面的**來宣告它的引數並使之對insmod可見。

static int howmany = 1;

static char *who = "andyliu";

module_param(howmany, int, s_irugo);

module_param(who, charp, s_irugo);

參見例項

#include

#include

#include

static int howmany = 1;

static char *who = "andyliu";

module_param(howmany, int, s_irugo);

module_param(who, charp, s_irugo);

static int __init mod_param_init(void)

return 0;

}static void __exit mod_param_exit(void)

module_init(mod_param_init);

module_exit(mod_param_exit);

module_license("dual bsd/gpl");

ifeq ($(kernelrelease),)

kerneldir ?= /lib/modules/$(shell uname -r)/build

pwd := $(shell pwd)

all:                               

$(make) -c $(kerneldir) m=$(pwd) modules

clean:                                             

$(make) -c $(kerneldir) m=$(pwd) clean

else

obj-m := mod_param.o

endif

核心支援的模組引數型別如下:

bool

invbool

布林值(true或false),關聯的變數應該是int型別。invbool型別反轉其值,true值變成false,而false變成true。

charp

字元指標值。核心會為使用者提供的字串分配記憶體,並相應設定指標。

intlong

short

uint

ulong

ushort

具有不同長度的基本整數值。以u開頭的型別用於無符號值。

模組裝載器也支援陣列引數,在提供陣列值時用逗號劃分各陣列成員。要宣告陣列引數,需要使用下面的巨集:

/*** module_param_array - a parameter which is an array of some type

* @name: the name of the array variable

* @type: the type, as per module_param()

* @nump: optional pointer filled in with the number written

* @perm: visibility in sysfs

** input and output are as comma-separated values.  commas inside values

* don't work properly (eg. an array of charp).

** array_size(@name) is used to determine the number of elements in the

* array, so the definition must be visible.

*/#define module_param_array(name, type, nump, perm)              \

module_param_array_named(name, name, type, nump, perm)

其中,name是陣列的名稱(也就是引數的名稱),type是陣列元素的型別,nump是乙個整數變數,而perm是常見的許可訪問值。如果在裝載時設定陣列引數,則num會被設定為使用者提供的值的個數。模組裝載器會拒絕接受超過陣列大小的值。

參見例項:

#include

#include

#include

static int ages = ;// 預設值

static int nump;

module_param_array(ages, int, &nump, s_irugo);

static int __init mod_param_init(void)

return 0;

}static void __exit mod_param_exit(void)

module_init(mod_param_init);

module_exit(mod_param_exit);

module_license("dual bsd/gpl");

如果需要的型別不在上面列出的清單中,模組**中的鉤子可以讓我們來定義這些型別。請參考linux/moduleparam.h檔案。備註:所有的模組引數都應該給定乙個預設值;insmod只會在使用者明確設定了引數的值的情況下才會改變引數的值。模組可以根據預設值來判斷是否是乙個顯示指定的引數。

module_param中的最後乙個成員是訪問許可值,應使用linux/stat.h中存在的定義。

#define s_irwxugo       (s_irwxu|s_irwxg|s_irwxo)

#define s_iallugo       (s_isuid|s_isgid|s_isvtx|s_irwxugo)

#define s_irugo         (s_irusr|s_irgrp|s_iroth)

#define s_iwugo         (s_iwusr|s_iwgrp|s_iwoth)

#define s_ixugo         (s_ixusr|s_ixgrp|s_ixoth)

這個值用來控制誰能夠訪問sysfs中對模組引數的表述。如果perm被設定為0,就不會有對應的sysfs入口項;否則,模組引數會在/sys/module中出現,並設定為給定的訪問許可。如果對引數使用s_irugo,則任何人可讀取該引數,但不能修改;注意,如果乙個引數通過sysfs而被修改,則如同模組修改了這個引數的值一樣,但是核心不會以任何方式通知模組。大多數情況下,不應該讓模組引數是可寫的,除非打算檢測這種修改並作出相應的動作。

Linux裝置驅動之第 2 章 預備知識

2.6.預備知識 核心是乙個特定的環境,對需要和它介面的 有自己的一些要求。大部分核心 中都要包含相當數量的標頭檔案,以便獲得函式 資料型別和變數的定義。有幾個標頭檔案是用於模組的,必須出現在每個可裝載的模組中。所有的模組 中都包含下面兩行 include include linux module....

Linux裝置驅動之第 2 章 核心符號表

2.5.核心符號表 insmod使用公共核心符號表來解析模組中未定義的符號。公共核心符號表包含所有的全域性核心項 函式和變數 的位址,這是實現模組化驅動程式所必需的。當模組被裝入核心後,這個模組匯出的任何符號都會變成核心符號表的一部分。通常情況下,模組只需實現自己的功能,而無需匯出任何符號。但是,如...

Linux裝置驅動 模組

模組檔案 在檔案系統中可以被直接插入到核心的檔案 模組三要素 模組載入函式 必須 當在檔案系統中使用insmod或者該模組在核心被執行的時候,自動執行該函式 函式方式 1 預設方式 int init module void 2 使用者自定義 int test init void module ini...