实验四 缺页统计操作系统缺页次数

实验四 缺页统计操作系统缺页次数
一、实验目的:
学习虚拟内存的基本原理和Linux虚拟内存管理技术;
深入理解、掌握Linux的按需调页过程;
掌握内核模块的概念和操作方法,和向/proc文件系统中增加文件的方法;
综合运用内存管理、系统调用、proc文件系统、内核编译的知识。
二、实验内容:
1.原理
Linux的虚拟内存技术采用按需调页,当CPU请求一个不在内存中的页面时,会发生缺页,缺页被定义为一种异常(缺页异常),会触发缺页中断处理流程。每种CPU结构都提供一个do_page_fault处理缺页中断。由于每发生一次缺页都要进入缺页中断服务函数do_page_fault一次,所以可以认为执行该函数的次数就是系统发生缺页的次数。因此可以定义一个全局变量pfcount 作为计数变量,在执行do_page_fault时,该变量值加1。本实验通过动态加载模块的方法,利用/proc文件系统作为中介来获取该值。
2.实验环境
操作系统:Ubuntu 12.04(内核版本为3.2.0-23-generic-pae)
内核源码:linux-3.2.58
三、 实验指导:
1.下载一份内核源代码并解压
Linux受GNU通用公共许可证(GPL)保护,其内核源代码是完全开放的。现在很多Linux的网站都提供内核代码的下载。推荐使用Linux的官方网站:http://www.kernel.org
在这里插入图片描述
图1 Linux的官方网站
在terminal下可以通过wget命令下载源代码:
$ cd /tmp
$ wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.58.tar.xz
切换到root身份,解压源代码到/usr/src目录下:

xz –d linux-3.2.58.tar.xz

tar –xvf linux-3.2.58.tar –C /usr/src

  1. 修改内核源代码,添加统计变量
    1、切换到预编译内核目录
    #cd /usr/src/linux-3.2.58
    2、修改处理内存访问异常的代码
    //用vi编辑器打开fault.c,一般使用Intel x86体系结构,则修改arch/x86/目录下的文件
    #vi arch/x86/mm/fault.c
    //在do_page_fault函数的上一行定义统计缺页次数的全局变量pfcount
    unsigned long volatile pfcount;
    //将pfcount加入到do_page_fault中,用以统计缺页次数
    pfcount++;
    3、修改内存管理代码
    //用vi编辑器打开头文件mm.h
    #vi include/linux/mm.h
    //在mm.h中加入全局变量pfcount的声明,代码加在extern int page_cluster;语句之后
    extern unsigned long volatile pfcount;
    4、导出pfcount全局变量,让整个内核(包括模块)都可以访问。方法是:
    #vi kernel/kallsyms.c
    //在文件最后加入一行代码
    EXPORT_SYMBOL(pfcount);
  2. 配置编译新内核
    用编译Linux内核预备实验中的方法完成新内核的配置、编译、替换,重启后验证是否完成替换。
    #uname –r //如果为3.2.58(与你采用的新内核版本一至)说明替换完成
  3. 编写读取pfcount值的模块代码
    系统重启后,执行如下操作:
    #mkdir source //在当前用户目录下创建source文件夹,用于存放编写的用户程序
    #cd source //切换到source目录
    #vi pf.c //新建用于构建模块的代码
  4. 编译、构建内核模块
    #vi Makefile //在source目录下建立Makefile文件
    在Makefile中添加编译内容
  5. 加载模块到内核中
    执行加载模块命令:
    #insmod pf.ko
    查看统计缺页次数:
    #cat /proc/pf/pfcount
    四、实验环境
    VMware 14 Pro虚拟机
    系统版本:CentOS Linux release 7.5.1804 (Core)
    内核版本:3.10.0-957.10.1.el7.x86_64
    工具版本:Xshell 6
    五、实验过程与结果分析:
    1.实验前期注意事项:
    1、克隆
    由于编译更换内核比较复杂,具有一定”危险性“,所以如果是使用VMware虚拟机,可以先克隆系统环境,在克隆 出来的系统下做此实验,不会对原系统造成影响。
    2、扩存
    为了避免容量不够,先进行扩容或重新安装操作系统并分配更多的磁盘空间,参考链接: https://www.cnblogs.com/Sungeek/p/9084510.html#sg1
    2.内核源码包
    1、下载内核源码包在这里插入图片描述
    2、解压内核源码包,然后将解压后的文件夹移至 /usr/src/ 目录下
    命令如下:

tar -xvJf linux-3.10.0-957.12.1.el7.tar.xz

mv linux-3.10.0-957.12.1.el7 /usr/src/

3.修改源码(首先切换到源码主目录,下面的操作全都在主目录下进行,切换命令为:cd /usr/src/linux-3.10.0-957.12.1.el7/)
1、定义pfcount变量
这里需要修改 arch/x86/mm/fault.c 文件,由于文件内容较长,我们首先要确定添加大致位置,命令如下:
cat -n arch/x86/mm/fault.c | grep __do_page_fault在这里插入图片描述
vim打开,并按:输入行数,回车跳转即可,然后在注释上方加入pfcount变量的定义。
在这里插入图片描述
2、 pfcount变量自增
在这里插入图片描述
3、修改内存管理代码
在这里插入图片描述
4、导出pfcount全局变量
此处可以直接使用命令:
echo ‘EXPORT_SYMBOL(pfcount);’>>kernel/kallsyms.c
检查是否成功:
cat kernel/kallsyms.c | grep pfcount
4.生成配置文件
1、安装工具
首先安装 ncurses-devel elfutils-libelf-devel openssl-devel 这三个工具:
yum install ncurses-devel elfutils-libelf-devel openssl-devel -y
如果不是第一次编译,请先执行命令清理(包括后面编译出错,重新编译也要先执行下面的这条命令:
make mrproper
执行命令生成 .config 配置文件:
make menuconfig
进入可视化界面,直接 Save 即可,使用默认配置 —> OK 生成 .config 配置文件,然后 Exit 退出.
5.编译与安装
在编译之前,需要安装 bc 工具:yum install bc -y
编译直接在主目录下使用 make 命令,编译完成后,可以在 arch/x86_64/boot/ 下查看到产生的内核文件 bzImage。
在这里插入图片描述
1、模块编译
执行命令编译模块:make modules
2、安装模块
由于自身编译源码,会有很多debug模块的存在,占用大量存储空间,我们需要在安装的时候排除它,添加参数 INSTALL_MOD_STRIP=1,命令如下:
make INSTALL_MOD_STRIP=1 modules_install
3、安装内核
make INSTALL_MOD_STRIP=1 install
安装完,如下图所示:
在这里插入图片描述
执行命令查看当前使用的内核版本:uname -r
在这里插入图片描述
6.编译加载模块到内核(此处类比实验三,相似),结果如下:
在这里插入图片描述
六、实验心得体会:
此次试验算的上是操作系统中历时最久的一次实验操作,学习了重新编译Linux内核,掌握了Linux内核和发行版本的区别。懂得了如何通过动态加载模块的方法,利用/proc文件系统作为中介来获取缺页数。除此之外,在本次实验中,除了实验的收获,我还学会了克隆和扩容。最大的收获是觉得命令行真的是一个字符都不能错,在扩容时,由于1和l的相像,卡顿了半个小时,最后终于扩容成功。通过此次,相信在之后的学习中会更加的深入。

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值