统计操作系统缺次数
v1.0 可编辑可修改 实验二实验二: : 统计操作系统缺页次数统计操作系统缺页次数 11 v1.0 可编辑可修改 目录目录 一.实验目的一.实验目的---------------------------------------------3---------------------------------------------3 二.实验内容二.实验内容--------------------------------------------3--------------------------------------------3 三三. .实验步骤实验步骤----------------------------------------------3----------------------------------------------3 22 v1.0 可编辑可修改 统计操作系统缺页次数统计操作系统缺页次数 一一 实验目的实验目的 学习虚拟内存的基本原理和Linux 虚拟内存管理技术; 深入理解、掌握 Linux 的按需调页过程; 掌握内核模块的概念和操作方法, 和向/proc 文件系统中增加文件的方法; 综合运用内存管理、系统调用、proc 文件系统、内核编译的知识。 二二 实验内容实验内容 1.1.原理原理 Linux 的虚拟内存技术采用按需调页,当 CPU 请求一个不在内存中的 页面时,会发生缺页,缺页被定义为一种异常(缺页异常) ,会触发缺页中 断处理流程。每种 CPU 结构都提供一个 do_page_fault 处理缺页中断。由 于每发生一次缺页都要进入缺页中断服务函数do_page_fault 一次,所以 可以认为执行该函数的次数就是系统发生缺页的次数。因此可以定义一个 全局变量 pfcount 作为计数变量,在执行 do_page_fault 时,该变量值加 1。本实验通过动态加载模块的方法, 利用/proc 文件系统作为中介来获取 该值。 2.2.实验环境实验环境 操作系统:Ubuntu (内核版本为 3.2.0-23-generic-pae) 内核源码:linux-3.2.58 33 v1.0 可编辑可修改 三三 实验步骤实验步骤 1.1. 下载一份内核源代码并解压下载一份内核源代码并解压 Linux 受 GNU 通用公共许可证(GPL)保护,其内核源代码是完全开放 的。现在很多 Linux 的网站都提供内核代码的下载。推荐使用Linux 的官 方网站: 。 在 terminal 下可以通过 wget 命令下载源代码: $ cd /tmp $ wget 切换到 root 身份,解压源代码到/usr/src 目录下: # xz –d tar –xvf–C /usr/src 2.2.修改内核源代码,添加统计变量修改内核源代码,添加统计变量 1、切换到预编译内核目录 #cd /usr/src/linux-3.2.58 44 v1.0 可编辑可修改 2、修改处理内存访问异常的代码 55 v1.0 可编辑可修改 3.2.58 文件: #make mrproper 然后配置编译选项(此处使用原内核的配置文件,完整的配置命令看 操作提示) : # cp /boot/config-3.2.0-23-generic-pae .config 66 v1.0 可编辑可修改 该命令的 作用 是将 原内核 配置文 件拷 贝的 当前目 录下, 并命 名 为.config。若需要进一步修改配置请参照操作提示。 用编译 Linux 内核预备实验中的方法完成新内核的配置、 编译、 替换, 重启后验证是否完成替换。 #uname#uname 3.2.583.2.58 ––r r 写读取写读取 pfcountpfcount 值的模块代码值的模块代码 系统重启后,执行如下操作: cd /home/sa #mkdir source //在当前用户目录下创建source 文件夹,用于 存放编写的用户程序 77 v1.0 可编辑可修改 #cd source //切换到 source 目录 #vi //新建用于构建模块的代码 -------------------------------------------- /**/ /*modules program*/ #include #include #include #include #include #include #include struct proc_dir_entry *proc_pf; struct proc_dir_entry *proc_pfcount; extern unsigned longvolatile pfcount; static inline struct proc_dir_entry *proc_pf_create(const char* name, mode_t mode, read_proc_t * get_info) { return create_proc_read_entry(name,mode,proc_pf,get_info,NULL); } 88 v1.0 可编辑可修改 int get_pfcount(char *buffer, char **start, off_t offset, int length, int *peof, void *data) { int len = 0; len = sprintf(buffer, “%ld \n“, pfcount); return len; } static int pf_init(void) { proc_pf = proc_mkdir(“pf“, 0); proc_pf_create(“pfcount“, 0, get_pfcount); return 0; } static void pf_exit(void) { remove_proc_entry(“pfcount“,proc_pf); remove_proc_entry(“pf“,0); } module_init(pf_init); module_exit(pf_exit); 99 v1.0 可编辑可修改 MODULE_LICENSE(“GPL“); 5.5. 编译、构建内核模块编译、构建内核模块 cd /home/sa/source #vi Makefile //在 source 目录下建立 Makefile 文件 在 Makefile 中添加如下内容: obj-m := 编译内核模块: make -C /usr/src/ SUBDIRS=/home/sa/source modules 6.6. 加载模块到内核中加载模块到内核中 执行加载模块命令: #insmod 查看统计缺页次数: #cat /proc/pf/pfcount 1010