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, &param_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 <linux/init.h>
#include <linux/module.h>

#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 <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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章