linux统计中断的时间,统计Linux系统缺页次数

Centos7实现缺页中断具体步骤

一些可能用到的命令

安装vim编译器

yum -y install vim*

Centos修改文件权限,将只读文件改为可写

chmod a+w -R /home/PycharmProjects/

实验题目

61d2d314adaf8c02de7e4430b52ee430.png

具体步骤

一.下载解压内核包

1)下载对应版本的rpm包

2)在Centos7中提取rpm包中的文件可以先提取到文档里,只需要里面的linux-3.10.0-1062.el7.tar.xz文件

3)找到.tar.xz结尾的文件,(这里以linux-3.10.0-1062.el7.tar.xz为例)

在终端打开解压

用xz命令来解压tar.xz格式文件,

[root@Think Arrix]# xz -d linux-3.10.0-1062.el7.tar.xz

[root@Think Arrix]# tar -xvf linux-3.10.0-1062.el7.tar -C/usr/src //将文件解压至/usr/src

解压之后为

c9252a4a4dbf1f4342a31e648552f074.png

4)然后将解压后的文件夹移至/usr/src/目录下

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

二.修改源码

1)切换到源码主目录

(下面的操作就在此目录中)

cd /usr/src/linux-3.10.0-1062.el7/

2)定义pfcount变量

这里需要修改arch/x86/mm/fault.c文件,由于文件内容较长,我们首先要确定添加大致位置;

cat -n arch/x86/mm/fault.c | grep __do_page_fault

601e8f6d7fd201e83cf8f0e68855f44f.png

这里可以看到我的 __do_page_fault 函数在文件的1142行中

跳转到所在行

51c333c4eec32a7be38a4c837934069b.png

打出:1142 后输入所在行回车

按 i 进入插入文本模式插入代码

unsigned long volatile pfcount;

插入后如下图

c0444339f62eddace5d69fc72c29ee10.png

:wq 保存后退出

3)pfcount变量自增

由于建议将该语句添加在good_area:内,所以还是先定位good_area:的位置;

cat -n arch/x86/mm/fault.c | grep good_area:

82b856caeb6ccd6912e609524c1b827d.png

我的是1304行,和前面一样,用vim打开,并跳转至所在行;

vim arch/x86/mm/fault.c

然后加上 pfcount++; 即可

96b685cb93830566f1fbedcf0b5503d7.png

:wq 保存退出

4)修改内存管理代码

接着,vim打开include/linux/mm.h头文件;

vim include/linux/mm.h

在mm.h中加入全局变量pfcount的声明

extern unsigned long volatile pfcount;

代码加在extern int page_cluster;语句之后;

9f25110be358990af3f85f81ebd7d803.png

:wq保存退出

5)导出pfcount全局变量

我们需要导出pfcount全局变量,以便于让系统所有模块访问;

需要在kernel/kallsyms.c文件的最后一行加入

EXPORT_SYMBOL(pfcount);

可以直接使用命令

echo 'EXPORT_SYMBOL(pfcount);'>>kernel/kallsyms.c

检查是否成功

cat kernel/kallsyms.c | grep pfcount

出现 EXPORT_SYMBOL(pfcount);表示成功

05f45b7cbf834f689cf6d03675a819e5.png

三、生成配置文件

首先安装ncurses-devel elfutils-libelf-devel openssl-devel这三个工具;

yum install ncurses-devel elfutils-libelf-devel openssl-devel -y

然后如果不是第一次编译,请先执行命令清理(包括后面编译出错,重新编译也要先执行下面的这条命令)

make mrproper

执行命令生成.config配置文件

make menuconfig

会进入如下界面

e37c73df2e3be8b2bfc355f50191364a.png

进入可视化界面,直左右移动Save即可,使用默认配置;

668a6eb387dbe874a93e3f3960a84d69.png

OK生成.config配置文件,然后Exit退出;

配置文件已经成功生成;

四、编译与安装

1)内核编译

在编译之前,需要安装bc工具(过程中需要);

执行命令

yum install bc -y

编译直接在主目录下使用make命令

make

编译时间较长,请耐心等待;(这个内核编译大概两个半小时,还不算编译模块的时间);

编译完成后,可以在arch/x86_64/boot/下查看到产生的内核文件bzImage(32位系统在arch/x86/boot下);

5b43725cf8bfcdf5a219f4ae6e5eda70.png

2)模块编译

执行命令编译模块

make modules

3)安装模块

由于自身编译源码,会有很多debug模块的存在,占用大量存储空间,我们需要在安装的时候排除它,添加参数INSTALL_MOD_STRIP=1;

执行命令

make INSTALL_MOD_STRIP=1 modules_install

4)安装内核

执行命令

make INSTALL_MOD_STRIP=1 install

安装成功后,可以查看/lib/modules目录下的文件(这里我们安装的内核并没有带次版本号,不影响使用,在后面使用make命令编译的时候就可以看到)

b1fc229a3e1e1fb130d5f02fea224c92.png

在虚拟机上执行reboot命令(重启命令),并在重启时候键盘上下建选择我们自己安装的内核,回车进入;

2d365cf0f41673f7b1ceb65b383ca37a.png

执行命令查看当前使用的内核版本

uname -r

a0d6f68a212d8532f5536260d45f2854.png

五、使用pfcount

在home目录新建一个source目录,并cd进去;

mkdir source && cd source

1)编写readpfcount.c

在source文件中创建一个readpfcount.c文件

vi readpfcount.c

参考代码

(代码中学号可以改为自己的)

/*************************************************

使用seq_file接口实现可读写proc文件

参考:https://elixir.bootlin.com/linux/v5.0/source/include/linux/proc_fs.h

*************************************************/

#include

#include

#include

#include

#include

#include

#include

#include

extern unsigned long volatile pfcount;

/*5,实现show函数

作用是将内核数据输出到用户空间

将在proc file输出时被调用

*/

static int my_proc_show(struct seq_file *m, void *v)

{

/*这里不能使用printfk之类的函数

要使用seq_file输出的一组特殊函数

*/

seq_printf(m, "The pfcount is %ld !\n", pfcount);

return 0;

}

static int my_proc_open(struct inode *inode, struct file *file)

{

/*4,在open函数中调用single_open绑定seq_show函数指针*/

return single_open(file, my_proc_show, NULL);

}

/*2,填充proc_create函数中调用的flie_operations结构体

其中my开头的函数为自己实现的函数,

seq和single开头为内核实现好的函数,直接填充上就行

open为必须填充函数

*/

static struct file_operations my_fops = {

.owner = THIS_MODULE,

.open = my_proc_open,

.release = single_release,

.read = seq_read,

.llseek = seq_lseek,

};

static int __init my_init(void)

{

struct proc_dir_entry *file;

//创建父级目录,第二个参数NULL表示在/proc下

//这里用我的学号当做文件名

struct proc_dir_entry *parent = proc_mkdir("3170301084",NULL);

/*1,

首先要调用创建proc文件的函数,需要绑定flie_operations

参数1:要创建的文件

参数2:权限设置

参数3:父级目录,如果传NULL,则在/proc下

参数4:绑定flie_operations

*/

file = proc_create("readpfcount", 0644, parent, &my_fops);

if(!file)

return -ENOMEM;

return 0;

}

/*6,删除proc文件*/

static void __exit my_exit(void)

{

//移除目录及文件

remove_proc_entry("3170301084", NULL);

}

module_init(my_init);

module_exit(my_exit);

2)编写Makefile

vi Makefile

Makefile参考内容

ifneq ($(KERNELRELEASE),)

obj-m:=readpfcount.o

else

KDIR:= /lib/modules/$(shell uname -r)/build

PWD:= $(shell pwd)

default:

$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:

$(MAKE) -C $(KDIR) M=$(PWD) clean

endif

目录内容

61a994589210253dece0a3bc5eac5203.png

输入make编译,可以看到我们的确是使用的新安装的内核

a4411732b6e3cf2b94f42460e1b07d66.png

3)安装模块

输入命令

insmod readpfcount.ko

56b63c4fb261a3e293484cb11929d180.png

4)查看pfcount的值

输入命令

cat /proc/${你的学号}/readpfcount

832b983030d53f879a34be6c3953431c.png

5) ok缺页次数已经显示出来了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值