linux内核模块设计.ppt_第1页
linux内核模块设计.ppt_第2页
linux内核模块设计.ppt_第3页
linux内核模块设计.ppt_第4页
linux内核模块设计.ppt_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

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

文档简介

1、Linux 2.6内核模块设计,,,内核模块概述,Linux内核是整体式结构,各个子系统联系紧密,作为一个大程序在内核空间运行。,,内核模块概述,太多的设备驱动和内核功能集成在内核中,内核过于庞大。如何解决? Linux内核引入内核模块机制。通过动态加载内核模块,使得在运行过程中扩展内核的功能。不需要的时候,卸载该内核模块。,,内核模块概述,什么是内核模块? 内核模块是一种没有经过链接,不能独立运行的目标文件,是在内核空间中运行的程序。经过链接装载到内核里面成为内核的一部分,

2、可以访问内核的公用符号(函数和变量)。 内核模块可以让操作系统内核在需要时载入和执 行,在不需要时由操作系统卸载。它们扩展了操作系统内核的功能却不需要重新启动系统。 如果没有内核模块,我们不得不一次又一次重新编译生成单内核操作系统的内核镜 像来加入新的功能。这还意味着一个臃肿的内核。,,内核模块概述,模块机制的优点: 减小内核映像尺寸,增加系统灵活性; 节省开发时间;修改内核,不必重新编译整个内核。 模块的目标代码一旦被链入内核,作用和静态链接的内核目标代码完全等价。 模块机制的缺点: 对系统性能有一定损失; 使用不当时会导致系统崩溃;,www.gec-edu.o

3、rg,内核模块概述,内核模块是如何被调入内核工作的? 当操作系统内核需要的扩展功能不存在时,内核模块管理守护进程kmod执行modprobe去加载内核模块。 modprobe遍历文件/lib/modules/$(version)/modules.dep 来判断是否有其它内核模块需要在该模块加载前被加载。 最后modprobe调用insmod先加载被依赖的模块,然后加载该被内核要求的模块。,,内核模块概述,内核模块的卸载 当我们不需要内核模块了,为了减少系统资源的开销,需要卸载时使用命令 #rmmod module_name 或者 #modprobe r modul

4、e_name 查看系统已经加载的模块,使用命令 #lsmod,,实验:Hello World模块,步骤: 新建模块目录 用编辑器(vi)编辑源文件 用编辑器编辑Makefile 在内核源码树外编译 把模块加到内核源码树并把配置信息同时加入,,实验:Hello World模块,#include / for module_init() #include / must be include #include / for printk() static int _init hello_init(void) printk(“Hello worl

5、dn”); return 0; static void _exit hello_exit(void) printk(“Hello module exitn”); module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE(“GPL”); MODULE_AUTHOR(“hsq”);,,实验:Hello World模块,说明: 1) 模块入口函数为hello_init(), 由module_init() 宏指定,在模块被加载的时候被调用向系统 注册, 就象应用程序的main()一样,主要来 完成模块

6、的初始化工作 2) 入口函数的返回值为0表示成功, 非0表示失败 3) 模块的退出函数为hello_exit(),由module_exit()宏 指定,在模块被卸载是被调用向系统注销,主要来完成 资源的清理工作,它被调用完毕后,就模块就被内核清除了 4) 一个模块最少需要有入口和退出函数,,实验:Hello World模块,说明: 关于_init和_exit宏 如果该模块被编译进内核,而不是动态加载,则宏 _init的使用会在初始化完成后丢弃该函数并收回所占内存。 如果该模块被编译进内核,宏_exit将忽略“清理收尾”的函数。 这些宏在头文件linux/init.

7、h定义,用来释放内核占用的内存。例如启动时看到的信息“Freeing unused kernel memory: 236k freed”,正是内核释放这些函数所占用空间时的打印信息。,,实验:Hello World模块,printk( )函数 printk 函数在 Linux 内核中定义并且对模块可用,为内核提供日志功能, 记录内核信息或用来给出警告。与标准 C 库函数 printf 的行为相似。 每个printk() 声明都会带一个优先级。内核总共定义了八个优先级的宏, 在linux/kernel.h中定义。若你不指明优先级,DEFAULT_MESSAGE_LO

8、GLEVEL这个默认优先级将被采用。 信息添加到文件 /var/log/messages,可直接查看,或者用命令dmesg查看。在Xwindows下的终端insmod一个模块,日志信息只会记录在日志文件中,而不在终端打印。,,实验:Hello World模块,写内核程序需要注意:,,实验:Hello World模块,内核模块的Makefile: CONFIG_HELLO_WORLD ?= m ifneq ($(KERNELRELEASE),) hello_world-objs := hello.o obj-$(CONFIG_HELLO

9、_WORLD) += hello_world.o else KERNELDIR = /$(your_kernel_source)/ PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules endif clean: rm rf *.o * core .depend . *.cmd *.ko *.mod.c .tmp_versions 注意: your_kernel_source,是你的linux kernel源代码的目录,,实验:Hello World模块,Makefile说明: 为

10、2.6版本内核构造模块 首先需要有配置并构建好的2.6内核源代码树。而且最好运行和模块对应的内核。 2.6 内核的模块要和内核源代码树中的目标文件连接。 2.6 内核的构建系统Kbuild,使得内核源码外的内核模块编译跟内核编译统一起来,无须手动给定这些参数。 改变目录到用 -C 选项提供的内核源码目录,在那里找到内核的顶层makefile。M= 选项使 makefile 在试图建立模块目标前, 回到模块源码目录。,,实验:Hello World模块,编译加载/卸载: 在hello world模块目录上 #make 得到hello_world.ko就是产生的内核模

11、块,在 评估板上使用 #insmod hello_world.ko 和 #rmmod hello_world 观察控制台输出的结果,,实验:Hello World模块,内核模块证书和内核模块文档说明 2.4内核后,引入识别代码是否在GPL许可下发布的机制 。在使用非公开的源代码产品时会得到警告。通过宏MODULE_LICENSE(“GPL”),设置模块遵守GPL证书,取消警告信息。 宏MODULE_DESCRIPTION()用来描述模块的用途。 宏MODULE_AUTHOR()用来声明模块的作者。 宏MODULE_SUPPORTED_DEVICE() 声明模块支持

12、的设备。 这些宏都在头文件linux/module.h定义。使用这些宏只是用来提供识别信息。 范例:hello-4.c,,实验:Hello World模块,模块参数 内核允许对模块指定参数,这些参数可在装载模块时改变。在运行insmod或者modprobe命令时给出参数的值。 insmod hellop.ko howmany=10 whom=Mom 如何定义实现模块参数呢? 要传递参数给模块,首先将获取参数值的变量声明为全局变量。然后使用宏moudle_param来声明 int myint = 3; module_param(myint, int,0);,www.

13、,实验:Hello World模块,模块参数 module_param(name,type,perm); perm是一个权限值,控制谁可以存取模块参数在 sysfs 中的表示。 perm 被设为 0, 就根本没有 sysfs 项 这个宏定义应当放在任何函数之外, 典型地是出现在源文件的前面。 应该总是为变量赋初值。,,实验:Hello World模块,模块参数 宏MODULE_PARM_DESC() 用来注解该模块可以接收的参数。该宏两个参数:变量名和一个对该变量的描述。 模块可以用这样的命令行加载: ./insmod mymodule.ko

14、 myvariable=2 例子:hello-5.c,,实验:Hello World模块,模块参数 声明一个数组参数: module_param_array(name,type,num,perm); name 数组的名子(也是参数名) type 数组元素的类型 num 是数组元素的个数,模块加载者拒绝比数组能放下的多的值。2.6.9传递数组个数变量名,2.6.11传递数组个数变量的地址。 perm 是通常的权限值. 如果数组参数在加载时设置。,,实验:Hello World模块,参数数组的定义: static int test5 =

15、1,2,3,4,5; static int num =5; module_param(num,int,0); module_param_array(test,int,num,0); MODULE_PARM_DESC(test, test array); 参数数组的加载方式: insmod test.ko test=6,7,8,9,10 num=5,,实验:Hello World模块,把模块加到Kernel的代码树: 选择一个需要把你的模块加入进去的Kernel子目录,如/$(KERNEL_DIR)/drivers/char, 在此子目录的Makefile中的 适当

16、的位置加入 obj-$(CONFIG_HELLO_WORLD) += $(your_module_dir_name)/ 这一句让Kernel被Kbuild系统编译的时候进入到您的模块的 Makefile去执行,,实验:Hello World模块,把模块加到Kernel的代码树: 在模块的目录中新建一个Kconfig文件,内容为 config HELLO_WORLD tristate “A helloworld sample” default m help this is a test module sample for study, it just print h

17、ello world on console 在/$(KERNEL_DIR)/drivers/char/Kconfig中的适当位置加入 source “drivers/char/$(your_module_dir_name)/Kconfig”,,实验:Hello World模块,修改模块的Makefile: hello_world-objs := hello.o obj-$(CONFIG_HELLO_WORLD) := hello_world.o 注意Kconfig里面HELLO_WORLD前面没有CONFI_ 的,是Kbuild系统在编译时加上的 从新配置和编译内核,看hello world是否 在系统启动时有出现,www.gec-edu.

温馨提示

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

评论

0/150

提交评论