#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. CRM客户关系管理系统(四)

    kingadmin设计开发 4.4.根据list_display配置生成数据列表 (1)kingadmin/views.py (2)kingadmin/templates/kingadmin/tabl ...

  2. iOS开源照片浏览器框架SGPhotoBrowser的设计与实现

    简介 近日在制作一个开源加密相册时附带着设计了一个照片浏览器,在进一步优化后发布到了GitHub供大家使用,该框架虽然没有MWPhotoBrowser那么强大,但是使用起来更为方便,操作更符合常规相册 ...

  3. springMVC源码分析--ModelFactory

    ModelFactory是用来维护Model的,具体包含两个功能 (1)初始化Model (2)处理器执行后将Model中相应的参数更新到SessionAttributes中 1.初始化Model其实 ...

  4. The type org.apache.commons.lang.exception.NestableRuntimeException cannot be resolved.

    最近自己练手写项目时,遇到了这个错,写个文章记录下, The type org.apache.commons.lang.exception.NestableRuntimeException canno ...

  5. 剑指Offer——联通研究院笔、面试题 (Offer已收割)

    剑指Offer--联通研究院笔.面试题 1.二叉树适宜存储什么样的数据? 树最适合用来表示( C ). A.有序数据元素 B.无序数据元素 C.元素之间具有分支层次关系的数据 D.元素之间无联系的数据 ...

  6. SpriteKit物理引擎碰撞中5个重要信息

    我们知道在SpriteKit物理引擎实际是基于Box2D! 在SpriteKit中当你设置好适当的碰撞参数后,通过遵守SKPhysicsContactDelegate,你可以选择实现2各碰撞回调方法: ...

  7. Swift变量名的一种玩法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 是的,Swift的变量名可以用任何合法的Unicode字符,这 ...

  8. Servlet配置与资源参数

    import java.io.*; import javax.servlet.*; import javax.servlet.http.*; // 继承HttpServlet 类 public cla ...

  9. Linux2.6--Linus电梯

          内核为了处理来自IO层的请求,需要进行相应的优化,因为当请求很多时,且请求的块又都几种在一块,那么如果按照顺序处理这些请求无疑是很大的时间开销,所以,我们需要寻求方法来处理这种情况(当然, ...

  10. python 远程调度进程服务与客户端

    python 远程调度进程服务与客户端 核心思想: 在本地或远程机器上创建一个进程,提供调度服务.使用了 APScheduler. 安装:APScheduler $ wget https://pypi ...