




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验五 内核模块设计实验 现代的Linux内核是具有微内核特点的宏内核。Linux内核作为一个大程序在内核空间运行。太多的设备驱动和内核功能集成在内核中,内核过于庞大。Linux内核引入内核模块机制。通过动态加载内核模块,使得在运行过程中扩展内核的功能。不需要的时候,卸载该内核模块。内核模块内核模块是一种没有经过链接,不能独立运行的目标文件,是在内核空间中运行的程序。经过链接装载到内核里面成为内核的一部分,可以访问内核的公用符号(函数和变量)。内核模块可以让操作系统内核在需要时载入和执行,在不需要时由操作系统卸载。它们扩展了操作系统内核的功能却不需要重新启动系统。如果没有内核模块,我们不得不一次又一次重新编译生成单内核操作系统的内核镜 像来加入新的功能。这还意味着一个臃肿的内核。内核模块是如何被调入内核工作的?当操作系统内核需要的扩展功能不存在时,内核模块管理守护进程kmod执行modprobe去加载内核模块。modprobe遍历文件/lib/modules/version/modules.dep 来判断是否有其它内核模块需要在该模块加载前被加载。最后modprobe调用insmod先加载被依赖的模块,然后加载该被内核要求的模块。内核模块是如何被调入内核工作的?Insmod将调用init_module系统调用,传入参数(Module.c)Sys_init_module系统调用检查权限后,并查找modules链表,验证模块未被链接。然后分配一个module结构体变量描述该内核模块。如果定义了模块的init方法,则执行init方法。模块机制的特点:减小内核映像尺寸,增加系统灵活性;节省开发时间;修改内核,不必重新编译整个内核。模块的目标代码一旦被链入内核,作用和静态链接的内核目标代码完全等价。最简单的内核模块 任一个内核模块需要包含linux/module.h初始化函数init_module(),在模块加载到内核时被调用。init_module()向内核注册模块的功能,申请需要的资料等初始化工作。 卸载函数cleanup_module() ,在内核模块被卸载时被调用,干一些收尾清理的工作,撤消任何初始化函数init_module()做的事,保证内核模块可以被安全的卸载。 printk( )函数printk 函数在 Linux 内核中定义并且对模块可用,为内核提供日志功能, 记录内核信息或用来给出警告。与标准 C 库函数 printf 的行为相似。每个printk() 声明都会带一个优先级。内核总共定义了八个优先级的宏, 在linux/kernel.h中定义。若你不指明优先级,DEFAULT_MESSAGE_LOGLEVEL这个默认优先级将被采用。信息存在在内核消息缓冲区中,并被定时的添加到文件 /var/log/messages,可直接查看,或者用命令dmesg查看。在Xwindows下的终端insmod一个模块,日志信息只会记录在日志文件中,而不在终端打印。从内核Linux 2.4之后,可以为模块的“初始化”和“卸载”函数起任意的名字。不再必须使用 init_module()和cleanup_module()的名字。通过宏 module_init()和module_exit()实现。这些宏在linux/init.h中定义。module_init(hello_2_init); module_exit(hello_2_exit); 函数必须在宏的使用前定义,否则编译会报错。关于_init和_exit宏 如果该模块被编译进内核,而不是动态加载,则宏 _init的使用会在初始化完成后丢弃该函数并收回所占内存。 如果该模块被编译进内核,宏_exit将忽略“清理收尾”的函数。这些宏在头文件linux/init.h定义,用来释放内核占用的内存。例如启动时看到的信息“Freeing unused kernel memory: 236k freed”,正是内核释放这些函数所占用空间时的打印信息。内核模块证书和内核模块文档说明 2.4内核后,引入识别代码是否在GPL许可下发布的机制 。在使用非公开的源代码产品时会得到警告。通过宏MODULE_LICENSE(“GPL”),设置模块遵守GPL证书,取消警告信息。宏MODULE_DESCRIPTION()用来描述模块的用途。宏MODULE_AUTHOR()用来声明模块的作者。 宏MODULE_SUPPORTED_DEVICE() 声明模块支持的设备。这些宏都在头文件linux/module.h定义。使用这些宏只是用来提供识别信息。准备工作顺利编译并且加载第一个“hello world”模块有时会比较困难。保证系统具备正确的编译器、模块工具、以及其他必要工具。内核目录 Documentation/Changes 列出了需要的工具版本。用错误的工具版本建立一个内核(包括模块),可能导致一些奇怪复杂的问题。 通常芯片公司的SDK包会告诉你使用什么版本的交叉工具链去完成,并提供相应的工具链。准备好系统平台所对应的内核源代码配置并构建好平台对应的2.6内核源代码。2.6 内核使用kbuild构建系统配置编译,kbuild构建系统可用于编译自定义的内核模块。编译过程首先会到内核源码目录下,读取顶层的Makefile文件,然后再编译模块源码,连接生成的内核模块后缀为.ko 在内核源代码目录下:make menuconfig,使得配置跟目标平台一致make编写内核模块的makefile内核Makefile提供的obj-m表示对象文件(object files)编译成可加载的内核模块Hello-1.c的Makefile文件obj-m += hello-1.o 表明有一个模块要从目标文件 hello-1.o 建立,kbuild从该目标文件建立内核模块hello-1.ko。编译内核模块的命令make -C 内核源代码路径 M=模块所在路径 modulesmake -C /lib/modules/uname -r/build M=$PWD modules改变目录到用 -C 选项提供的内核源码目录,make读取内核的makefile,并编译M所指定路径下的内核模块源代码。内核模块的加载2.6内核模块使用.ko的文件后缀(代替.o后缀)。使用insmod ./hello-1.ko命令加载该模块。/proc/modules记录被加载的内核模块。使用lsmod命令查看已经加载的模块使用命令 rmmod hello-1 卸载模块 tail /var/log/messages编写hello模块,包含初始化init_module和卸载函数cleanup_module编写makefile文件Obj-m += hello-1.o编译hello内核模块make -C /lib/modules/uname -r/build M=$PWD modulesUname r 给出当前系统内核的版本,使用短撇号,将其输出结果作为参数的一部分。而build是符号链接,指向对应内核的源代码目录。加载hello内核模块:insmod hello-1.ko查看加载信息:tail /var/log/message卸载hello内核模块 rmmod hello-1使用modprobe命令修改/lib/module /uname -r/modules.dep文件,添加hello-1.ko内核模块路径和依赖关系加载hello内核模块: Modprobe hello-1卸载hello内核模块 Modprobe r hello-1n 修改hello内核模块的makefilen 添加all目标n 添加clean目标obj-m += hello-1.oKERN_VER = $(shell uname -r)KERN_DIR = /lib/modules/$(KERN_VER)/buildall:$(MAKE) -C $(KERN_DIR) M=$(PWD) modulesclean:rm -rf *.o rm -rf *.mod.* rm -rf *.korm rf .tmp_version n 直接通过make,编译内核模块n 多个文件构成的内核模块n Makefile会帮我们完成编译和连接的工作。n 例如 内核模块分两个文件 start.c stop.c,则Makefile这样写:obj-m += test.o test-objs := start.o stop.o跟单个文件模块的编译方式一样,内核编译系统会将所有的目标文件连接为一个文件。n 内核模块的Makefile模块mymodule-objs = file1.o file2.oobj-m += mymodule.o PWD = $(shell pwd)KDIR = 内核源代码路径all:$(MAKE) -C $(KDIR) M=$(PWD) modulesclean:rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions lsmod 列出已经挂载的内核模块lsmod 是列出目前系统中已加载的模块的名称及大小等效果跟通过less /proc/modules查看模块一样。 modinfo 查看模块信息 modinfo 可以查看模块的信息,通过查看模块信息来判定这个模块的用途。 modinfo 模块名modprobe 挂载新模块以及新模块相依赖的模块modprobe 模块名,在挂载该内核模块的同时,这个模块所依赖的模块也被同时挂载。modprobe还有其他用法,问他的“man” 。例如:modprobe -l 是列出内核中所有的模块,包括已挂载和未挂载的,读取的模块列表就位于 /lib/modules/uname -r 目录中。 rmmod 移除已挂载模块用法:rmmod 模块名(不带后缀)等同于:modprobe -r 模块名 insmod 挂载模块 insmod 需要给出模块所在目录的绝对路径,以及要带有模块文件名后缀(.o 或.ko)insmod /lib/modules/2.6.18/kernel/fs/vfat/vfat.ko 功能上没有modprobe 强。 depmod 创建模块依赖关系的列表目前的的Linux 发行版所用的内核是2.6x版本,是自动解决依赖关系。depmod -a为所有列在/etc/modprobe.conf 或/etc/modules.conf 中的所有模块创建依赖关系,并且写入到modules.dep文件 depmod e 列出已挂载但不可用的模块为2410开发板配置编译Linux内核内核版本:linux-2.6.24交叉工具链:cross-3.4.4.tar.gz选择相应的配置时,有三种选择,它们分别代表的含义如下: Y-将该功能编译进内核 N-不将该功能编译进内核 M-将该功能编译成模块,可以在需要时动态插入到内核中make xconfig,使用鼠标就可以选择对应的选项。make menuconfig,则需要使用空格键进行选取。如果有不明白的地方,按 shift+?的组合键来查看说明主要配置选项1.Code maturity level options - 应该选择* Prompt for development and/or incomplete code/drivers这将会在设置界面中显示还在开发或者还没有完成的代码与驱动. 因为有许多设备可能必需选择这个选项才能进行配置,实际上它是安全的。Enable loadable module support 打开可加载模块支持2 General setup -大部分保持默认* Support for paging of anonymous memory (swap) 应该选择这个选项将使你的内核支持虚拟内存。 * System V IPC 应该选择为进程提供通信机制。有些程序只有在选Y的情况下才能运行,这里一定要选。* POSIX Message Queues POSIX的消息队列,它同样是一种IPC,应该选择* Support for hot-pluggable devices 支持热插拔的,若是为普通电脑配置内核,则最好选择3 Loadable module support -* Enable loadable module support 应该选择这个选项可以让你的内核支持模块。一般一些不常用到的驱动或特性可以编译为模块以减少内核的体积。* Module unloading 应该选择这个选项可以让你卸载不再使用的模块,如果不选的话你将不能卸载任何模块* Forced module unloading强行卸载模块,可以把正在使用中的模快卸载掉。做内核开发或者驱动开发的时候,有一定的好处。但一般用户不应该选择。* Module versioning support 模块版本支持该选项可以使得系统支持其它版本的内核模块。 Source checksum for all modules 否这个功能是为了防止更改了内核模块的代码但忘记更改版本号而造成版本冲突。 * Automatic kernel module loading在内核需要一些模块时,可以自动调用modprobe命令来加载需要的模块。4 Processor type and features -Processor family (Pentium-Pro) - 选择cpu的类型5 Power management options (ACPI, APM) -* Power Management support支持高级电源管理(也就是平常我们说的软关机、系统休眠等)。6 Bus options (PCI, PCMCIA, EISA, MCA, ISA) -* PCI support PCI支持。当然必选PCI access mode (Any) -PCI的存取方式,分三种,有透过BIOS或是直接存取跟任意,预设值Any7 Executable file formats -* Kernel support for ELF binaries 一定要选择8 Device Drivers -Memory Technology Devices (MTD) - 存储设备层,大部分的flash芯片驱动都基于MTD。用于嵌入式系統。Block devices Loopback device support可以将一个文件挂成一个文件系统。mount iso文件9 file systems -建议将根文件系统直接编译到内核中。并且在这里选择系统支持的文件系统。常见内核编译命令make dep 实际上读取配置过程生成的配置文件Make zImage 生成压缩的内核程序映像make bzImage 生成big的压缩的内核程序映像make modules 生成相应的模块make modules_install 把模块拷贝到需要的目录make clean 清除之前所编译的执行文件及目的文件 Make distclean 清楚所有的执行文件、目标文件,以及其他一起中间文件,只剩下源代码文件。内核配置命令:make config (基于文本的配置界面,不推荐使用)make menuconfig (基于文本菜单的配置界面)make xconfig (要求QT被安装)make gconfig (要求GTK+被安装)Linux内核通过Kbuild构建系统来管理和配置Kbuild构建系统的组成Makefile 定义Linux内核的编译规则,顶层目录的Makefile管理整个Linux内核的配置编译。Kconfig 描述配置菜单的文件Documentation/kbuild目录详细描述在Linux内核中增加程序的3项工作:将编写的源代码复制到Linux内核源代码的相应目录.在目录的Kconfig文件中增加新源代码对应项目的编译配置选项.在目录的Makefile文件中增加对新源代码的编译条目.Kbuild构建系统Kconfig文件arch/$(ARCH)/Kconfig文件是主Kconfig文件,主Kconfig文件调用其他目录的Kconfig文件。这些Kconfig文件形成树状关系-树状菜单。script目录下提供不同的配置工具去读取Kconfig文件形成不同的配置方式。如menuconfig目标使用mconf。Documentation/kbuild/kconfig-language.txt提供了kconfig文件的书写语法。S3C2410处理器的RTC设备驱动s3c2410-rtc.c 放在linux-2.6.24.7/drivers/har目录中该目录的Kconfig文件中包含S3C2410_RTC的配置项目 config S2C2410_RTCbool “S2C2410 RTC Driver”depends on ARCH_ S2C2410help RTC (Realtime Clock) driver for the clock inbuilt into the Samsung S2C2410. This can provide periodic interrupt rates from 1Hz to 64Hz for user programs, and wakeup from Alarm.菜单结构 菜单项在菜单结构中的位置定义:menu “Network device support” depends on NET config NETDEVICES . . .endmenu所有处于”menu”和”endmenu”之间的菜单项都会成为”Network dcvice support”的菜单项或者子菜单.而且,所有子菜单选项都会继承父菜单的依赖关系菜单项 内核配置选项对应Kconfig中的一个菜单项 “config”关键字定义新的配置选项,之后的几行定义了该配置选项的属性,配置选项的属性包括类型,数据范围,输入提示,依赖关系(及反向依赖关系),帮助信息和默认值等. 每个配置选项都必须指定类型, 包括bool,tristate,string等 config MODVERSIONS bool “ Set version information on all module symbols” depends on MODULES help Usually, modules have to be recompiled whenever you switch to a new kernel.包含一个Kconfig文件采用source命令读取一个Kconfig文件Kconfig文件的路径是基于内核原代码的路径。例如:source “driver/char/ker/Kconfig”目标定义目标定义用来定义哪些内容要作为模块编译,哪些要编译并连接进内核. 例如:obj-y += foo.o obj-y表示要由foo.c或者foo.s文件编译得到foo.o并连接进内核obj-m表示该文件要作为模块编译.根据.config文件的CONFIG_变量来决定文件的编译方式 obj$ (CONFIG_GEC_TEST) += ker/obj$ (CONFIG_GEC_TEST) += test.o多文件模块的定义 一个模块由多个文件组成, 应采用模块名加-objs后缀或者-y后缀的形式来定义模块的组成文件obj $ (CONFIG_EXT2_FS) += ext2.oext2-objs := balloc.o bitmap.o实验:往内核中添加你的代码把你的内核模块代码ker目录拷贝到drivers/char/下在ker目录下建立Kconfig,通过menu添加菜单,通过config添加菜单项在char目录下的Kconfig文件中通过source包含自定义的ker的Kconfig文件添加makefileobj-$(CONFIG_GEC_TEST) += test.o修改上层makefileobj-$(CONFIG_GEC_TEST) += ker/注明:ker文件夹中包含编辑好的test.c文件实验一、动态编译本机内核模块/hello.c/#include /* Needed by all modules */#include /* Needed for KERN_ALERT */#include static int test_init(void) printk(Hello world 1.n); /* A non 0 return means init_module failed; module cant be loaded.*/ return 0;static void test_exit() printk(Goodbye world 1.n);module_init(test_init);module_exit(test_exit);/Makefile/obj-m += hello.oPWD := $(shell pwd)KERN_VER = $(shell uname -r)KERN_DIR = /lib/modules/$(KERN_VER)/buildall: $(MAKE) -C $(KERN_DIR) M=$(PWD) modulesclean: rm rf *.o * core .depend . *.cmd *.ko *.mod.c .tmp_versions编译生成的内核模块可以直接加载:insmod hello.ko卸载模块:rmmod hello.ko可以通过参看系统内核日志信息来查看模块的加载与卸载情况。实验二、静态编译本机内核模块将上述hello.c内核代码拷贝到内核源码drivers/char/下在char目录下的Kconfig文件中通过config添加菜单项config CHAR_TEST tristate hello_worl
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 妇产科医生年终工作总结15篇
- 关于夫妻开店协议书8篇
- 土地所有权转让合同(14篇)
- 家庭财产分割协议书15篇
- 婚礼上新郎父亲致辞(26篇)
- 外墙保温施工合同完整版样板5篇
- ERP服务项目及项目合同5篇
- 试剂价格调整协议书5篇
- 2025年电子商务行业市场竞争与发展模式研究报告
- 2025年航空物流行业国际物流与空运发展研究报告
- 2025年中国零售用显示屏行业市场全景分析及前景机遇研判报告
- 吉林省长春市2024-2025学年七年级上学期生物月考试题(含答案)
- 2025至2030中国视觉点胶机市场运行状况与未来发展走势预测报告
- 心源性休克病人的护理
- 种草莓劳动课件
- 雀巢牛奶购销合同范本
- 2025-2026学年华中师大版(2024)小学体育与健康一年级(全一册)教学设计(附目录P123)
- GA/T 952-2011法庭科学机动车发动机号码和车架号码检验规程
- 吊洞停止点检查记录表
- 以友辅仁教案
- “20道游标卡尺题目及答案”
评论
0/150
提交评论