在系统编程中绝大多数情况需要main函数作为程序的入口函数来进行参数的传递。如:
int main(int argc,char **argv){
}
参数说明:
argc英文全称为argument count,代表形参表示传入参数的个数。
argv全称为argument value,代表参数传入的值。
在装载内核模块时,用户可以向模块传递参数,形式为“insmode(或 modprobe)模块名参数名=参数值”,如果不传递,参数将使用模块内定义的缺省值。如果模块被内置,就无法 insmod 了,但是 bootloader可以通过在 bootargs 里设置“模块名.参数名=值”的形式给该内置的模块传递参数。
优势:
1,通过驱动传参,可以让驱动程序史加灵活。兼容性史强。
2.可以通过驱动传参,设置安个校验,防止驱动被盗用。
不足:
1.使驱动代码变得复杂化。
2.增加了驱动的资源占用。
c语言中常用的数据类型内核大部分都支持驱动传参。这里将内核支持的驱动传递参数
的类型分成三类:
基本类型:char,bool,int,long,short’byte,ushort’uinto
数组:array
字符串:string
驱动支持的参数类型有基本类型,数组,字符串。这三个类型分别对应函
module_param:传递基本类型函数
module_param_array:传递数组类型函数
module_param_string:传递字符串类型函数
这三个函数在Linux内核源码include/linux/moduleparam.h中有定义,如下:
#define module_param(name, type, perm) \
module_param_named(name, name, type, perm)
#define module_param_array(name, type, nump, perm) \
module_param_array_named(name, name, type, nump, perm)
#define module_param_string(name, string, len, perm) \
static const struct kparam_string __param_string_##name \
= { len, string }; \
__module_param_call(MODULE_PARAM_PREFIX, name, \
¶m_ops_string, \
.str = &__param_string_##name, perm, -1, 0);\
__MODULE_PARM_TYPE(name, "string")
其它的可以使用下面的方法来判断:
可以将数字最后三位转化为二进制:xxx xxx xxx,高位往低位依次看,第一位为 1 表示文件所有者可读,第二位为 1 表示文件所有者可写,第三位为 1 表示文件所有者可执行;接下来三位表示文件所有者同组成员的权限;再下来三位为不同组用户权限。
include/uapi/linux/stat.h
//user,owner,group
// 文件权限
#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 // 执行权限,其他
efine S_IXOTH 00001
include/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)
这部分代码定义了一些用于文件权限控制的宏,如S_IRWXUGO、S_IALLUGO、S_IRUGO、S_IWUGO、S_IXUGO等。这些宏可以用于设置文件的权限,以及判断文件的权限。其中,S_IRWXUGO表示所有用户都有读、写、执行权限;S_IALLUGO表示所有用户都有读、写、执行权限,并且设置了set-user-ID、set-group-ID和sticky位;S_IRUGO表示所有用户都有读权限;S_IWUGO表示所有用户都有写权限;S_IXUGO表示所有用户都有执行权限。
MODULE_PARM_DESC函数
函数功能:描述模块参数的信息。在include/linux/moduleparam.h定义
函数原型:MODULE_PARM_DESC(_parm,desc)
函数参数:
_parm:要描述的参数的参数名称。
desc:描述信息。
#include <linux/moduleparam.h>
#define MODULE_PARM_DESC(name, desc) __MODULE_PARM_DESC(name, desc)
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
static int a = 0;
static int array[5] = {0};
static int array_size;
//static char str[10] = {0};
static char str1[10] = {0};
module_param(a, int, S_IRUGO);
MODULE_PARM_DESC(a,"int module param");
module_param_array(array, int, &array_size, S_IRUGO);//自动获取长度
MODULE_PARM_DESC(array,"array module param");
module_param_string(str, str1, sizeof(str1), S_IRUGO);
MODULE_PARM_DESC(str,"str module param");
static int module_param_init(void){
int i = 0;
printk("a is %d\n",a);
for(i = 0;i < array_size;i++){
printk("array[%d] is %d\n",i,array[i]);
}
printk("array_size is %d\n",array_size);
printk("str1 is %s\n",str1);
return 0;
}
static void module_param_exit(void){
printk("module_param exit!!!\n");
}
module_init(module_param_init);
module_exit(module_param_exit);
MODULE_AUTHOR("Paranoid");
MODULE_VERSION("V1.0");
MODULE_LICENSE("GPL");
注意权限设置S_IRUGO,若设置为另外的S_IALLUGO会报错
#make 编译项目
#make file 在存放.ko文件目录中创建对应项目的目录
#make install 将*.ko及其应用测试文件移动到根文件中
KERN_DIR = /home/alientek/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
ROOTFS_DIR = /home/alientek/linux/nfs/rootfs/experiment
#项目名字
PROJECT_NAME = module_param
#各驱动名字,ko
DRIVER_NAME1 = module_param
all:
make -C $(KERN_DIR) M=`pwd` modules
clear:
rm -rf modules.order $(DRIVER_NAME1).mod.c *.o Module.symvers .*.cmd .tmp_versions
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
file:
mkdir $(ROOTFS_DIR)/$(PROJECT_NAME)
install:
cp *.ko $(ROOTFS_DIR)/$(PROJECT_NAME)
# 参考内核源码drivers/char/ipmi/Makefile
# 要想把a.c, b.c编译成ab.ko, 可以这样指定:
obj-m += $(DRIVER_NAME1).o