#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> MODULE_LICENSE("GPL"); static int year=2013; MODULE_PARM(year,"i"); int hello_init()
{
printk(KERN_WARNING"Hello World %d!\n",year);
return 0;
} void hello_exit()
{
printk("Hello Exit!\n");
} module_init(hello_init);
module_exit(hello_exit);

1.在包含任何头文件前,必须先预定义符号__KERNEL__,这个符号用于控制选择头文件的哪一部分。

2.另一个很重要的符号就是MODULE,必须在包含<linux/module.h>前定义这个符号,它用于告诉头文件,这是一个模块,如果编译进内核,必须去掉该定义。

3.模块加载函数(必需):安装模块时被系统自动调用的函数,通过module_init宏来指定。

4.模块卸载函数(必需):卸载模块时被系统自动调用的函数,通过module_exit宏来指定。

5.许可证申明(可选):宏MODULE_LICENSE被用来告知内核,该模块带有一个许可证,没有这样的说明,加载模块时内核会抱怨。有效的许可证有"GPL","GPL v2","GPL and additional rights","Dual BSD/GPL","Dual MPL/GPL"和“Proprietary"。

6.模块参数(可选):通过宏MODULE_PARM指定模块参数,模块参数用于在加载模块时传递参数给它。

MODULE_PARM(name,type)有两个参数,name是模块参数的名称,type是这个参数的类型,类型包括以下几种:

b:比特型    h:短整型    i:整型    l:长整型    s:字符串型

在传递字符串型的参数时,这个模块参数需要在模块中用char* 来声明,系统会自动为其分配内存空间。

例如:

int a = 3;

char* st;

MODULE_PARM(a,"i");

MODULE_PARM(st,"s");

7.模块的编译工作由gcc -c 命令来完成。例如:

#gcc -c -I/usr/src/linux-headers-2.6.32-48/include hello.c

8.加载 insmod    (insmod hello.o)

9.卸载 rmmod    (rmmod hell)

10.查看 lsmod

11.加载 modprobe

modprobe如同insmod,也是加载一个模块到内核。它的不同之处在于它会查看要加载的模块,看它是否还依赖于其他模块,如果是modprobe找到这些模块,把他们先加载到内核。

12.为了确定模块是否可以被安全的卸载了,系统为每个模块保留了一个使用计数(lsmod可查看),用于记录正在使用该模块的用户数,只有当使用计数=0时,模块才可以被卸载。

以下3个宏在内核中用来维护使用计数:

MOD_INC_USE_COUNT:模块计数加1

MOD_DEC_USE_COUNT:模块计数减1

MOD_IN_USE:模块计数非0时返回真


内核模块开发过程中需特别注意以下几点:

1.在使用gcc编译模块时使用-c编译选项

2.在gcc编译选项中定义宏:_DMODULE和 -D__KERENL__

或直接在源文件中定义这两个宏:

#define MODULE

#define __KERNEL__

3.在使用gcc编译内核模块时,需要通过增加编译选项:-I/XXX/include  来指定内核源代码的头文件目录,并且还要保证内核源代码必须是配置过(make menuconfig),make dep过的。

注:XXX代表内核源代码的绝对路径,如:/usr/src/linux-headers-2.6.32-48/

4.版本不匹配

内核模板的版本是由其所依赖的内核源代码版本所决定的,位于内核源代码所处的顶层Makefile中,如:

VERSION = 3
PATCHLEVEL = 9
SUBLEVEL = 2
EXTRAVERSION =

当此版本与正在运行的内核版本(可通过uname -r 查询)不一致时,内核模块将无法插入内核。

解决办法:

1.使用insmod -f  强行插入

2.修改内核源代码顶层Makefile中的版本信息来与uname -r查看到的一致。

hello 内核模块的更多相关文章

  1. Linux内核模块开发基础【转】

    本文转载自:http://blog.csdn.net/coding__madman/article/details/51298180 1. 什么是内核模块 内核模块具有以下两个特点:1. 模块本身并不 ...

  2. linux 使用/proc文件系统 实现用户空间与内核模块之间通信

    项目中可能会用到用户态和内核模块之间进行通信的功能.想到linux系统本身很多通信都是通过/proc文件系统来的,比如修改网络中连接跟踪表连接数限制/proc/sys/net/netfilter/nf ...

  3. Linux内核模块设计

    内核的设计有两种方式:单内核和微内核,两者各有优劣,关于两者的比较可以参见wiki.windowds和Solaris采用微内核结构. Linux内核采用单内核结构,设计比较简单,但单内核的理念是把所有 ...

  4. secure boot(安全启动)下为内核模块签名

    上一篇随笔中提到了如何在secure boot下安装Nvidia显卡驱动 >>上一篇随笔 如果不需要安装Nvidia显卡驱动,而且要生成密钥,可以参考>> 这篇文章 这里假设生 ...

  5. 5.linux内核模块基础,内核模块学习

    linux内核模块基础 一.定义 Linux 内核的整体结构非常庞大,其包含的组件也非常多,如何使用这些组件呢: 方法 1:把所有的组件都编译进内核文件,即:zImage 或 bzImage,但这样会 ...

  6. Neusoft(3)增加自己的内核模块

    Linux版本 Ubuntu12.04LTS,内核版本为3.2.0-26-generic-ape 具体方法如下: 1.建立源文件,假设文件目录为path,文件名为hello.c源代码如下: #incl ...

  7. Linux内核模块简介

    一. 摘要 这篇文章主要介绍了Linux内核模块的相关概念,以及简单的模块开发过程.主要从模块开发中的常用指令.内核模块程序的结构.模块使用计数以及模块的编译等角度对内核模块进行介绍.在Linux系统 ...

  8. Ubuntu 编译安装 Linux 4.0.5 内核,并修复 vmware 网络内核模块编译错误

    . . . . . 今天把 Ubuntu 14.04 升级到了最新的 4.0.5 的内核版本,本来不打算记录下来的,但是升级的过程中确实遇到了一些问题,所以还是记录下来,分享给遇到同样问题的猿友. 先 ...

  9. Openvswitch原理与代码分析(3): openvswitch内核模块的加载

      上一节我们讲了ovs-vswitchd,其中虚拟网桥初始化的时候,对调用内核模块来添加虚拟网卡.   我们从openvswitch内核模块的加载过程,来看这个过程.   在datapath/dat ...

  10. Linux中mod相关的命令 内核模块化 mod相关命令都是用来动态加载内核模块/驱动程序模块

    Linux中mod相关的命令 内核模块化   mod相关命令都是用来动态加载内核模块/驱动程序模块 http://baike.baidu.com/link?url=lxiKxFvYm-UfJIxMjz ...

随机推荐

  1. Python中enumerate用法详解

    enumerate()是python的内置函数.适用于python2.x和python3.xenumerate在字典上是枚举.列举的意思enumerate参数为可遍历/可迭代的对象(如列表.字符串)e ...

  2. 利用Python进行数据分析——Numpy基础:数组和矢量计算

    利用Python进行数据分析--Numpy基础:数组和矢量计算 ndarry,一个具有矢量运算和复杂广播能力快速节省空间的多维数组 对整组数据进行快速运算的标准数学函数,无需for-loop 用于读写 ...

  3. Codeforces Round #305 (Div. 2) A. Mike and Fax 暴力回文串

     A. Mike and Fax Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/548/pro ...

  4. Go 语言指向指针的指针

    如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量. 当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址: 指向指针的指针变量声 ...

  5. Latex:TexStudio的使用

    http://blog.csdn.net/pipisorry/article/details/54565608 Texsdudio 快捷键 The keyboard shortcuts can be ...

  6. Weblogic 12c 集群环境搭建

    本文是在windows7操作系统下配置的,jdk版本1.7 ,weblogic版本12.1.3.0.0. 搭建集群前的规划 其中AdminServer是总控制端,server1.server2.ser ...

  7. [CSDN_Markdown] Markdown基本语法

    简介 本文介绍Markdown的基本使用方法: 使用标题 加粗.斜体 分割线 列表 引用 我写博客一般将可以独立的内容分节,每一节有一个标题,标题的字体应该与正文的字体有点区别.两个相邻节之间使用分割 ...

  8. [OpenCV]拓展图像边界

    图像处理中经常遇到使用当前像素邻的像素来计算当前像素位置的某些属性值,这样就会导致边界像素处越界访问,一般有两种方法解决这种问题:只对不越界的像素进行处理:对图像边界进行拓展,本文主要介绍如何使用Op ...

  9. WmS详解(二)之如何理解Window和窗口的关系?基于Android7.0源码

    上篇博客(WmS详解(一)之token到底是什么?基于Android7.0源码)中我们简要介绍了token的作用,这里涉及到的概念非常多,其中出现频率最高的要数Window和窗口这一对搭档了,那么我们 ...

  10. JVM垃圾回收总结

    来自Oracle官方文档,对JVM GC知识整理的清晰易懂,查资料还是看官方的好! 1 GC步骤简述 步骤1:标记 (Marking) 根据对象引用关系,将未被任何对象引用的对象实例标记出来,如下图中 ...