歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

內核模塊指定參數方式

內核模塊的參數傳遞方式很多,第一次嘗試僅僅介紹了 指定普通類型和數組類型

內核模塊指定參數方式

定義內核參數變量

普通變量 : module_param(變量名,變量類型,訪問許可掩碼)
數組變量 : module_param_array(name, type,&num,perm)
關於數組長度變量num需要說一下,num保存數組的長度變量的地址,方便別的地方調用,而數組的長度由數組初始化的時候指定。

內核支持的模塊參數類型
bool 布爾型
invbool 布爾型的反轉, 這兩種類型和int型關聯,即true=0,false=1,反轉布爾型是指 裝載模塊的時候指定0則此變量賦值為false 否則為true
charp 字符指針型,內核會為用戶提供的字符串分配內存,並相應的設置指針
int long short 有符號整形變量
uint ulong ushort 無符號整型變量

訪問許可掩碼,也就是sysfs的訪問權限,每一個模塊裝載後都會在 /sys/module/下保存一個以模塊名命名虛擬文件系統
模塊名下的/paramters/目錄內保存了以變量名命名的文件 訪問許可掩碼即這些文件的訪問權限,看一下下面的介紹

最後的 module_param 字段是一個權限值,表示此參數在sysfs文件系統中所對應的文件節點的屬性。
你應當使用 <linux/stat.h> 中定義的值. 這個值控制誰可以存取這些模塊參數在 sysfs 中的表示.當perm為0時,表示此參數不存在 sysfs文件系統下對應的文件節點。 否則, 模塊被加載後,在/sys/module/ 目錄下將出現以此模塊名命名的目錄, 帶有給定的權限.。
權限在include/linux/stat.h中有定義
比如:
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001
#
使用 S_IRUGO 作為參數可以被所有人讀取, 但是不能改變; S_IRUGO|S_IWUSR 允許 root 來改變參數. 注意, 如果一個參數被 sysfs 修改, 你的模塊看到的參數值也改變了, 但是你的模塊沒有任何其他的通知. 你應當不要使模塊參數可寫, 除非你准備好檢測這個改變並且因而作出反應

向模塊傳遞參數

普通類型 :

static int howmany=0;
static char * whom="world";
module_param(howmany,int,S_IRUGO);
module_param(whom,charp,S_IRUGO);

insmod param_test.ko howmany=10 whom="Yuanye.Ma"

數組 :

static int len;    //存儲數組的長度
static int buf[]={0,0,0,0,0,0,0,0,0};
module_param_array(buf,int, &len, S_IRUGO);   //此處是長度的地址


insmod parm_test.ko buf=2,2,2,2 //注意,源代碼中定義了九個元素,而此處輸入了4個則 len=4
insmod parm_test.ko buf=2,2,2,2 //注意,源代碼中定義了九個元素,而此處輸入了9個則 len=9

總之,len<=輸出初始化的元素個數

實驗

實驗一:

目標:安裝內核模塊的時候通過命令行指定整型數 howmany 和 字符串 whom,模塊加載進入內核的時候連續輸出howmany次 “hello” whom 。

編寫源代碼

#include <linux/module.h>
#include <linux/init.h>

static char * whom = "world";
static int howmany = 0;

module_param(howmany,int,S_IRUGO);
module_param(whom,charp,S_IRUGO);

static int __init parm_test(void)
{
        int i = 0;
        for(i=0; i<howmany;i++)
        {
                printk(KERN_ALERT"hello %s\n",whom);
        }
        return 0;
}

static void __exit parm_exit(void)
{
        printk(KERN_ALERT"GoodBye Kernel");
}

module_init(parm_test);
module_exit(parm_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yuanye.Ma");
MODULE_DESCRIPTION("module param test");

編寫Makefile

obj-m := parm_test.o

KERNEL_PATH = "/usr/src/kernels/2.6.18-8.el5-i686/"
PWD = $(shell pwd)

all:
        make -C $(KERNEL_PATH) M=$(PWD) modules
clean:
        make -C $(KERNEL_PATH) M=$(PWD) clean

內核信息

[root@localhost mod_parm]# modinfo parm_test.ko 
filename:       parm_test.ko
description:    module param test   //模塊描述信息
author:         Yuanye.Ma           //作者名
license:        GPL                 //內核版本信息
srcversion:     F27110872EE977A467DD221
depends:        
vermagic:       2.6.18-8.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
parm:           howmany:int                    //模塊參數
parm:           whom:charp                    //模塊參數

安裝並檢查結果

[root@localhost mod_parm]# insmod parm_test.ko  howmany=10 whom="Yuanye.Ma"   //傳入參數
[root@localhost mod_parm]# dmesg | tail 
GoodBye Kernel<1>hello Yuanye.Ma
hello Yuanye.Ma
hello Yuanye.Ma
hello Yuanye.Ma
hello Yuanye.Ma
hello Yuanye.Ma
hello Yuanye.Ma
hello Yuanye.Ma
hello Yuanye.Ma
hello Yuanye.Ma

實驗二

目標:輸入一個數組,在模塊內部按順序輸出

編寫源碼

#include <linux/module.h>
#include <linux/init.h>
#include <linux/moduleparam.h>

static int len;
static int buf[]={0,0,0,0,0,0,0,0,0,0};

module_param_array(buf,int, &len, S_IRUGO);

static int __init parm_test(void)
{
        int i = 0;
        printk("\nlen = %d\n",len);
        for(i=0;i<len;i++)
                printk(KERN_ALERT"%d\n",buf[i]);

        return 0;
}

static void __exit parm_exit(void)
{
        printk(KERN_ALERT"GoodBye Kernel");
}

module_init(parm_test);
module_exit(parm_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yuanye.Ma");
MODULE_DESCRIPTION("module param test");

Makefile 文件內容和實驗一相同

查看模塊信息

[root@localhost mod_parm]# modinfo parm_test.ko 
filename:       parm_test.ko
description:    module param test
author:         Yuanye.Ma
license:        GPL
srcversion:     83F9FF93EFA9D7495BD1290
depends:        
vermagic:       2.6.18-8.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
parm:           buf:array of int  //數組參數

裝載模塊

[root@localhost mod_parm]# insmod parm_test.ko  buf=1,2,3,4,5
[root@localhost mod_parm]# dmesg | tail
len = 5
1
2
3
4
5
[root@localhost mod_parm]# rmmod parm_test.c 
[root@localhost mod_parm]# insmod parm_test.ko  buf=1,2,3,4,5,6,7,8,9,0,1     //超過所初始化的元素個數的時候報錯
insmod: error inserting 'parm_test.ko': -1 Invalid parameters   //報錯
[root@localhost mod_parm]# 

實驗三:

目標:bool 和 invbool測試

編寫源碼

#include <linux/module.h>
#include <linux/init.h>
#include <linux/moduleparam.h>

static int boo=0;
module_param(boo,bool,S_IRUGO);

static int boo1=0;
module_param(boo1,invbool,S_IRUGO);

static int __init parm_test(void)
{
        printk("\nboo= %d\n",boo);
        printk("boo1= %d\n",boo1);  

        return 0;
}

static void __exit parm_exit(void)
{
        printk(KERN_ALERT"GoodBye Kernel");
}

module_init(parm_test);
module_exit(parm_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yuanye.Ma");
MODULE_DESCRIPTION("module param test");

Makefile 文件內容和實驗一實驗二都一樣此處不再重復

裝載模塊

[root@localhost mod_parm]# insmod parm_test.ko boo=0 boo1=0
[root@localhost mod_parm]# dmesg  | tail
boo= 0       //boo 為bool變量 賦值為0 所以還是輸出0
boo1= 1    //boo1 是invbool變量 賦值為0 自動反轉為1

Copyright © Linux教程網 All Rights Reserved