第2章 构造和运行模块_第1页
第2章 构造和运行模块_第2页
第2章 构造和运行模块_第3页
第2章 构造和运行模块_第4页
第2章 构造和运行模块_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

152第2章构造和运行模块HelloWorld模块模块与应用程序模块的编译和加载内核符号表初始化和关闭模块参数346HelloWorld模块#include<linux/init.h>#include<linux/module.h>#include<linux/kernel.h>MODULE_LICENSE("DualBSD/GPL");

staticint

hello_init(void){

printk(KERN_ALERT"Hello,world\n"); return0;}staticvoidhello_exit(void){

printk(KERN_ALERT"Goodbye,cruelworld\n");}module_init(hello_init);module_exit(hello_exit);

HelloWorld模块编译%makemake[1]:Enteringdirectory`/usr/src/linux-2.6.10‘CC[M]/home/ldd3/src/misc-modules/hello.oBuildingmodules,stage2.MODPOSTCC/home/ldd3/src/misc-modules/hello.mod.oLD[M]/home/ldd3/src/misc-modules/hello.komake[1]:Leavingdirectory`/usr/src/linux-2.6.10'%su

root#insmod./hello.koHello,worldroot#rmmodhelloGoodbyecruelworldroot#

HelloWorld模块模块常用的一些宏MODULE_AUTHOR(author);声明模块的作者MODULE_DESCRIPTION(description);说明模块的用途MODULE_VERSION(version_string);声明模块的修订号MODULE_DEVICE_TABLE(table_info);说明模块所支持的设备MODULE_ALIAS(alternate_name);说明模块的别名EXPORT_SYMBOL(symbol);声明模块导出的符号EXPORT_SYMBOL_GPL(symbol);声明模块导出的符号152第2章构造和运行模块HelloWorld模块模块与应用程序模块的编译和加载内核符号表初始化和关闭模块参数346模块与应用程序应用程序从头至尾执行单个任务,运行在用户空间核心模块可根据需要加载、卸载加载时初始化并注册自己,然后等待服务于将来的某个请求,类似于事件驱动的编程退出时必须自己清理现场(撤销初始化函数所做的一切)只能使用内核导出的符号(函数与变量),不能使用函数库libc运行在内核空间模块与应用程序内核空间和用户空间03G4G0X虚拟地址空间内存空间物理内存PAGE_OFFSET用户空间内核空间内核空间地址与物理内存地只差一偏移量,故内核空间地址(虚地址)到内存空间地址的转换是直接的,不需经页表模块与应用程序内核空间和用户空间03G4G0X虚拟地址空间PAGE_OFFSET用户空间内核空间xx页yy页xx页yy页页表用户空间地址(虚地址)到内存空间地址的转换必需经页表内存空间物理内存模块与应用程序内核中的并发内核编程与常见应用程序编程的区别在于对并发的处理,内核代码(包括驱动)必须是可重入的,必须能够同时运行在多个上下文中。产生并发的原因Linux是多任务系统,同时运行多个进程产生中断内核定时器对称多处理器(SMP)2.6内核可抢占,在单处理器上也存在类似多处理器的并发模块与应用程序当前进程由指向当前进程控制块struct

task_struct

的指针current可获得当前进程current->comm:当前进程命令名current->pid

:当前进程ID早期版本中current为一个全局变量,在2.6中,current存放在内核栈中内核栈大小为4096B,由用户进程与内核进程共享,不要声明大的自动变量152第2章构造和运行模块HelloWorld模块模块与应用程序模块的编译和加载内核符号表初始化和关闭模块参数346模块的编译和装载编译模块模块不是独立的可执行程序,需要依赖核心才能工作,需要使用核心导出的符号,例printk()模块不能单独编译,应该用核心的构造系统来构造,即使用编译核心时所使用的编译器、链接器工具及同样的内核源代码树环境模块可放在内核源码代码树中构造也可放在内核源代码树外构造模块的编译和装载放在内核源代码树中设备驱动程存放在内核源代码树根目录drivers/的子目录下,例如:字符设备:drivers/char/块设备:drivers/block/USB设备:drivers/usb/char下有子目录,也有文件,驱动程序源码是放在该目录下还是创建一个自己的子目录?模块的编译和装载放在drivers/char/下拷贝hello.c到drivers/char/目录下打开drivers/char/Makefile,在其中增加一行:obj-m+=hello.o或若有配置选项,增加如下一行:obj-$(CONFIG_HELLO)+=hello.o

打开配置文件drivers/char/Kconfig,在其中增加一项:configHELLOtristate“NewHello”makemenuconfigmakemodules在何处执行make?模块的编译和装载放在drivers/char/下的子目录中在drivers/char/下创建子目录hello拷贝hello.c到drivers/char/hello/目录下打开drivers/char/Makefile,在其中增加一行:obj-m

+=hello/

或若有配置选项,增加如下一行:obj-$(CONFIG_HELLO)+=hello/

在drivers/char/hello/下新建Makefile,需一行:obj-m+=fishing.o

或若有配置选项:obj-$(CONFIG_HELLO)+=hello.o

模块的编译和装载打开配置文件drivers/char/Kconfig,在其中增加一项:configHELLOtristate“NewHello”makemenuconfigmakemodules模块的编译和装载放在内核源代码外设放在/home/ldd下,则需在该目录中新建一Makefile,只需一行:obj-m:=hello.o运行命令make-C/kernel/source/locationSUBDIRS=$PWDmodules或使用带条件语句的复杂makefile(见后)模块的编译和装载加载卸载模块insmodmodule需指定模块的完整文件名及路径modprobemodulemodprobe只能从标准的已安装模块目录中搜索需要装入的模块(/lib/modules/(shelluname–r))rmmodmodulemodprobermodules模块的编译和装载helloworld的编译建hello目录,将hello.c与makefile放入其下,makefile中只需一行:Obj-m:=hello.o在hello目录下运行命令:make-C~/kernel-2.6M=$PWDmodules

或使用带条件语句的复杂makefile(见后)模块的编译和装载带条件语句的makefile:在hello目录下运行命令make#IfKERNELRELEASEisdefined,we'vebeeninvokedfromthe#kernelbuildsystemandcanuseitslanguage.ifneq($(KERNELRELEASE),)

obj-m:=hello.o#Otherwisewewerecalleddirectlyfromthecommand#line;invokethekernelbuildsystem.else KERNELDIR?=/lib/modules/$(shelluname-r)/build PWD:=$(shellpwd)default: $(MAKE)-C$(KERNELDIR)M=$(PWD)modulesendif152第2章构造和运行模块HelloWorld模块模块与应用程序模块的编译和加载内核符号表初始化和关闭模块参数346内核符号表内核符号表中包含了所有全局内核项(函数和变量)的地址,这是实现模块化驱动程序所必需的,当模块被装入内核后,它所导出的任何符号都会成为内核符号表的一部分。模块可导出符号供其他模块使用,也可不导出任何符号,只实现自己的功能利用模块导出的符号可以在已有模块基础上层叠新模块,这称为模块层叠技术模块层叠技术可将复杂模块分为几层,然后从上到下逐层实现,以减化实现的复杂性内核符号表例如video-for-linux

驱动程序组划分出了一个通用模块,它导出的符号可供下层与具体硬件相关的驱动程序使用。根据所安装的具体硬件的不同,可以加载通用的video模块以及与具体硬件相关的特定模块msdos文件依赖fat模块导出的符号USB输入设备模块层叠在usbcore和input模块之上Modprobe是处理模块层叠的一个实用工具如何向内核导出符号?EXPORT_SYMBOL(name);EXPORT_SYMBOL_GPL(nam)152第2章构造和运行模块HelloWorld模块模块与应用程序模块的编译和加载内核符号表初始化和关闭模块参数346初始化和关闭初始化模块的初始化函数负责注册模块所提供的任何设施。这里的设施指的是一个可以被应用程序访问的新功能,它也可能是一个完整的驱动程序或者仅仅是一个软件抽象。初始化函数定义:staticint

__init

initialization_function(void){ /*Initializationcodehere*/}module_init(initialization_function);

初始化和关闭__init修饰标记表示在模块装载之后,模块装载器就会将初始化函数扔掉,以释放其占用的内存资源__initdata

与__init类似,只不过用于修饰数据内核源代码中可能还会碰到__devinit

和__devinitdata

,此两修饰符只有在内核未被配置为支持热插拔时被翻译为__init

和__initdata初始化和关闭清除函数清除函数负责在模块被卸载前注销接口并向系统中返回所有资源。清除函数定义:清除函数没有返回值__exit表示该代码仅用于模块卸载staticvoid__exit

cleanup_function(void){ /*Cleanupcodehere*/}module_exit(cleanup_function);

初始化和关闭初始化过程中的错误处理int__initmy_init_function(void){

interr; /*registrationtakesapointerandaname*/ err=register_this(ptr1,"skull"); if(err)goto

fail_this; err=register_that(ptr2,"skull"); if(err)goto

fail_that; err=register_those(ptr3,"skull"); if(err)goto

fail_those; return0;/*success*/

fail_those:unregister_that(ptr2,"skull");

fail_that:unregister_this(ptr1,"skull");

fail_this:returnerr;/*propagatetheerror*/}

初始化和关闭模块的清除函数需要撤销初始化函数所注册的所有设施void__exitmy_cleanup_function(void){ unregister_those(ptr3,"skull"); unregister_that(ptr2,"skull"); unregister_this(ptr1,"skull"); return;}

152第2章构造和运行模块HelloWorld模块模块与应用程序模块的编译和加载内核符号表初始化和关闭模块参数346模块参数应用程序可带参数运行,模块装载时若也能带参数,将会增强模块的适应性insmod/modprobe执行时可指定模块参数,modprobe还可从其配置文件/etc/modprobe.conf

中读取参数怎么给模块增加参数?module_param(name,type,perm);模块参数例给helloworld模块增加参数staticchar*whom="world";staticint

howmany=1;module_param(howmany,int,S_IRUGO);module_param(whom,charp,S_IRUGO);staticint

hello_init(void){

inti;for(i=0;i<howmany;i++)

printk(KERN_ALERT"(%d)Hello,%s\n",i,whom);return0;}staticvoidhello_exit(void){

printk(KERN_ALERT"Goodbye,cruelworld\n");}module_init(hello_init);module_exit(hello_exit);#include<linux/init.h>#include<linux/module.h>#include<li

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论