### module_param 宏详解 #### 一、概述 在Linux内核编程中,为了实现对模块参数的管理和访问,内核提供了一套完善的机制。`module_param` 是一个非常重要的宏,它允许开发者向内核模块传递参数,并且能够通过 sysfs 文件系统访问这些参数。这对于调试和配置内核模块具有重要意义。 #### 二、`module_param` 的定义与作用 `module_param` 宏定义在 `include/linux/moduleparam.h` 文件中,其定义如下: ```c #define module_param(name, type, perm) \ module_param_named(name, name, type, perm) ``` 这个宏接受三个参数: 1. **name**:要传递的参数变量名。 2. **type**:变量的数据类型。 3. **perm**:访问参数的权限。 #### 三、权限参数 `perm` `perm` 参数用于指定参数在 sysfs 文件系统中所对应的文件节点的权限。这些权限值来源于 `<linux/stat.h>` 头文件。例如: - `S_IRUSR`: 用户读权限。 - `S_IWUSR`: 用户写权限。 - `S_IXUSR`: 用户执行权限。 - `S_IRGRP`: 组读权限。 - `S_IWGRP`: 组写权限。 - `S_IXGRP`: 组执行权限。 - `S_IROTH`: 其他用户读权限。 - `S_IWOTH`: 其他用户写权限。 - `S_IXOTH`: 其他用户执行权限。 #### 四、权限参数的应用示例 假设我们想要创建一个参数,使得所有用户都可以读取它,但只有 root 用户可以修改它,我们可以这样定义: ```c module_param(howmany, int, S_IRUGO | S_IWUSR); ``` 这里 `S_IRUGO` 表示所有用户(user, group, other)都可以读取该参数,而 `S_IWUSR` 表示仅 root 用户可以写入。这样,当我们加载模块后,在 `/sys/module/模块名/parameters/howmany` 路径下就可以找到这个参数。 #### 五、`module_param` 支持的参数类型 `module_param` 支持多种数据类型的参数,包括但不限于: 1. **bool**:布尔型值,相关变量应为 `int` 类型。真值为 1,假值为 0。 2. **invbool**:与 `bool` 相反,真值为 0,假值为 1。 3. **charp**:字符指针类型,指向用户提供的字符串。 4. **int** / **long** / **short** / **uint** / **ulong** / **ushort**:整型数值类型,带 `u` 前缀的是无符号类型。 #### 六、数组参数的支持 除了单个参数外,`module_param` 还支持数组参数。可以通过以下宏定义数组参数: ```c module_param_array(name, type, num, perm); ``` 这里的参数含义如下: - **name**:数组的名称,同时也是参数名。 - **type**:数组元素的数据类型。 - **num**:整型变量,用来记录数组元素的数量。 - **perm**:权限值。 例如,如果我们想要定义一个整型数组参数,可以这样定义: ```c static int my_array[10]; static int my_array_num = 0; module_param_array(my_array, int, my_array_num, S_IRUGO); ``` 加载模块时提供的值数量将赋给 `my_array_num` 变量,如果提供的值超过数组容量,模块加载器会拒绝加载。 #### 七、实际应用案例 下面是一个简单的模块 `hello.c`,它演示了如何使用 `module_param`: ```c #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> MODULE_LICENSE("Dual BSD/GPL"); static char *who = "world"; static int times = 1; module_param(times, int, S_IRUSR); module_param(who, charp, S_IRUSR); static int hello_init(void) { int i; for (i = 0; i < times; i++) { printk(KERN_ALERT "(%d)hello, %s!\n", i, who); } return 0; } static void hello_exit(void) { // 退出处理 } module_init(hello_init); module_exit(hello_exit); ``` 在这个例子中,`hello.c` 模块定义了两个参数:`who` 和 `times`。`who` 是一个字符串,`times` 是一个整数。这两个参数都可以被用户通过 sysfs 文件系统进行访问和修改。 #### 八、总结 `module_param` 宏在 Linux 内核开发中扮演着极其重要的角色。它不仅提供了方便的接口来处理模块参数,还确保了参数的安全性和灵活性。通过合理利用 `module_param`,开发者可以轻松地实现模块参数的配置和调试,从而提高模块的可用性和扩展性。
- 粉丝: 2022
- 资源: 22
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助