Linux内核之module_param()函数使用说明

Table of Contents

1. 概述:

2. module_param定义:

3. 完整测试例程如下:


1. 概述:

主要区别就是用户可否在系统启动或模块装载时为参数指定相应值,在驱动程序里,参数的用法如同全局变量。

  • 不使用module_param

如只定一个全局变量:

#define MY_MAJOR 0x09
static int global_val_test = MY_MAJOR;

那么编译模块后,insmod加载模块时不能传参数进去,如:

[root@bogon hello_world]# insmod first_hello.ko global_val_test=5
insmod: ERROR: could not insert module first_hello.ko: Invalid parameters

同时,insmod模块后,对应module目录下的对应模块下不会生成parameter子目录,更不会生成参数文件.

[root@bogon hello_world]# cat /sys/module/first_hello/
coresize     holders/     initsize     initstate    notes/       refcnt       rhelversion  sections/    srcversion   taint        uevent       version
  • 使用module_param后,参考如下:
#define MY_MAJOR 0x09
static int global_val_test = MY_MAJOR;
module_param(global_val_test, int, 0644);

再编译模块后,再insmod加载模块时就可以传参数进去了,如:

[root@bogon hello_world]# insmod first_hello.ko global_val_test=5
[root@bogon hello_world]# tail /var/log/messages
May 26 14:20:08 localhost kernel: [63460.994397] global_val_test = 5
May 26 14:20:08 localhost kernel: [63460.994409] hello world enter
May 26 14:20:08 localhost kernel: global_val_test = 5
May 26 14:20:08 localhost kernel: hello world enter

同时,在模块目录下会生成parameter目录及参数文件,如下:

[root@bogon hello_world]# cat /sys/module/first_hello/
coresize     holders/     initsize     initstate    notes/       parameters/  refcnt       rhelversion  sections/    srcversion   taint        uevent       version
[root@bogon hello_world]# ls -alt /sys/module/first_hello/parameters/
total 0
-rw-r--r-- 1 root root 16384 May 26 14:54 global_val_test


2. module_param定义:

函数原型:


/**
 * module_param - typesafe helper for a module/cmdline parameter
 * @name: the variable to alter, and exposed parameter name.
 * @type: the type of the parameter
 * @perm: visibility in sysfs.
 *
 * @name becomes the module parameter, or (prefixed by KBUILD_MODNAME and a
 * ".") the kernel commandline parameter.  Note that - is changed to _, so
 * the user can use "foo-bar=1" even for variable "foo_bar".
 *
 * @perm is 0 if the the variable is not to appear in sysfs, or 0444
 * for world-readable, 0644 for root-writable, etc.  Note that if it
 * is writable, you may need to use kernel_param_lock() around
 * accesses (esp. charp, which can be kfreed when it changes).
 *
 * The @type is simply pasted to refer to a param_ops_##type and a
 * param_check_##type: for convenience many standard types are provided but
 * you can create your own by defining those variables.
 *
 * Standard types are:
 *	byte, short, ushort, int, uint, long, ulong
 *	charp: a character pointer
 *	bool: a bool, values 0/1, y/n, Y/N.
 *	invbool: the above, only sense-reversed (N = true).
 */
#define module_param(name, type, perm)				\
	module_param_named(name, name, type, perm)
/**
 * module_param_named - typesafe helper for a renamed module/cmdline parameter
 * @name: a valid C identifier which is the parameter name.
 * @value: the actual lvalue to alter.
 * @type: the type of the parameter
 * @perm: visibility in sysfs.
 *
 * Usually it's a good idea to have variable names and user-exposed names the
 * same, but that's harder if the variable must be non-static or is inside a
 * structure.  This allows exposure under a different name.
 */
#define module_param_named(name, value, type, perm)			   \
	param_check_##type(name, &(value));				   \
	module_param_cb(name, ¶m_ops_##type, &value, perm);		   \
	__MODULE_PARM_TYPE(name, #type)

name既是用户看到的参数名,又是模块内接受参数的变量; 

type指定参数类型.

perm指定了在sysfs中相应文件的访问权限。访问权限与linux文件爱你访问权限相同的方式管理,如0644,或使用stat.h中的宏如S_IRUGO表示。

0表示完全关闭在sysfs中相对应的项。

3. 完整测试例程如下:

/*
 * a simple kernel module: hello
 *
 * Copyright (C) 2020 
 *
 * Licensed under GPLv2 or later
 */
#include 
#include 

#define MY_MAJOR 0x09
static int global_val_test = MY_MAJOR;
module_param(global_val_test, int, 0644);
static int __init hello_init(void)
{
        printk(KERN_INFO "global_val_test = %d\n", global_val_test);
        if (global_val_test == 9)
                printk(KERN_INFO "hello my world enter\n");
        else
                printk(KERN_INFO "hello world enter\n");
        return 0;
}

module_init(hello_init);

static void __exit hello_exit(void)
{
        printk(KERN_INFO "hello World exit\n");
}
module_exit(hello_exit);

MODULE_AUTHOR("xxxx ");
MODULE_LICENSE("GPS v2");         //模块许可证声明,一般用GPL v2
MODULE_VERSION("1.0.0");
MODULE_DESCRIPTION("A simple hello world module");
MODULE_ALIAS("a simplest module"); //别名

Makefile如下:

KVERS = $(shell uname -r)

obj-m := first_hello.o
first_hello-objs := hello.o

build: kernel_modules

kernel_modules:
        make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules

clean:
        make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

编译方法:make

加载模块:insmod first_hello.ko  global_val_test=5

查看log方法:tail /var/log/messages

或者可以通过:cat /sys/module/first_hello/parameters/global_val_test 查看参数的值.

完整源码见:

https://download.csdn.net/download/sinat_29891353/12461625

你可能感兴趣的:(内核开发,linux,驱动开发)