Linux设备驱动程序第三版学习笔记--构造和运行模块
zhenyaqi 2008-12-12
装载驱动:
#include <linux/init.h>
定义的宏
__init __initdata //模块始初化的函数或数据标记,标记为初始化的项目会在初始化结束后丢弃;
__exit __exitdata //模块清除阶段的函数或数据标记,标记为清除化项目会在内核示被配置为可卸载模块的情况下被丢弃。
//内核将以上相应的目标对象放置在可执行文件的特殊ELF段中而让这些标记起做
内核源码中的宏定义:
#define __init __section(.init.text) __cold
#define __initdata __section(.init.data)
#define __exit __section(.exit.text) __exitused __cold
#define __exitdata __section(.exit.data)
//用来指定函数或数据所属区段,内核模块装载时从指定区段读取。如没有在指区段没有找到相应入口点,则装载失败。
定义的宏
module_init ( __init func ); //模块装载入口
module_exit ( __exit func ); //模块卸载出口 如果未定义,则表明该驱动无法卸载
内核源码中的宏定义:
#define module_init(initfn) \
static inline initcall_t __inittest(void) \
{ return initfn; } \
int init_module(void) __attribute__((alias(#initfn)));
#define module_exit(exitfn) \
static inline exitcall_t __exittest(void) \
{ return exitfn; } \
void cleanup_module(void) __attribute__((alias(#exitfn)));
//目前本人还看不懂这段代码,哪位高手看明白的,请帮我解释一下,谢谢。
#include <linux/module.h> //设备驱动必须包含的头文件,包含可装载模块需要的大量符号和函数的定义
常用宏:
MODULE_LICENSE ( "Daul BSD/GPL" );//为模块指定代码所使用的许可证,有许多许可证类型。这里就不列举了。
//如果模块没有显式地标记内核可识别的许可证,则会被假定为专有的。内核加载这种模块就会抱怨内核被“污染”。
MODULE_AUTHOR ( AUTOHR ); //模述模块作者
MODULE_DESCRIPTION ( description );//对模块的描述信息
MODULE_VERSION ( version ); //指定模块版本
MODULE_DEVICE_TABLE ( table_information );//模块设备表信息
MODULE_ALIAS ( alternate_information ); //指模块的相关文档信息
EXPORT_SYMBOL ( symbol_name );
EXPORT_SYMBOL_GPL ( symbol_name );
//当需要模块层叠技术时(如:msdos文件系统依赖于由fat模块导出的符号),应该了解导出内核符号的用法。
//EXPORT_SYMBOL_GPL使得要导出的模块只能被GPL许可证下的模块使用。符号必须在模块文件的全局部分导出,不能在函数中导出。
//因为上面这两上宏将被扩展为一个特殊变量的声明,而该变量必须是全局的。该变量将在模块可执行文件的特殊部分(ELF段)保存。
//装载时,内核通过这个段来寻找模块导出的变量。
//更多宏定义请查看该头文件注释
#include <linux/moduleparam.h>
常用宏:
module_param ( variable, type, perm );
//用来创建模块参数的宏,用户可在装载模块时调整这些参数的值。
//type类型:
// bool charp(字符指针) int invbool(反转逻辑) long short ushort uint ulong.
module_param_array ( name, type, num, perm );
//以上perm的值在 <linux/stat.h>中定义
//如果perm被设置为0,就不会有对应的sysfs入口点,否则模块参数会在/sys/module中出现。
//S_IRUGO,任一用户均可以读取:记忆方法:S=status(状态)IR=ReadOnly(只读) UGO=user,group,other(用户,用户组,其它)
//S_IWUSE,只有root可以修改该参数
#include <linux/kernel.h>