首页 未命名正文

linux编程_内核模块指定参数方式

云返利网 未命名 2020-05-26 09:08:00 14 0

内核模块的参数通报方式许多,第一次实验仅仅先容了 指定通俗类型和数组类型

内核模块指定参数方式

界说内核参数变量

通俗变量 : 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");

装载模块

[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

【关于云返利网】

云返利网是阿里云、腾讯云、华为云产品推广返利平台,在各个品牌云产品官网优惠活动之外,云返利网还提供返利。您可以无门槛获得阿里云、华为云、腾讯云所有产品返利,在官网下单后就可以领取,无论是自己用、公司用还是帮客户采购,您个人都可以获得返利。云返利网的目标是让返利更多、更快、更简单!详情咨询13121395187(微信同号)