欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > DOCX文档下载  

    实验五内核模块设计实验.docx

    • 资源ID:3436191       资源大小:45.11KB        全文页数:16页
    • 资源格式: DOCX        下载积分:6.99金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要6.99金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    实验五内核模块设计实验.docx

    实验五内核模块设计实验实验五 内核模块设计实验 文章由网提供现代的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表示对象文件编译成可加载的内核模块 Hello-1.c的Makefile文件 obj-m += hello-1.o 表明有一个模块要从目标文件 hello-1.o 建立,kbuild从该目标文件建立内核模块hello-1.ko。 编译内核模块的命令 make -C 内核源代码路径 M=模块所在路径 modules make -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 modules Uname 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-1 n 修改hello内核模块的makefile n 添加all目标 n 添加clean目标 obj-m += hello-1.o KERN_VER = $(shell uname -r) KERN_DIR = /lib/modules/$(KERN_VER)/build all: $(MAKE) -C $(KERN_DIR) M=$(PWD) modules clean: rm -rf *.o rm -rf *.mod.* rm -rf *.ko rm 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.o obj-m += mymodule.o PWD = $(shell pwd) KDIR = 内核源代码路径 all: $(MAKE) -C $(KDIR) M=$(PWD) modules clean: 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 需要给出模块所在目录的绝对路径,以及要带有模块文件名后缀 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或是直接存取跟任意,预设值Any 7 Executable file formats -> * Kernel support for ELF binaries 一定要选择 8 Device Drivers -> Memory Technology Devices (MTD) -> 存储设备层,大部分的flash芯片驱动都基于MTD。用于嵌入式系統。 Block devices <M> 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_RTC bool “S2C2410 RTC Driver” depends on ARCH_ S2C2410 help 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.o ext2-objs := balloc.o bitmap.o 实验:往内核中添加你的代码 把你的内核模块代码ker目录拷贝到drivers/char/下 在ker目录下建立Kconfig,通过menu添加菜单,通过config添加菜单项 在char目录下的Kconfig文件中通过source包含自定义的ker的Kconfig文件 添加makefile obj-$(CONFIG_GEC_TEST) += test.o 修改上层makefile obj-$(CONFIG_GEC_TEST) += ker/ 注明:ker文件夹中包含编辑好的test.c文件 实验一、动态编译本机内核模块 /hello.c/ #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_ALERT */ #include <linux/init.h> static int test_init(void) printk("Hello world 1.n"); /* A non 0 return means init_module failed; module can't 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.o PWD := $(shell pwd) KERN_VER = $(shell uname -r) KERN_DIR = /lib/modules/$(KERN_VER)/build all: $(MAKE) -C $(KERN_DIR) M=$(PWD) modules clean: 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_world_testing " depends on / -help- This driver supports for char testing 修改char下的Makefile文件,在Makefile中添加以下语句: obj-$(CONFIG_CHAR_TEST) += test.o 这样,当运行make menucofnig时,将发现CHAR_TEST选项,如果选择了此项。该选择就会保存在.config文档中。编译内核时,将会读取.config文档,当发现CHAR_TEST选项为yes 时,系统在调用/driver/char/下的makefile 时,将会把 test.o 加入到内核中。在内核启动的过程中就可以看到该内核模块的加载信息。 实验三、开发板的内核模块设计 /hello.c/ #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_ALERT */ #include <linux/init.h> static int test_init(void) printk("Hello world 1.n"); /* A non 0 return means init_module failed; module can't be loaded.*/ return 0; static void test_exit printk("Goodbye world 1.n"); module_init(test_init); module_exit(test_exit); /Makefile/ # Makefile2.6 ifneq ($(KERNELRELEASE),) #kbuild syntax. dependency relationshsip of files and target modules are listed here. obj-m := led.o else PWD := $(shell pwd) # where the kernel sources are located KERNEL_DIR :=/root/build_kernel/linux-gec2410-2.6.24 all: cd $(KERNEL_DIR); make SUBDIRS=$(PWD) modules clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions endif 文章由站长网编辑,转载请注明来源。

    注意事项

    本文(实验五内核模块设计实验.docx)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开