现在的位置: 首页 > 操作系统 > 正文

linux驱动学习第三天(linux内核模块)

2018年05月27日 操作系统 ⁄ 共 1720字 ⁄ 字号 评论关闭

 

一、linux内核模块简介

        静态编译,把所需要的功能都编译到linux内核,会导致生成的内核会很大,如果我们要在现有的内核中新增或删除功能,将不得不重新编译内核。

        动态编译,linux提供这样一种机制,称为模块(Module)。此机制的特点是,模块本身不被编译入内核映像,从而控制了内核的大小。内核一旦被加载,它就和内核中的其他部分完全一样。

        在linux中,使用lsmod命令可以获得系统中加载了的所有模块以及模块间的依赖关系,lsmod命令实际上读取并分析"/proc/modules"文件。内核中已加载模块的信息也存在于/sys/module目录下。

        modprobe命令比insmod命令要强大,它在加载某模块时,会同时加载该模块所依赖的其它模块。以modprobe -r filename的方式加载将同时卸载其依赖的模块。

 

二、linux内核模块程序结构

①模块加载函数(必须)

②模块卸载函数(必须)

③模块许可证声明(必须)

④模块参数(可选)

⑤模块导出符号(可选)

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

 

三、模块加载函数

        linux内核模块加载函数一般以__init标识声明,模块加载函数必须以module_init(函数名)的形式指定。返回整型值,初始化成功返回0。初始化失败时,应该返回错误编码,在linux内核里错误编码是一个负值。

 

四、模块卸载函数

        linux内和模块卸载函数一般以__exit标识声明,模块卸载函数必须以module_exit(函数名)的形式指定,不返回任何值。

 

        模块卸载函数完成与模块加载函数相反的功能:

                模块加载函数注册了XXX,则模块卸载函数应注销XXX;

                模块加载函数动态申请了内存,则模块卸载函数应释放该内存;

                模块加载函数申请了硬件资源(中断、DMA通道、I/O端口和I/O内存等)的占用,则模块卸载函数应释放这些硬件资源。

                模块加载函数开启了硬件,则卸载函数中一般要关闭。

 

五、模块参数

        用“module_param(参数名,参数类型,参数读/写权限)”为模块定义一个参数,在装载内核模块时,用户可以向模块传递参数,形式为“insmod (或modprobe) 模块名 参数名=参数值”,如果不传递,参数使用模块内定义的缺省值。

 

六、导出符号

        /proc/kallsyms文件对应着内核符号表,它记录了符号以及符号所在的内存地址。模块可以使用如下宏导出符号到内核符号表:

                EXPORT_SYMBOL(符号名);

                EXPORT _SYMBOL_GPL(符号名);

 

七、模块声明与描述

        在linux内核模块中

        MODULE_AUTHOR(author);声明模块的作者

        MODULE_DESCRIPTION(description);声明模块描述

        MODULE_VERSION(version_string);声明模块的版本

        MODULE_DEVICE_TABLE(table_info);声明模块支持的设备表

        MODULE_ALIAS(alternate_name);声明模块别名

 

八、模块的使用计数

        try_module_get(&module) 该函数用于增加模块使用计数

        module_put(&module) 该函数用于减少模块使用计数

 

九、模块的编译

Makefile文件应该与源码位于同一目录

    #make modules

 

十、使用模块绕开GPL

①内核编译时选择“可以加载模块”

②将编译的.ko文件放置在目标文件系统的相关目录中

③文件系统应包含支持新内核的insmod、lsmod、rmmod等工具。

④可使用insmod命令手动加载模块

⑤修改启动过程的rc脚本(erc/init.d/rcS),增加insmod /.../xxx.ko

抱歉!评论已关闭.