Linux 驱动开发之内核模块分析3

Linux 驱动开发之内核模块分析3(基于Linux6.6)---内核模块编译 Makefile分析

一、module_param() 定义

通常在用户态下编程,即应用程序,可以通过main()的来传递命令行参数,而编写一个内核模块,则通过module_param() 来传参。

include/linux/moduleparam.h

#define module_param(name, type, perm)				\
	module_param_named(name, name, type, perm)

通过宏module_param()定义一个模块参数:

module_param(name, type, perm);

参数的意义:

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

type      表示参数的数据类型,是下列之一:byte, short, ushort, int, uint, long, ulong, charp, bool, invbool;     

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

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

二、module_param() 使用方法

在 Linux 内核模块中,module_param() 宏用于将模块的参数暴露给内核,并允许用户通过模块加载时传递参数值。这些参数可以在内核中被访问和修改,通常用于调整模块行为。

2.1、module_param() 宏的基本用法

module_param() 宏的语法如下:

module_param(name, type, perm);
  • name:参数名,表示传入模块的参数变量名称。
  • type:参数的类型,通常使用以下类型:
    • int:整数类型。
    • bool:布尔值类型(truefalse)。
    • charp:字符串类型。
    • long:长整型。
    • unsigned int:无符号整数类型。
    • unsigned long:无符号长整型。
  • perm:权限设置(可选)。它控制模块参数的读写权限,通常用于设置文件的权限。例如,S_IRUGO 表示只读,S_IWUSR 表示用户可写。常用的权限设置包括:
    • S_IRUGO:只读权限(用户可以读取该参数,但不能修改)。
    • S_IWUSR:用户可写权限。
    • S_IRUSR:用户可读权限。

2.2、示例:使用 module_param() 定义模块参数

假设我们要定义几个模块参数,并在模块加载时根据这些参数的值调整模块的行为。

1. 简单的整数参数

我们将创建一个简单的模块,该模块有一个整数参数 param1,允许在模块加载时传递。

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

static int param1 = 42;  // 默认值为 42
module_param(param1, int, S_IRUGO | S_IWUSR);  // 允许读取和写入

static int __init hello_init(void) {
    pr_info("Hello, World! param1 = %d\n", param1);
    return 0;
}

static void __exit hello_exit(void) {
    pr_info("Goodbye, World!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple Hello World Kernel Module with Parameters");
2. 编译并加载模块
  • 编译模块:

  • make
    
  • 加载模块并传递参数:

  • sudo insmod hello.ko param1=100
    
  • 查看内核日志(dmesg):

dmesg | tail -n 10

你会看到类似以下的输出:

  • [ 1234.567890] Hello, World! param1 = 100
    

    这表明模块加载时,参数 param1 被设置为 100。

3. 卸载模块
sudo rmmod hello

2.3、支持不同类型的参数

1. 字符串参数(charp

你也可以使用 module_param() 宏定义一个字符串参数。例如,定义一个字符串参数 param_str

static char *param_str = "default_value";
module_param(param_str, charp, S_IRUGO | S_IWUSR);

在模块加载时,你可以通过命令行传递字符串参数:

sudo insmod hello.ko param_str="Hello, Kernel!"
2. 布尔参数(bool

布尔类型参数允许你在加载模块时通过 10 来指定布尔值:

static bool enable_feature = false;
module_param(enable_feature, bool, S_IRUGO | S_IWUSR);

加载模块时传递布尔值:

sudo insmod hello.ko enable_feature=1
3. 长整型(long)和无符号长整型(unsigned long

你可以定义长整型或无符号长整型参数:

static long param_long = 1000;
module_param(param_long, long, S_IRUGO | S_IWUSR);

static unsigned long param_ulong = 1000;
module_param(param_ulong, unsigned long, S_IRUGO | S_IWUSR);
4. 整数数组(array 类型)

内核也支持通过 module_param_array() 宏来传递数组参数。例如,传递一个整数数组:

static int param_array[5] = {1, 2, 3, 4, 5};
module_param_array(param_array, int, NULL, 0644);

在加载模块时,传递数组:

sudo insmod hello.ko param_array=10,20,30,40,50

2.4、module_param() 常见问题

  1. 参数类型不匹配:确保在使用 module_param() 时传入的类型与定义的类型匹配。如果你使用了 int 类型的参数,确保在加载时传入的参数是整数类型。

  2. 权限问题module_param() 的权限设置控制模块参数的可读写性。S_IRUGO 表示只读,S_IWUSR 表示用户可写。确保在设置权限时根据实际需求设置合适的权限。

  3. 无法修改参数值:如果在加载模块时修改参数的值,但该参数是只读的,内核会返回错误。如果需要修改参数的值,确保为该参数设置了写权限。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值