声明:内容搬自阿三哥网站,只是翻译了一下。侵删。https://embetronicx.com/tutorials/linux/device-drivers/
正文如下:
这是“linux设备驱动系列”的教程。本系列的目的是提供简单实用的示例,使每个人都能以简单的方式理解这些概念。现在让我们即将学习“linux设备驱动第二部分-第一个linux设备驱动程序”。【hello world警告】在写驱动程序之前,我们先讲一些关于模块的基本信息。那我们快开始吧~~
内容速览
·1 linux设备驱动第二部分-第一个linux设备驱动程序
·2 模块信息
·2.1 许可证(license)
·2.2 作者
·2.3 模块描述
·2.3 模块版本
·1 linux设备驱动第二部分-第一个linux设备驱动程序
·2 模块信息
·许可证
·作者
·模块简介
·模块版本
这些信息被定义为宏(macro),位于 linux/module.h 中。
·2.1 许可证(license)
GPL,也就是“GNU通用公共许可证”,是一种面向软件的开源许可证。。如果您的软件是按照GPL条款进行授权的,那么它是免费-“free”的。然而,这里的“free”不是指免费软件,它也可以是付费软件。根据GPL,free意味着自由。正如GPL的支持者自豪地宣称的那样:免费就是自由,而不是免费啤酒(free as in freedom, not free beer)。
以下许可标识目前被接受为自由软件模块:
“GPL”【[GNU 公共许可证 v2 及以上版本】
“GPL v2” 【GNU 公共许可证 v2】
“GPL and additional rights” 【GPL公共许可证v2 及更多】
“Dual BSD/GPL” 【GPL公共许可证v2或BSD许可证】
“Dual MIT/GPL” 【GPL公共许可证v2或MIT许可证】
“Dual MPL/GPL” 【GPL公共许可证v2或Mozilla许可证】
以下是其他许可证标识:
“Proprietary” 【非免费产品】
还有一些双许可证的组件,但在linux上运行时,与之相关的只有GPL,所以这不是问题。比如,与GPL链接的LGPL许可证是GPL组合中的一种。
许可证标识的存在是由于以下几点因素:
1.用户想要审查他们的安装是否是免费的, modinfo 命令可以显示许可证信息。
2.社区【linux社区】可以忽略来自私有模块的bug报告。
3.供应商可以根据自己的需求标识他们的许可证。
我们可以在我们的驱动程序中添加许可证,如下图。要完成这项任务,你需要include linux/module.h 头文件。
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL v2"); MODULE_LICENSE("Dual BSD/GPL");
注意:标识许可证并不是严格必需的,但是你的模块确实应该指定什么许可证应用在你的代码上。
·2.2 作者
使用这个宏我们可以知道是谁写了这个驱动程序或者模块。所以想要知道作者姓名的用户可以使用 modinfo 显示这些信息。我们可以给我们的驱动程序(模块)添加作者姓名,如下图。为了完成这项任务,你需要include linux/module.h 头文件。
MODULE_AUTHOR("Author");
注意:使用“姓名<邮箱>”的格式或者“姓名”的格式, 如果由多个作者,就要使用多行MODULE_AUTHOR()语句来声明。
·2.3 模块描述
使用这个宏,我们可以用来描述我们的模块或者驱动程序。这样用户就可以使用 modinfo 命令得到模块描述的信息。我们可以给我们的驱动程序(模块)添加模块描述,如下图。为了完成这项任务,你需要include linux/module.h 头文件。
MODULE_DESCRIPTION("A sample driver");
·2.3 模块版本
使用这个宏我们可以给出模块或者驱动程序的版本号。这样用户就可以使用 modinfo 命令得到模块的版本信息。
版本格式:[<epoch>:]<version>[-<extra-version>] 【[ ]中的内容为可选,<>中的内容为必选】
<epoch>:无符号整数,可以用来重新启动一个版本。如果没有给出,则默认为 0 。比如版本“2:1.1”是版本“1:2.0”之后的一个版本。
<version> :此选项只能包含字母数字或者字符“.”。数字部分按照数字排序,字母部分按字母顺序排序(根据RPM或者DEB算法)。
<extra-version>:跟<version>选项类似,但是可以插入本地定制,比如“rh3”或者“rusty1”。
例子:
MODULE_VERSION("2:1.0");
static int __init hello_world_init(void) /* Constructor */ { return 0; } module_init(hello_world_init);
void __exit hello_world_exit(void) { } module_exit(hello_world_exit);
printk(KERN_INFO "Welcome To our simple driver");
/***************************************************************************//** * file hello_world_module.c * * details Simple hello world driver * * author EmbeTronicX * * *******************************************************************************/ #include<linux/kernel.h> #include<linux/init.h> #include<linux/module.h> /* ** Module Init function */ static int __init hello_world_init(void) { printk(KERN_INFO "Welcome to EmbeTronicX "); printk(KERN_INFO "This is the Simple Module "); printk(KERN_INFO "Kernel Module Inserted Successfully... "); return 0; } /* ** Module Exit function */ static void __exit hello_world_exit(void) { printk(KERN_INFO "Kernel Module Removed Successfully... "); } module_init(hello_world_init); module_exit(hello_world_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("EmbeTronicX <embetronicx@gmail.com>"); MODULE_DESCRIPTION("A simple hello world driver"); MODULE_VERSION("2:1.0");
obj-m += hello_world_module.o KDIR = /lib/modules/$(shell uname -r)/build all: make -C $(KDIR) M=$(shell pwd) modules clean: make -C $(KDIR) M=$(shell pwd) clean
·5.4 得到模块细节信息
为了得到模块更多的信息(作者、支持的选项),我们可以使用 modinfo 命令。
举个栗子,
modinfo hello_world_module.ko
----------------分割线----------------
现在我们知道了linux设备驱动程序从哪里开始。谢谢你的阅读。在我们下一小节的教程中,我们会看到怎么给linux设备驱动程序传递参数~~~