内核模块

来源:互联网 发布:淘宝网注册开店 编辑:程序博客网 时间:2024/04/27 21:44
一、模块程序结构:
    1、模块许可声明
        MODULE_LICENSE("GPL")
     如果没有模块许可声明,加载内核时,会发出抱怨。另外,很多内核函数只有遵循了GPL许可协议才能被调用。另外还有Dual BSD
许可等。        
    2、加载函数
        缺省使用     int   init_module(void)
        加载函数用于为这个模块申请资源,在加载模块时自动执行。
        返回值为1时标明加载成功,失败就返回负的错误码
    3、卸载函数
        缺省使用    void    cleanup_module(void)
        模块卸载时自动执行
注:内核模块程序没有参数时,需显示指定void
        
二、指定加载函数和卸载函数
    1、指定加载函数
        static    int    xxx_init(void)
        {
            ········
        }    
        通过宏来指定加载函数
        module_init(xxx_init);
    2、指定卸载函数
        static    void    xxx_exit(void)
        {
            ········
        }
        通过宏来指定卸载函数
        module_exit(xxx_exit)

__init是一个宏,静态编译时,所修饰的函数代码将会存放在init.text段,一般用于修饰加载函数
    init.text段和init.data段是初始化段,内核初始化完毕后,这两个段空间所占用的内存会被释放掉
__exit是一个宏,静态编译时,所修饰的函数不会被编译进内核,一般用于修饰卸载函数

数据也可被定义为__initdata__exitdata

三、常用命令
    insmod    xxx.ko      加载内核模块,后跟内核模块的名字,可用于加载外部模块和内部模块,但不会检查模块的依赖关系
    modprobe    xxx      加载内核模块,后跟模块名字,不用加.ko,只能加载内部模块,会检查模块间的依赖关系。
    modprobe    -r     xxx    卸载模块,同时卸载其依赖的模块
    lsmod                         查看系统当前已加载的模块信息,这个命令实际上是读取/proc/modules文件
    rmmod   xxx              卸载模块,不用加.ko
    modinfo  xxx             查看模块信息,后跟要查看的模块的名字。
 
   /lib/modules/3.2.0-29-generic-pae/文件夹下的 modules.dep 存放了内部模块的依赖关系,所有内部模块的依赖关系在编译内核时都会被放到这个文件中,然后再成一个二进制文件 modules.dep.bin,这样,   modprobe 就会根据 modules.dep.bin文件来寻找依赖关系。


    dmesg                         查看内核打印信息
    dmesg    -c                 查看内核打印信息并清空,需要root权限
    uname    -r                  查看当前内核版本


四、模块传参
  • 使用模块进行传参时,需要包含头文件<linux/moduleparam.h>
  • 定义参数时,需要初始化参数,如果不初始化参数,则默认使用100
1、给模块传参需要通过一个宏来实现:
module_param(name,type,permission)
name:    参数名字
type:    参数类型,可以为byte,short,ushort,int,uint,long,ulong,charp(字符指针),bool或invbool
permission: 参数权限,加载模块后,参数是以文件形式存在的。如0644,代表root用户的权限是可读可写,普通用户只能读。如果为0666,其实是和0644是一样的,因为对于内核模块来说,普通用户最多只能有读权限。如果为0000,则什么权限都没有,所以不会创建这个参数的文件。参数的文件在目录/sys/module下相应模块的文件夹中。文件的内容为参数的值
如:对于模块hello来说,存放参数的文件在/sys/module/hello/parameters文件夹中。

2、给模块传的参数为数组,也有一个宏来实现
module_param_array(name,type,&arr_argc,permission)
name:  数组名
type: 数组类型
arr_argc:  存放实际输入的数组元素个数
permission:参数权限

MODULE_PARM_DESC(parm,“xxxxxx”)
这个宏用于添加对参数的描述

五、导出符号
/proc/kallsyms对应着内核符号表,它记录了符号以及符号所在的内存地址。可使用如下的宏导出符号到内核符号表。
EXPORT_SYMBOL(符号名)
EXPORT_SYMBOL_GPL(符号名)
导出的符号可以被其他模块使用,使用前需声明一下即可。EXPORT_SYMBOL_GPL只适用于包含了GPL许可权的模块

六、模块声明与描述

MODULE_AUTHOR("······")                添加模块的作者信息
MODULE_DESCRIPTION("······")      添加模块的一些描述信息
MODULE_VERSION("version_string")    声明模块的版本
MODULE_ALIAS("alias name")                声明模块的别名








0 0
原创粉丝点击