操作系统课程设计
操作系统实验 —— 基于WRK的进程工作集实验
实验目的
1 掌握虚拟机和调试工具等的使用。
2 阅读Windows源码中工作集管理相关部分。
3 修改Windows内核中页面置换算法,深入理解工作集和页面置换算法如何在一个完整的操作系统中实现
实验步骤
1 搭建实验环境
WRK v1.2
Virtual PC 2007
    -Windows 2003 Sp1
WinDbg
搭建环境相对简单,只需按照下列步骤完成即可
1)首先把实验需要的文件下载到本地d:\ WRK-CRK目录下。
2)在cmd命令行中输入:
    a. mkdir c:\wrk(建立一个新目录)
    b. set wrk=c:\wrk(上面建立的目录)
    c. xcopy /crehkdq d:\ WRK-CRK\WRK-v1.2 %wrk%(把WRK内核代码和工具拷到新建立的目录下)
    d. set arch=x86[amd64](设置机器的CPU架构,x86还是amd64)指定编译目标结构
    e. set path=%wrk%\tools\%arch%;%path%(设置WRK平台编译工具路径)
    f. cd %wrk%\base\ntos(进入编译工具目录)
    g. nmake–nologo %arch%=(编译WRK内核)
3)如果编译成功的话,%wrk%\base\ntos\build\exe目录下会生成两个文件,和wrkx86.pdb。
2 源码阅读及算法验证
工作集代码分布
文件名称
模块功能
ps.h
工作集的部分结构声明
mi.h
存储器管理相关的数据结构和接口
wslist.c
包含操作系统工作集结构的系列函数
wstree.c
实现工作集管理中的一些辅助函数
wsmanage.c
包含操作活动状态进程工作集的函数,同时实现工作集管理线程
Step1 编写测试程序
程序内容:申请内存分配。
代码如下:
#include<stdio.h>
#definelocsize 1024*1024
voidmain()
{
    inti=6;
    i=i++;
    printf("%d",i);
    while (1)
    {
        char * newplace= (char *) malloc(locsize);
        sprintf(newplace,"%s","hello!");
        printf("%s\n",newplace);
        //free (newplace);
    }
}
Step2 查看工作集
在虚拟机中运行程序。在内核中设置断点,让内核停下来查看进程状态。
在WinDbg的命令行输入命令查看工作集信息。
1.!process 0 0
显示的是当前所有进程信息,查我们编写的程序的进程信息:
据此地址查看EPROCESS信息
2. dteprocess811d41c8
从显示的EPROCESS信息中查MMSUPPORT的地址
0x1e8是相对地址。
3.dtnt!_MMSUPPORT 811d41c8+0x1e8
查看MMSUPPORT的信息
   
4.dtnt!_MMWSL 0xc0502000
查看MMWSL信息
FirstFree下次进行工作集页面添加的位置
FirstDynamic工作集页面中第一个可用页面的下标
LastEntry工作集页面中最后一个可用页面的下标
NextSlot进行页面修剪算法是据此搜索最有替换页面
5.dd 0xc0502698 l 0x40
进程间通信实验报告心得
查看MMWSLE的信息,即工作集页面项(所有页面虚拟地址)的详细信息
Step3 验证页面置换算法
在置换算法中设置断点,图中桃红标识。
此时的各个变量的值。其中TheNextSlot(0x2b)标识置换算法起始搜索的页面。
本地local
置换前
置换完之后
即TheNextSlot指向的页面被置换
分析:
源码:if ((Flags == WsleAllocationReplace) ||
OldestAge>= MI_IMMEDIATE_REPLACEMENT_AGE ||
NumberOfCandidates> MM_WORKING_SET_LIST_SEARCH)
三个条件:
1 Flags 等于WsleAllocationReplace(WsleAllocationReplace表示内存紧张,立即替换)
2 页面年龄大于2(MI_IMMEDIATE_REPLACEMENT_AGE=2)
3 搜索的页面数大于17(MM_WORKING_SET_LIST_SEARCH=17),
满足一个即进行页面替换。我们可以看到置换前
1 Flag = WsleAllocationAny
2内存中从红框标识页之后的17个页面年龄均为0
所以页面置换算法会在搜索17个页面之后,立即进行置换,置换也为TheNextSlot指向的页。
断点后单步执行的过程,也验证了这一分析。
3 修改算法及验证
Step1 修改页面置换算法
修改代码base\ntos\inc\ps.h:
typedefstruct _MMSUPPORT {
    LIST_ENTRY WorkingSetExpansionLinks;
    LARGE_INTEGER LastTrimTime;
    MMSUPPORT_FLAGS Flags;
    ULONG PageFaultCount;
    WSLE_NUMBER PeakWorkingSetSize;
    WSLE_NUMBER GrowthSinceLastEstimate;
    WSLE_NUMBER MinimumWorkingSetSize;
    WSLE_NUMBER MaximumWorkingSetSize;
struct _MMWSL *VmWorkingSetList;
    WSLE_NUMBER Claim;
    WSLE_NUMBER NextEstimationSlot;
    WSLE_NUMBER NextAgingSlot;
    WSLE_NUMBER EstimatedAvailable;
    WSLE_NUMBER WorkingSetSize;
EX_PUSH_LOCK WorkingSetMutex;
ULONG num; // 新增加
} MMSUPPORT, *PMMSUPPORT;
修改代码base\ntos\mm\wslist.c: 272:MiDoReplacement()
算法思想:碰见有效页面就进行替换,每次搜索的的起始索引依然为NextSlot。
VOID
MiReplaceWorkingSetEntry (
    IN PMMSUPPORT WsInfo,
    IN WSLE_ALLOCATION_TYPE Flags
    )
{
    WSLE_NUMBER WorkingSetIndex;
    WSLE_NUMBER FirstDynamic;
    WSLE_NUMBER LastEntry;
    PMMWSL WorkingSetList;
    PMMWSLE Wsle;
    PMMPTE PointerPte;
    WSLE_NUMBER TheNextSlot;
WorkingSetList = WsInfo->VmWorkingSetList;
Wsle = WorkingSetList->Wsle;
LastEntry = WorkingSetList->LastEntry;
FirstDynamic = WorkingSetList->FirstDynamic;
WorkingSetIndex = WorkingSetList->NextSlot;
    if (WorkingSetIndex>LastEntry || WorkingSetIndex<FirstDynamic) {
WorkingSetIndex = FirstDynamic;
    }
TheNextSlot = WorkingSetIndex;
    while (TRUE) { 
        while (Wsle[WorkingSetIndex].u1.e1.Valid == 0) {
WorkingSetIndex += 1;
            if (WorkingSetIndex>LastEntry) {
WorkingSetIndex = FirstDynamic;
            }
            if (WorkingSetIndex == TheNextSlot) {
                if (Flags == WsleAllocationAny) {
WsInfo->GrowthSinceLastEstimate += 1;
                }
                return;
            }
        }
PointerPte = MiGetPteAddress(Wsle[WorkingSetIndex].u1.VirtualAddress);
      if (MiFreeWsle (WorkingSetIndex, WsInfo, PointerPte)) {//直接替换
WorkingSetList->NextSlot = WorkingSetIndex + 1;
                break;
            }
WorkingSetIndex += 1;
        if (WorkingSetIndex>LastEntry) {
WorkingSetIndex = FirstDynamic;
        }
        if (WorkingSetIndex == TheNextSlot) {
            if (Flags == WsleAllocationAny) {
WsInfo->GrowthSinceLastEstimate += 1;
            }
            break;
        }
    }
    return;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。