Linux内核模块

1、最简单的内核模块例子

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

static  int __init hello_init(void)

{

         printk(KERN_INFO "Hello world\n");

         return 0;

}

static void __exit hello_exit(void)

{

         printk(KERN_INFO "Goodbye world\n");

}

module_init(hello_init);

module_exit(hello_exit);

 

注释::

•    static int __init hello_init(void)

•    static void __exit hello_exit(void)

–  Static声明,因为这种函数在特定文件之外没有其它意义

–  __init标记, 该函数只在初始化期间使用。模块装载后,将该函数占用的内存空间释放

–  __exit标记 该代码仅用于模块卸载。

•    Init/exit

–  宏:module_init/module_exit

–  声明模块初始化及清除函数所在的位置

–  装载和卸载模块时,内核可以自动找到相应的函数

               module_init(hello_init);

               module_exit(hello_exit);

•    Makefile文件

obj-m := hello.o

all:

      make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules

clean:

      make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean

•    Module includes more files

obj-m:=hello.o

hello-objs := a.o b.o

2、装载和卸载模块相关命令

–  lsmod

–  insmod hello.ko

–  rmmod hello.ko

 

•    有些模块需要传递一些参数

•    参数在模块加载时传递

     #insmod hello.ko test=2

•    参数需要使用module_param宏来声明

             module_param的参数:变量名称,类型以及访问许可掩码

•    支持的参数类型

Byte, short, ushort, int, uint, long, ulong, bool, charp

Array (module_param_array(name, type, nump, perm)

例子::

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/moduleparam.h>

static int test;

module_param(test, int, 0644);

static int __init hello_init(void)

{

         printk(KERN_INFO “Hello world  test=%d \n” , test);

         return 0;

}

static void __exit hello_exit(void)

{

         printk(KERN_INFO "Goodbye world\n");

}

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("Test");

MODULE_AUTHOR("xxx");

module_init(hello_init);

module_exit(hello_exit);

 

3、

•    /proc文件系统,这是内核模块和系统交互的两种主要方式之一。

•    /proc文件系统也是Linux操作系统的特色之一。

•    /proc文件系统不是普通意义上的文件系统,它是一个伪文件系统。

•    通过/proc,可以用标准Unix系统调用(比如open()、read()、write()、 ioctl()等等)访问进程地址空间

•    可以用cat、more等命令查看/proc文件中的信息。

•    用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。

•    当调试程序或者试图获取指定进程状态的时候,/proc文件系统将是你强有力的支持者。通过它可以创建更强大的工具,获取更多信息。

 

•    create_proc_entry()  创建一个文件

•    proc_symlink()  创建符号链接

•    proc_mknod()   创建设备文件

•    proc_mkdir()   创建目录

•    remove_proc_entry()  删除文件或目录

 

4、 模块引用计数器

         Linux2.4中在linux/module.h中定义了三个宏来维护实用计数:

             __MOD_INC_USE_COUNT       当前模块计数加一
             __MOD_DEC_USE_COUNT      
当前模块计数减一
             __MOD_IN_USE              
计数非0时返回真

         在Linux2.6中,模块引用计数器由系统自动维护,所以程序中有关这些宏都可以注释掉。

•    关于符号导出列表(list of exported symbols
   Linux2.4
中会用EXPORT_NO_SYMBOLS宏,来表示不想导出任何变量或函数。

                   在Linux2.6中这个宏也已经消失。系统默认为不导出任何变量或函数。

5、模块程序编译方法的改变
    Linux2.4
中命令为:

    gcc –Wall –DMODULE –D__KERNEL__ -DLINUX –c 源文件名.c
    
其中:
         __KERNEL__
:   即告诉头文件这些代码将在内核模式下运行
         MODULE
:          即告诉头文件要给出适当的内核模块的定义
         LINUX
:              并非必要
         -Wall
:                  显示所有warning信息。

•    Linux2.6中必须写makefile。通过make命令编译程序。
     Linux2.6
中makefile的写法:(以helloworld为例)
//Makefile  obj-m += hello.o
     all: 
          make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
     clean:
          make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

         * 注意:all下一行需要有一个“Tab”键,不要写成空格或略去,不然系统无法识别,报错:nothing to be done for “all”

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值