:构造和运行模块

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的实例

Linux驱动之内核加载模块过程分析

Perl 的@INC 是如何构造的? (又名影响 Perl 模块搜索位置的所有方法是啥?)

:构造和运行模块

ldd3-2 构造和运行模块:Hello World模块笔记

Linux设备驱动开发学习:构造和运行模块(未完)