#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. 函数&语法

    定义一个函数 加上一些算法,由自己定义的函数,以下是简单的规则: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 (). 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参 ...

  2. AbstractQueuedSynchronizer 原理分析 - 独占/共享模式

    1.简介 AbstractQueuedSynchronizer (抽象队列同步器,以下简称 AQS)出现在 JDK 1.5 中,由大师 Doug Lea 所创作.AQS 是很多同步器的基础框架,比如 ...

  3. Java中使用CountDownLatch进行多线程同步

    CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantL ...

  4. MacOS下Rails+Nginx+SSL环境的搭建(上)

    这里把主要的步骤写下来,反正我是走了不少弯路,希望由此需求的朋友们别再走类似的弯路.虽说环境是在MacOS下搭建,但是基本上和linux下的很相像,大家可以举一反三. 一.安装Rails 这个是最简单 ...

  5. OC基础之推荐一个旋转木马(跑马灯)效果的图片展示Demo

    这个旋转木马(跑马灯)效果的图片展示Demo,包括设定旋转方向,图片倒影,背景设置,旋转速度,开始结束,点击显示选中的图片,彩色的块展示等等功能 效果图:(源码下载:https://github.co ...

  6. Dynamics CRM 构建IN查询

    CRM中有3种查询数据的方式,分别是QueryExpression.fetchxml.linq,本篇讲述的条件IN的查询只支持前两种,linq并不支持. QueryExpression的写法如下,示例 ...

  7. 一个整数数组,有n个整数,如何找其中m个数的和等于另外n-m个数的和?

    int getSum(int* arr, int len) { int sum = 0; for (int i = 0; i < len; ++i) { sum += arr[i]; } ret ...

  8. JAVA面向对象-----访问修饰符

    访问修饰符是用来控制类.属性.方法的可见性的关键字称之为访问修饰符. 1.public 一个类中,同一包中,子类中,不同包中 2.protected 一个类中,同一包中,子类中 3.default 一 ...

  9. Linux 高性能服务器编程——TCP/IP协议族

    1 TCP/IP协议族体系结构 数据链路层:     职责:实现网卡接口的网络驱动程序,一处理数据在物理媒介(如以太网.令牌环等)上的传输.     常用协议:ARP协议(地址解析协议),RARP协议 ...

  10. HTTP状态码总结

    HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码.有些 App 端接口与 HTML 接口用的是同一个,所以做移动端开发也有必要了解一下HTTP状态码 ...