Linux 驱动学习笔记之模块

 

  1.  一个Linux内核模块主要由下面几个部分组成。
    1. 1模块加载函数(一般需要)。

        当通过insmod或modprobe命令加载内核模块时,模块的加载函数就会自动被内核执行,完成本模块的相关初始化工作。

            1.2 模块卸载函数(一般需要)。

当通过rmmod命令卸载某模块时,模块的卸载函数就会自动被内核执行,完成与模块加载函数相反的功能。

 

           1.3 模块许可声明(必须)

许可证(LICENSE)声明描述内核模块的许可权限,如果不声明LICENSE,模块被加载时,将收到内核被污染(kernel tainted)的警告。

在Linux 2.6内核中,可接受的LICENSE包括’GPL’,  ’GPL v2’,  ’GPL and additional rights’,   ‘Dual BSD/GPL’,   ‘Dual MPL/GPL’ 和‘Proprietary’

大多数情况下,内核模块应该遵循GPL兼容许可协议。Linux 2.6内核模块最常见的是以MODULE_LICENSE(“Dual BSD/GPL”)语句声明模块采用BSD/GPL双LICENSE。

 

           1.4 模块参数(可选)。

模块参数是模块被加载的时候可以被传递给它的值,它本身对应模块内部的全局变量。

 

          1.5 模块导出符号(可选)。

内核模块可以导出符号(symbol , 对应函数或变量),这样其他模块可以使用本模块中的变量或函数。

 

          1.6 模块作者等信息声明。

 

 

2. 模块加载函数

    Linux内核模块记载函数一般以__init标志声明,典型的模块加载函数如:

    static int __init initialization_function(void)

    {

    /*init code*/

}

module_init(initialization_function);

模块加载函数必须以”module_init(函数名)”的形式被指定。它返回整型值,若初始化成功,应返回0;若初始化失败,应返回错误编码。

 

3. 模块卸载函数

    Linux内核模块记载函数一般以__exit标志声明,典型的模块卸载函数如:

    static void __exit cleanup_function(void)

    {

    /*cleanup code*/

}

Module_exit(cleanup_function);

 

模块卸载函数在模块卸载的时候执行,不返回任何值,必须以”module_exit(函数名)”的形式来指定。

通常来说,模块卸载函数要完成与模块加载函数相反的功能,如下所示:

  1. 若模块加载函数注册了XXX,则模块卸载函数应该注销XXX.
  2. 若模块加载函数动态申请了内存,则模块卸载函数应该释放该内存。
  3. 若模块加载函数申请了硬件资源(中断,DMA通道,I/O端口和I/O内存等)的占用,则模块卸载函数应该释放这些资源。
  4. 若模块加载函数开启了硬件,则模块卸载函数中一般要关闭。

 

4. 模块参数

   我们可以用’module_param(参数名,参数类型,参数读/写权限)’为模块定义一个参数,例如下列代码定义了1个整型参数和1个字符指针参数:

static char *test_name = “Test name is DEREN”;

static int num = 100;

module_param(num, int, S_IRUGO);

module_param(test_name, charp, S_IRUGO);

 

在加载内核模块时,用户可以向模块传递参数,

形式以”insmode(或modprobe) 模块名 参数名 =  参数值”,如果不传递,参数将使用模块内部定义的缺省值(默认值)。

参数类型可以是byte,short,ushort,int,uint,long,ulong,charp(字符指针),bool或invbool(布尔的反),在模块被编译时会将module_param中声明的参数类型与变量低定义的类型进行比较,判断是否一致。

例子:

#include <linux/init.h>

#include <linux/module.h>

MODULE_LICENSE(“Dual BSD/GPL”);

 

static char *test_name = “Test name is DEREN”;

static int num = 100;

 

static int book_init(void)

{

    printk(KERN INFO “book  name:%s\n”, test_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(test_name, charp, S_IRUGO);

 

对上述模块运行”insmod book.ko”命令加载,相应输出都为模块内的默认值,通过查看”var/log/messages”日志文件可以看到输出:

book name:The test name is DEREN

book num:100

 

当用户运行”insmod book.ko book_name=’test book’ nun=200 ”命令时,输出的是:

book name :test book

book num:200

 

5. 模块声明与描述

在Linux内核模块中,我们可以使

MODULE_AUTHOR,MODULE_DESCRIPTION,MODULE_VERSION,MODULE_DEVICE_TABLE,

MODULE_ALIAS分别声明模块的作者,描述,版本,设备表,别名。如:

MODULE_AUTHOR(author);

MODULE_DESCRIPTION(description);

MODULE_VERSION(version_string);

MODULE_DEVICE_TABLE(table_info);

MODULE_ALIAS(alternate_name)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值