:构造和运行模块
Posted Ven_J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了:构造和运行模块相关的知识,希望对你有一定的参考价值。
1、一个简单的hello,world的模块:
#include <linux/init.h> /* 用于指定初始化和清楚函数 */
#include <linux/module.h> /* 包含有可装载模块所需的大量符号和函数定义 */
#include <linux/kernel.h>
static int hello_init(void)
printk(KERN_ALERT "Hello, World\\n");
return 0;
static void hello_exit(void)
printk(KERN_ALERT "Goodbye, World\\n");
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL"); /* GPL许可证 */
MODULE_AUTHOR("Venjie"); /* 模块作者 */
MODULE_DISCRIPTION("A Hello, World Module"); /* 模块的简短描述 */
相应的Makefile
obj-m := hello.o
/* 如果有多个源文件的话
就加上 modules-objs := file1.o file2.o
*/
VERSION_NUM := $(shell uname -r)
KDIR := /usr/src/linux-$VERSION_NUM
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
2、核心模块与应用程序的对比
大部分的应用程序是从头到尾执行单个任务,而模块却只是预先注册自己以便服务于将来的某个请求,然后它的初始化函数就立即结束。 模块初始化的任务就是为了以后调用模块函数预先做准备; 应用程序和模块之间一个很大的区别就是:应用程序在退出时,可以不管资源的释放或者其他的清除工作,但模块的退出函数必须仔细撤销初始化函数所做的一切,否则,在系统重新引导之前某些东西就会残留在系统中。 3、装载模块和卸载模块
装载模块:
insmod hello.ko 或者
modprobe hello.ko
卸载模块:
rmmod hello.ko
insmod 是把当前的模块添加到内核中去。
modprobe是把当前模块及其依赖的模块都加载到内核中去。
4、初始化和关闭
初始化函数的定义通常如下:
static int __init initialization_function(void)
/* 这里是初始化代码 */
module_init(initialization_function);
初始化函数应该被声明为static,因为这种函数在特定文件之外没有任何意义。上述定义中的 ___init标记表示该函数仅在初始化起见使用,在模块被装载后,模块装载器就会把初始化函数丢掉,这样可以把该函数占用的内存释放出来。 module_init的使用是强制的。这个宏会在模块的目标代码中增加一个特殊的段,用于说明内核初始化函数的所在位置。没有这个定义,初始化函数永远不会被调用。
清除函数的定义:
static void __exit cleanup_function(void)
/* 这里是清除代码 */
module_exit(cleanup_function);
清除函数没有返回值,因此被声明为void。____exit修饰词标记该代码仅用于模块卸载。如果模块被直接内嵌到内核中,或者内核的配置不允许卸载模块,则被标记为____exit的函数就会被简单的丢弃。出于以上的原因,被标记为____exit的函数只能在模块卸载或者系统关闭的时候才能被调用,其他任何用法都是错误的。 module_exit声明对于帮助内核找到模块的清楚函数是必需的。 如果一个模块没有定义清除函数,则内核不允许卸载该模块。
5、初始化过程中的错误处理 我们在内核中注册设备时,要时刻铭记注册可能失败。 如果在注册设施的时候遇到任何错误,首先要判断模块是否可以继续初始化。通常,在某个注册失败后可以通过降低功能来继续运转。因此,只要可能,模块应该继续向前并继续向前尽可能提供其功能。 如果在发生了某个特定类型的错误之后无法继续装载模块,则要将出错之前的任何注册工作都撤销掉。
以上是关于:构造和运行模块的主要内容,如果未能解决你的问题,请参考以下文章
android 怎么在自定义控件中获取控件所在fragment的实例
Perl 的@INC 是如何构造的? (又名影响 Perl 模块搜索位置的所有方法是啥?)