文档详情

【9】linux模块编程

沈***
实名认证
店铺
2024-11-02
PPT
1.86MB
约29页
【9】linux模块编程_第1页
1/29
【9】linux模块编程_第2页
2/29
【9】linux模块编程_第3页
3/29

单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,*,单击此处编辑母版标题样式,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,*,Linux,模块编程,1,主要内容,1,Linux,内核模块机制介绍,2,内核编程,2,微内核与单内核,Linux,的模块机制,Linux,内核模块机制介绍,1,3,先来区分进程的两种运行模式:,用户模式,(user mode),运行在用户空间,实现用户的功能,内核模式,(kernel mode,运行在内核空间,一般是实现系统相关的功能进程在自己空间中实现用户功能时,如果想使用系统功能,必须将运行级别从用户态提升到核心态才能访问内核空间,实现相关操作这个过程是通过系统调用实现的,,而用户态切换到核心态过程不可避免的存在一定开销,4,1.,两种体系结构下的内核,微内核,(,Micro kernel,),最常用的功能模块被设计成内核模式运行的一个或一组进程,通常只包含进程调度、内存管理和进程间通信几个基本功能。

其他功能,都作为单独的进程,在用户模式下运行,,通过信号量、邮箱等信息传递方式进行通信灵活、易于移植进程间通信开销大,速度相对较慢单内核,(,Monolithic kernel,,有时也叫宏内核,Macro kernel,),内核一般做为一个大进程存在,内部各功能模块可直接调用彼此的函数因为都在内核空间,没有切换开销,效率上有一定优势可扩展性和可维护性比较差5,2.Linux,的模块机制,Linux,操作系统内核是单内核,速度和性能都很高,问题在于如何提高可扩展性和可维护性?,模块,(Module),机制,用户可以根据需要,在不需要对内核重新编译的情况下,可以将,模块动态地载入或移出内核,6,模块的编写,模块的编译,模块的安装与使用,2,模块编程,7,内核模式下编程的一些限制:,不能使用用户模式下的,C,标准库,因为内核模式下不存在,libc,库,也就没有这些用户函数供调用不能使用浮点运算,因为,linux,内核切换模式时不保存处理器的浮点状态不要让内核程序进行长时间等待,因为,linux,内核是非抢占的尽可能保持代码的清洁易懂,因为内核调试不方便,简洁的代码能减少并方便后期调试8,1.,模块的编写,一个模块一般包含如下几部分,许可证声明,模块初始化和退出函数声明,初始化和退出函数,普通函数,模块导出符号表,其他操作,9,关于模块导出符号表,只有模块中导出的内核函数才可以被其它模块调用。

导出的内核符号表被看作是导出的内核接口,也可以看作内核,API,在内核中,导出内核函数使用的指令有:,10,关于模块的许可证,从,Linux,内核,2.4.10,开始,动态加载的模块必须通过,MODULE_LICENSE,宏声明此模块的许可证,否则动态加载时,会收到内核被污染,“,module license,unspecified,taints kernel.,”,的警告被内核接受的许可证有很多,最常用的的是,“,GPL,”,和,Dual BSD/GPL,书写格式如下:,MODULE_LICENSE(GPL);,MODULE_LICENSE(Dual,BSD/GPL);,11,关于模块的参数,Linux,操作系统内核模块也可带参数,定义一个模块参数,module_param(name,type,perm);,name,参数名,type,参数类型,perm,指定模块在,sysfs,文件系统下的对应文件权限,可用八进制,或,S_Ifoo,形式,如,S_IRUGO|S_IWUSR,表示任何人可读,所有者可写如,:,static char*,user_name,=“username”;,module_param(user_name,charp,S_IRUGO,);,安装模块时使用参数,insmod,module.ko,user_name,=book_user1,type,参数:,byte,字节,short,短整型,ushort,无符号短整型,int,整型,uint,无符号整型,long,长整型,ulong,无符号长整型,charp,字符指针,bool,布尔类型,12,关于模块使用计数,内核需要记录加载到系统里的每一个模块的使用情况。

在,Linux,操作系统,2.4,内核中使用两个宏来完成对模块引用计数的操作:,在,Linux,操作系统,2.6,内核中,使用下面的两个函数来完成对模块引用计数的操作:,13,编写一个内核模块,module,,向外导出两个函数,分别是“求累积和”和“求阶乘”功能编写另两个内核模块,module1,、,module2,,分别使用上面,module,模块中的函数,实现计算注意路径清晰,分别在三个目录下编写,内核编写实例,14,内核调试常用函数,printk,printk,是内核使用的函数,接口和,printf,(),基本相似,可以在控制台显示多达,1024,个字符内核根据“记录级别”判断是否在终端打印消息没有指定日志级别的,printk,语句默认采用的级别是,DEFAULT_ MESSAGE_LOGLEVEL,(级别在,4,),看不到输出,因为正常输出的前提是日志输出级别小于,console_loglevel,(在内核中数字越小优先级越高)这些级别都是简单宏定义,可在,include/,linux,/,kernel.h,中查看15,#include,#include,MODULE_LICENSE(Dual,BSD/GPL);,static,int,_init,mod_init_modtest(void,);,static void _exit,mod_exit_modtest(void,);,module_init(mod_init_modtest,);,module_exit(mod_exit_modtest,);,int,sum_op(int,numdata,);,int,factorial_op(int,N);,/,初始化与退出函数,int mod_init_modtest(void),printk(KERN_INFO-Module_export_symbol,init!-n);,return 0;,void,mod_exit_modtest(void,),printk(KERN_INFO-Module_export_symbol,was deleted!-n);,/,普通函数,=,EXPORT_SYMBOL(sum_op,);,EXPORT_SYMBOL(factorial_op,);,MODULE_AUTHOR(book,author);,MODULE_DESCRIPTION(module1:Module_export_symbol-,sum_op-factorial_op,-);,MODULE_VERSION(Ver,1.0);,int sum_op(int numdata),/,用于计算比某一数字小的所有正整数的和,,char i=0;,char ret=0;,printk(KERN_INFOsum operationn);,while(i=numdata),ret+=i+;,return ret;,int,factorial_op(int,N),/,factorial_op,(),用于计算某一数字的阶乘,char i=1;,int,Nx,=1;,printk(KERN_INFOfactorial,operationn);,if(N=0),return,Nx,;,for(;i,=,N;i,+),Nx,=,Nx,*i;,return,Nx,;,module.c,16,#include,#include,MODULE_LICENSE(Dual,BSD/GPL);,static,int,_init mod_init_modtest1(void);,static void _exit mod_exit_modtest1(void);,module_init(mod_init_modtest1);,module_exit(mod_exit_modtest1);,static char*,user_name,=,book_user,;,static,int,num_operator,=0;,extern,int,sum_op(int,);,int,mod_init_modtest1(void),int,result=0;,printk(KERN_INFOHello,I,am module 1!n);,printk(KERN_INFO%s,Welcome,to use this,sum_op!n,user_name,);,result=sum_op(,num_operator,);,printk(KERN_INFO1+.+%d =%dn,num_operator,result);,return 0;,void mod_exit_modtest1(void),printk(KERN_INFOModule,1:Goodbye%,sn,user_name,);,module_param(,user_name,charp,S_IRUGO);,module_param(,num_operator,int,S_IRUGO);,MODULE_AUTHOR(book,author);,MODULE_DESCRIPTION(Simple,Module 1,used to,sum_op,);,MODULE_VERSION(Ver,1.0);,module1.c,声明为内核模块的参数,改成,KERN_ALERT,级别试试。

安装模块时不提供参数时,缺省的参数值,module1,用到了,module,中的导出符号,其,makefile,中会有一句:,KBUILD_EXTRA_SYMBOLS=./module/,Module.symvers,17,#include,#include,MODULE_LICENSE(Dual,BSD/GPL);,static,int,_init mod_init_modtest2(void);,static void _exit mod_exit_modtest2(void);,module_init(mod_init_modtest2);,module_exit(mod_exit_modtest2);,static char*,user_name,=,book_user,;,static,int,num_operator,=0;,extern,int,factorial_op(int,);,int,mod_init_modtest2(void),int,result=0;,printk(KERN_INFOHello,I,am module 2!n);,printk(KERN_INFO%s,Welcome,to use this,factorial_op!n,user_name,);,result=factorial_op(num_operator);,printk(KERN_INFO%d!=%dn,num_operator,result);,return 0;,void mod_exit_modtest2(void),printk(KERN_INFOModule,2:Goodbye%,sn,user_name,);,module_param(user_name,charp,S_IRUGO);,module_param(num_operator,int,S_IRUGO);,MODULE_AUTHOR(book,author);,MODULE_DESCRIPTION(Simple,Module 2,used to,factoria。

下载提示
相关文档
正为您匹配相似的精品文档