linux 内核模块声明 MODULE_LICENSE

本文介绍Linux模块编程的基础,包括必须包含的头文件、模块初始化与清除函数,以及如何使用moduleparam.h进行参数传递。此外,还讲解了描述性声明的作用,如模块许可、作者、描述、版本、别名及设备表。

编写模块必须先包含下面两句:

//这个头文件包含了许多符号与函数的定义,这些符号与函数多与加载模块有关
#include <linux/module.h>               

//这个头文件包含了你的模块初始化与清除的函数
#include <linux/init.h>                      

另外,如果你的模块需要用到参数传递,那么你可能就要包含 moduleparam.h 这个头文件了。

再者,模块里常包含一些描述性声明,如:

MODULE_LICENSE("GPL");          // "GPL" 是指明了 这是GNU General Public License的任意版本
                                // “GPL v2” 是指明 这仅声明为GPL的第二版本
                                // "GPL and addtional"
                                // "Dual BSD/GPL"
                                // "Dual MPL/GPL"
                                // "Proprietary"  私有的
                                // 除非你的模块显式地声明一个开源版本,否则内核会默认你这是一个私有的模块(Proprietary)。

MODULE_AUTHOR                   // 声明作者
MODULE_DESCRIPTION              // 对这个模块作一个简单的描述,这个描述是"human-readable"的
MODULE_VERSION                  // 这个模块的版本
MODULE_ALIAS                    // 这个模块的别名
MODULE_DEVICE_TABLE             // 告诉用户空间这个模块支持什么样的设备

 

 

<think>我们正在讨论的是Linux内核模块编程问题。用户之前提供了模块元信息声明代码,但遇到了“应输入类型说明符”的错误。这个错误通常发生在C语言中,当编译器期望一个类型说明符(如int, void等)但未找到时出现。在内核模块中,元信息声明(如MODULE_LICENSE)是宏,它们必须放在全局作用域,且不能位于函数内部。 根据用户提供的代码片段: ```c MODULE_LICENSE("GPL"); MODULE_AUTHOR("abin"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); ``` 这些宏应该放在源文件的全局作用域,通常在文件顶部(在#include之后)或者函数外部。如果这些宏被错误地放在了函数内部,就会导致编译器报错,因为函数内部只能包含语句和声明,而MODULE_*宏实际上是在展开后生成特定的数据结构(属于声明),所以它们必须放在函数外部。 因此,解决方法如下: 1. 确保这些宏不在任何函数内部(包括init_module和cleanup_module等函数)。 2. 通常,它们放在头文件包含之后,函数定义之前。 例如,正确的放置方式: ```c #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("abin"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); static int __init example_init(void) { // 初始化代码 return 0; } static void __exit example_exit(void) { // 清理代码 } module_init(example_init); module_exit(example_exit); ``` 如果用户已经这样做了,那么可能是其他原因,比如缺少必要的头文件(如<linux/module.h>)或者拼写错误(如宏名写错)等。但根据错误信息“应输入类型说明符”,最可能的原因还是位置不正确。 另外,注意:MODULE_*宏后面不需要分号,但是用户提供的代码中是有分号的,这是正确的,因为宏展开后需要分号结束声明。 因此,总结解决方法: - 检查宏的位置,确保在函数外部(全局作用域)。 - 确保包含了<linux/module.h>头文件。 如果问题仍然存在,请检查编译器错误信息的具体位置,确认是否有其他语法错误。</think>### Linux内核模块元信息提示"应输入类型说明符"错误解决方法 当在Linux内核模块开发中出现"应输入类型说明符"错误时,通常是由于元信息声明位置不正确或语法问题导致的。以下是系统化的解决方法: #### 错误原因分析 1. **元信息声明位置错误** MODULE_*宏必须放在全局作用域,**不能**在函数内部声明 ```c // 错误示例:在函数内部声明 static int __init my_init(void) { MODULE_LICENSE("GPL"); // 会导致"应输入类型说明符"错误 ... } ``` 2. **头文件缺失** 缺少必要的内核头文件声明 ```c #include <linux/module.h> // 必须包含此头文件 ``` 3. **宏语法错误** 宏参数格式不正确或缺少分号 ```c MODULE_LICENSE(GPL) // 错误:缺少引号 MODULE_AUTHOR("abin") // 错误:缺少分号 ``` #### 正确解决方案 1. **确保全局作用域声明** 所有MODULE_*宏必须在函数外部声明: ```c #include <linux/module.h> #include <linux/init.h> // 正确位置:全局作用域 MODULE_LICENSE("GPL"); MODULE_AUTHOR("abin"); MODULE_DESCRIPTION("Simple module"); MODULE_VERSION("0.01"); static int __init my_init(void) { ... } // 初始化函数 ``` 2. **验证头文件包含** 确保包含所有必需头文件: ```c #include <linux/module.h> // MODULE_*宏定义 #include <linux/kernel.h> // printk函数 #include <linux/init.h> // __init/__exit宏 ``` 3. **检查宏语法规范** 每个宏必须满足: - 字符串参数用双引号包裹 - 以分号结束 - 无额外空格 ```c MODULE_LICENSE("GPL"); // 正确 MODULE_LICENSE( "GPL " ); // 错误:多余空格 ``` 4. **编译前代码检查** 使用内核开发工具验证: ```bash make C=2 M=$(pwd) # 启用额外代码检查 ``` #### 完整正确示例 ```c #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> // 元信息声明(全局作用域) MODULE_LICENSE("GPL"); MODULE_AUTHOR("abin"); MODULE_DESCRIPTION("A simple example Linux module"); MODULE_VERSION("0.01"); // 初始化函数 static int __init example_init(void) { printk(KERN_INFO "Module loaded\n"); return 0; } // 清理函数 static void __exit example_exit(void) { printk(KERN_INFO "Module unloaded\n"); } module_init(example_init); module_exit(example_exit); ``` #### 验证步骤 1. 编译模块: ```bash make -C /lib/modules/$(uname -r)/build M=$(pwd) modules ``` 2. 检查元信息: ```bash modinfo your_module.ko ``` 输出应包含: ``` license: GPL author: abin description: A simple example Linux module version: 0.01 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值