操作系统-实验四、内核模块编写

内核模块编写

  • 实验目的

(1)理解操作系统中缺页中断的工作原理。

(2)学会通过修改内核实现统计系统缺页次数的方法。

  • 实验内容

通过修改 Linux内核中的相关代码,统计系统缺页次数。

  • 实验步骤

(1)编写内核模块源代码文件 helloworld.c。

(2)编写编译内核模块时要用到的Makefile文件。

(3)编译 helloworld.c。

(4)执行内核模块装入命令。

(5)当不需要使用helloworld 模块时,就载这个模块。

  • 实验结果

(1)执行内核模块装人命令。

# sudo insmod helloworld,ko

可以通过 dmesg命令查看控制台输出,如图所示。

# dmesg

这时,可以看到输出结果“<1>Hello World!”,此内容是在 init module0函数中定义的,由此说明,helloworld 模块已经被成功装载到了内核中。

也可以使用1smod命令查看模块信息,如图所示。

#lsmod (2)当不需要使用helloworld 模块时,可以卸载这个模块。

# sudo rmmod helloworld

可以通过dmesg命令查看控制台的输出,如图所示

# dmesg

此时,可以看到输出结果“<1>Goodbye!”,此内容是在cleanup module0函数中定义的。由此说明,helloworld 模块已被删除。如果这时候再使用1smod命令,就会发现helloworld模块已经不存在了。

五、实验总结

1.总结并分析实验中出现的问题及对应的解决方法

本次实验和实验3相似,进行的比较顺利,并无出现太多问题,唯一需要注意的就是helloworld.c和Makefile文件的编写,不要出现错误,make需要在对应的文件夹中执行。

2.如何实现将多个源文件合并到一个内核模块中?

创建一个新的文件,命名为 "Makefile",用于编译和构建内核模块。

在 "Makefile" 文件中,定义模块的编译规则和依赖关系。可以使用变量来指定需要编译的源文件列表,如:obj-m := mymodule.o,其中 "mymodule.o" 是模块的目标文件名。

在同一个目录下创建多个源文件,如 "module1.c"、"module2.c" 等。

在每个源文件中,使用模块相关的宏(如 module_init 和 module_exit)定义模块的初始化和退出函数。

在 "Makefile" 文件中,通过变量指定需要编译的源文件列表,如:obj-m += module1.o module2.o,将所有需要编译的源文件都列出。

运行 make 命令编译内核模块,生成目标文件。

3.总结体会

本次实验进行了Linux内核模块的编写。

Linux内核非常庞大,包含很多组件,把需要的部分包含在内核中通常有两种办法:

1)把所有需要的功能都编译进内核中。

但是生成的内核会非常大;为现有内核添加、删除功能,需要重新编译。

2)不包含所有功能,需要的时候,动态地加载代码到内核。

这种机制即为模块(Module)。

一个Linux内核模块主要组成如下:

1)模块加载函数

如前面通过宏定义module_init声明的hello_init,就是模块加载函数。当通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块的相关初始化工作。

实验中对应init_module()函数。

2)模块卸载函数

如前面通过module_exit声明的hello_exit。当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块加载函数相反的功能。

实验中对应cleanup_module()函数。

3)模块许可证声明

通过MODULE_LICENSE许可证声明描述内核的许可权限,如不声明LICENSE,模块被加载时,将收到内核被污染(Kernel Tainted)的警告。可接受LICENSE:"GPL", "GPL v2", "GPL and additional rights", "Dual BSD/GPL", "Dual MPL/GPL", "Proprietary"。推荐使用"GPL"或"GPL v2"。

实验中对应MODULE_LICENSE(“GPL”)。

4)模块参数(可选)

模块参数是模块被加载时,可以传递给它的值。本身对应模块内部的全局变量。

5)模块导出符号(可选)

内核模块可以导出的符号(symbol,对应于函数或变量),若导出,其他模块则可以使用本模块的变量或函数。

6)模块作者等信息声明(可选)

在实验过程中使用了许多指令和函数等等。

printk是内核模块输出函数,运行在内核空间;printf是glibc库函数,运行在用户空间。

printk可定义输出级别,printf不支持输出级别定义。

lsmod命令列出已加载模块信息,实际是读取、分析"/proc/modules",可以用cat命令输出已加载模块信息。

本次实验,我理解了针对Linux提出内核模块这种机制的意义,掌握Linux实现内核模块机制的基本技术路线。学习了运用Linux提供的工具和命令,掌握操作内核模块的方法。

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值