操作系统实验五

实验五:添加内核模块

一、实验目的:

学习模块机制:它是Linux特有的一种机制。模块可以用来动态地增加内核的功能。

二、实验内容

一、模块的介绍

Linux模块(module)是一些可以作为独立程序来编译(使用适当的标志说明这是内核代码)的函数和数据类型的集合。在装载这些模块时,将它的代码链接到内核中。

Linux模块可以单独编译成为目标代码,module是一个目标文件。它可以根据需要在系统启动后动态地加载到系统核心之中。Linux中大多数设备驱动程序或文件系统都作成的module。超级用户可以通过insmodrmmod命令显示地将module载入核心或从核心中将它卸载。

二、模块的组织结构

一旦module载入核心后,它就成为核心代码的一部分。它与其它核心代码的地位是相同的。module在需要的时可通过“内核符号表”symbol table使用核心资源。核心将资源登记在符号表中,当module装载时,核心利用符号表来解决module中资源引用的问题。Linux中允许module堆栈(module stacking),既一个module可请求其他module为之提供服务。当module装载入系统核心时,系统修改核心中的符号表,将新装载module 提供的资源和符号加到核心符号表中。通过这种通信机制,新载入的module可以访问已装载的module提供的资源。通过/proc/ksyms文件可以查看内核符号表中各类符号及其地址。

三、模块的装载与卸载

模块在用户空间中(使用适当的标志)进行编译,结果产生一个可执行格式的文件。如前所述,模块可以引用内核变量,其条件是内核代码已编写好,从而允许变量被另一个模块所引用。简单说来,一个模块可以导出自己的符号,这样其他模块就可以使用它们。

在用insmod命令装载一个模块时(见下面的解决问题部分),将会发生以下事件:

  1. 新模块(通过内核函数create_module()加入到内核地址空间。

  2. 另外一个内核函数get_kernel_syms(),通过查找导出的内核符号对模块中的外部符号引用进行解析,导出内核符号之后是一个已经装载到系统中的其他模块的列表。这意味着如果一个模块引用了其他模块中定义的符号,那么定义这个符号的模块就必须在那些引用这个符号的模块装载进系统之前被装载。

  3. create_module()为这个模块分配内存空间。

  4. 通过init_module()系统调用装载模块。该模块定义的符号在此时被导出,供其他可能后来装载的模块使用。

  5. Insmod为新装载的模块调用init_module()函数

当模块卸载时(通过使用rmmod,见下面的“解决问题”部分),调用cleanup_module()函数。释放模块所使用的空间,同时取消虚拟地址的映象。

三、实验步骤

编写程序如下:

#define __KERNEL__
#define MODULE
#include<linux/module.h>
#include<linux/kernel.h>
int init_module() {
    printk("Hello! My stu_number xxxxxxxx\n");
    return 0;
}
void cleanup_module() {
    printk("Quit...My stu_number xxxxxxxx\n");
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用如下命令进行编译

gcc –c –I/usr/src/linux-2.4.20-8/include –Wall hello.c   

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用如下命令加载这个模块

insmod hello.o

如果显示内核不匹配(missmatch)导致无法加载,可以使用如下命令进行强制加载

insmod -f hello.o

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查看系统日志

dmesg

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用如下命令查看所有的模块

lsmod

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

卸载hello模块

rmmod hello

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

再次查看系统日志,卸载模块的输出语句已经成功执行完毕

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四、实验心得

本次实验的内容是增加一个内核模块。添加内核模块时需注意:代码运行在内核态下,很多用户态常用的函数、调用等可能无法使用(例如需要使用printk代替常用的printf);模块编译使用的命令与编译普通程序有所不同;模块的输出内容不会直接显示在控制台,需要使用dmesg命令查看系统日志读取相关输出。

  • 22
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值