Linux内核模块

Linux内核的整体结构非常庞大,其包含的组件也非常多,我们需要包含所需的部分功能组件。有两种方法:一种是将所需的功能组件编译进内核。二是,将所需的功能组件编译成独立于内核的模块,需要时动态加载进内核。通常采用第二种方式,它的好处是:

n  模块本身不被编译入内核映像,从而控制了内核的大小。

n  模块一旦被加载,它就和内核中的其他部分完全一样。

一个简单的内核模块的例子:

#include <linux/init.h>

#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)

{

  printk(KERN_INFO " Hello World enter\n");

  return 0;

}

 

static void hello_exit(void)

{

  printk(KERN_INFO " Hello World exit\n ");

}

 

module_init(hello_init);

module_exit(hello_exit);

 

MODULE_AUTHOR("Song Baohua");

MODULE_DESCRIPTION("A simple Hello World Module");

MODULE_ALIAS("a simplest module");

常用命令:/sbin/insmod, /sbin/modprobe, /sbin/lsmod, /sbin/modinfo, /sbin/rmmod

 

Linux内核模块的程序结构

    一个Linux内核模块主要由以下几部分组成:

模块加载函数(必须)

模块卸载函数(必须)

模块许可证声明(必须)

    常见的有:MODULE_LICENSE(“Dual BSD/GPL”)

模块参数(可选)

模块导出符号(可选)

模块作者等信息声明(可选)

 

模块加载函数

一般以__init标识声明,典型的加载函数的形式如下:

static int __init initialization_function(void)

{

/*初始化代码*/

}

module_init(initialization_function);

Linux 2.6内核中,可以使用request_module(const char *fmt, …)函数加载内核,如下所示:

request_module(module_name);

request_module(“char-major-%d-%d”, MAJOR(dev), MINOR(dev));

 

模块卸载函数

static void __exit cleanup_function(void)

{

/*释放代码*/

}

module_exit(cleanup_function);

 

模块参数

可以用module_param(参数名,参数类型,参数读/写权限)来定义一个参数。如:

static char *book_name = “bookname”;

static int num = 4000;

module_param(book_name, charp, S_IRUGO);

module_param(num, int, S_IRUGO);

参数类型可以是:byte, short, ushort, int , uint, long, ulong, charp, bool, invbool(布尔的反)

具体代码如下:

#include <linux/init.h>                               

#include <linux/module.h>                               

MODULE_LICENSE("Dual BSD/GPL");                                

                               

static char *book_name = "dissecting Linux Device Driver";             

static int num = 4000;                               

                               

static int book_init(void)                                

{                               

   printk(KERN_INFO " book name:%s\n",book_name);                       

   printk(KERN_INFO " book num:%d\n",num);                              

   return 0;                               

}                                

static void book_exit(void)                               

{                               

   printk(KERN_INFO " Book module exit\n ");                           

}                               

module_init(book_init);                                

module_exit(book_exit);                               

module_param(num, int, S_IRUGO);                               

module_param(book_name, charp, S_IRUGO);

                               

MODULE_AUTHOR("Song Baohua, author@linuxdriver.cn");

MODULE_DESCRIPTION("A simple Module for testing module params");

MODULE_VERSION("V1.0");

 

相应的Makefile代码:

obj-m := hello.o

obj-m += book.o

 

all:

   $(MAKE) -C /usr/src/kernels/2.6.23.1-42.fc8-i686/ M=$(shell pwd) modules

 

clean:

   rm -f *.o *.ko *.mod.o

符号导出

命令cat /proc/kallsyms可查看内核符号表。它记录了符号以及符号所在的内存地址。模块可以使用如下宏导出符号到内核符号表:

EXPORT_SYMBOL(符号名);

EXPORT_SYMBOL_GPL(符号名);只适用于包含GPL许可权的模块。

例子如下:

#include <linux/init.h>                               

#include <linux/module.h>                               

MODULE_LICENSE("Dual BSD/GPL");                               

int add_integar(int a,int b)                               

{                               

   return a+b;                            

}

int sub_integar(int a,int b)                                

{                               

   return a-b;                            

}   

EXPORT_SYMBOL(add_integar);

EXPORT_SYMBOL(sub_integar);

模块的声明与描述

MODULE_AUTHOR(author): 模块的作者

MODULE_DESCRIPTION(description):模块的描述

MODULE_VERSION(version_string):模块的版本

MODULE_DEVICE_TABLE(table_info):对于USBPCI等设备

MODULE_ALIAS(alternate_name):模块别名

 

模块的使用计数

Linux2.4中,使用MOD_INC_USE_COUNTMOD_DEC_USE_COUNT宏来管理自己被使用的计数。

Linux2.6中,提供了模块计数管理接口:int try_module_get(struct module *module):  void module_put(struct module *module);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值