本科大三时期,学习了一年的嵌入式程序设计。最近一段时间,会将那段时间的学习过的资料和内容进行整理,陆续发出来。
Linux驱动程序设计过程中,提到的模块概念与我们在软件工程中提到的模块概念并不相同。在软件工程概念中,我们提到模块的概念具有抽象性。但在Linux驱动开发中,模块是具有独立功能的程序实体,它可以被单独编译,但不能独立运行。它的作用是为内核或其他内核模块提供使用功能的代码块。
众所周知,Linux系统分为用户空间和内核空间。模块即运行在内核空间,并且不可以使用C库函数,直接或间接的为应用程序服务。而应用程序运行在用户空间。Linux系统遵循一切皆文件的原则,我们也可以说是,一个模块可以看做一个设备驱动。
我们先来看一个最基本的模块:
#include <linux/module.h> #include <linux/kernel.h> MODULE_LICENSE ("GPL"); int __init init_module (void) { printk (KERN_INFO "The first module\n"); return 0; } void __exit cleanup_module (void) { printk (KERN_INFO "The module has uninstalled\n"); }
我们可以很清晰的看到程序分为三个部分(忽略掉头文件部分)。这三部分也是一个模块必须具备的三个要素:
1.license声明:MODULE_LICENSE("GPL")或MODULE_LICENSE("DualBSD/GPL")
必须对模块进行license声明,否则后续操作中,不能将当前模块插入到系统内核中。
2.模块初始化函数:init_module(void);
模块初始化函数是模块被加载的时候执行的第一个函数。
3.模块卸载函数:cleanup_module(void);
模块卸载函数是模块从内核中被卸载的时候执行的函数。
接下来,我们将这个基本模块插入到Linux内核中。笔者使用的系统版本号为:Ubuntu Kylin 14.04。
下图为我们的工作目录文件列表:
hello.c文件为我们的源文件。Makefile文件是将源代码文件编译为目标文件的脚本文件(在后续中,会专门讲述Makefile文件的内容)。
我们首先在该工作目录下输入:make命令。工作目录中会生成如下的文件:
其中,hello.ko文件为我们的目标文件,其余的文件均为中间过程文件。
之后我们输入:sudo insmod hello.ko命令。可以将我们编译的模块加载到内核中。如果当前用户是root用户可以不加sudo命令,否则,将没有权限将模块加载到内核中。
我们可以输入:lsmod命令查看加载到内核中模块。如下图:
hello即为我们加载的模块。
输入:dmesg命令。可以查看到,内核模块调用时,初始化函数输出的打印信息:The first module。如下图
输入:sudo rmmod hello命令。可以将加载的模块从内核中卸载。
输入:dmesg命令,可以查看到模块卸载时,模块卸载函数输出的信息:The module has uninstalled。如下图