⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 是关于页面替换算法的代码模拟
💻 C
字号:
/*
 * main.c	
 * Copyright (c) Inst. of Machine Intelligence at Nankai University
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mmu.h"
#include "util.h"
#include "page.h"

extern int mem_end;
extern phyaddr_t	cpu_cr3;	
extern phyaddr_t	cpu_cr2;
extern phyaddr_t	cpu_cr0;
extern uint32		cpu_errcode;
extern struct page_list free_page_list;

extern char memory[];
int write_file(FILE* file[],struct Page* plist[])
{
	int i,j,signal;
	signal=0;
	for (i=0;i<8;i++)
	{
		for (j=0;j<5;j++)
		{
           if (i==(plist[j]->page_number))
           {
			   fprintf(file[i],"%08x ",page2pa(plist[j]));
			   signal=1;
           }
		}
		if(signal==0)
		    fprintf(file[i],"%08x ",0);
		signal=0;
	}
	return 0;   
}

int main(int argc, char* argv)
{
	int	 read = 0;
	int  buf = 0;
 
	/*
	 * 1, 初始化页目录和页表。
	 *		1) 页目录和页表的内容要写在memory数组里。
	 *		2) 涉及到memory数组的,都必须用write_memory 和read_memory对其进行读写。以后也是一样
	 *		3) 全局变量mem_end可以用来指定memory数组中未被使用的第一个字节的位置,
	 *		4) 将虚拟地址0xf0000000之后的256M空间映射到memory上,可写。
	 *		5) 将虚拟地址0xe0000000之后的256M空间映射到memory上,只读。
	 */
	/* Your Code*/
	//把顶级页表的1024项(占4×1024Bite)装进内存的前4096项,并对每四个字节
	//赋值,计算二级页表的项数:(512M/4k)/1024=128项
	int i;
	int k;
	int j;
	int l;
	int signal;
	int buF1;
	int begin;
	int begin1;
    FILE* vfile[8];
	
	struct Page* new_pagelist[5];
	int request[33]={0, 2, 1 ,3, 5 ,4, 6, 3, 7, 3, 3, 0, 1, 2 ,3, 4 ,5 ,0, 1, 2, 3, 4, 5 ,5, 3 ,1, 1 ,1 ,7 ,1 ,3 ,4 ,1 };
	char* name[8]={"file0.txt","file1.txt","file2.txt","file3.txt","file4.txt","file5.txt","file6.txt","file7.txt"};
	
	signal=0;
	l=0;
	begin1=14*64*4;      //0xe0000000的前十位为1110 0000 00 即14×64
	begin=15*64*4;       //0xf0000000的前十位为1111 0000 00 即15×64
	buF1=0x00001001;    //只读二级页表的初始地址
////////////对虚拟地址0xe0000000映射的顶级页表项的memory数组赋初值
	for (i=begin1;i<256+begin1;i=i+4) 
	{
		write_memory(i,(char*)&buF1,4);
		buF1+=0x1000;	
	}
	buF1=buF1+2;
////////////对虚拟地址0xf0000000映射的顶级页表项的memory数组赋初值
	for (i=begin;i<256+begin;i=i+4)
	{
		write_memory(i,(char*)&buF1,4);
        buF1+=0x1000;
	}
/////////////初始化所有的二级页表项,每个二级页表搜索整个4M内存
	buF1=0x00000001;
	//////////////////////对只读二级页表的初始化
	for (k=1;k<65;k++)
	{
		for (i=k*4*1024;i<(k+1)*1024*4;i=i+4)
		{
			write_memory(i,(char*)&buF1,4);
			buF1+=0x1000;
		}
		buF1=0x00000001;
	}   
	///////////////////////对可写二级页表的初始化
	buF1=0x00000003;
	for (k=65;k<129;k++)
	{
		for (i=k*4*1024;i<(k+1)*1024*4;i=i+4)
		{
			write_memory(i,(char*)&buF1,4);
			buF1+=0x1000;			
		}
		buF1=0x00000003;
	}
	mem_end=129*PGSIZE;
	/*
	 * 2, 开启CPU的分页模式 
	 */
	/* Your Code*/

    cpu_cr0=PAGING;

	//如果完成了前2个工作,就把这两句话注释掉。
	//printf("Page table isn't ready!\n");
	//exit(0);

	/*
	 * 测试前两个步骤
	 */
	read = 0;
	read_memory(0xf0000000 + PDX(0xf0000000) * 4, (char *)&read, 4); //计算后read=0x4003;
    //...0xf0000000 + PDX(0xf0000000) * 4...为f0000f00/////

	assert(read == ((int*)memory)[PDX(0xf0000000)]);//验证read,恰好相等

	buf = 0x00646c72;
	write_memory(0xf0100000, (char *)&buf, 4);
	read_memory(0xe0100000, (char *)&read, 4);
	printf("H%x, Wo%s\n", 57616, &read);       //57616的16进制数为e110
	
	check_pgdir();
	/*
	 * 3, 实现页管理
	 */
	page_init();
	//测试
	/*
	 * 4,缺页中断
	 * 自定义一个中断响应函数,然后将函数地址赋给pgfault_handler.
	 */
	/* Your Code*/
	
	//测试 
	buf = 0x12345678;
	write_memory(0xd0000000, (char*)&buf, 4);
	read_memory(0xd0000000, (char*)&read, 4);
	assert(read == buf);
	
	/*
	 * 5, 页替换
	 *		1), 新建一个可替换页列表,从空闲列表中分配5个物理页,放入可替换列表中。
	 *		2), 在这个替换列表中,实现页替换算法。
	 *		3), 在测试用例中,有33个请求,对应每个页的前33个4字节。如果页在第i次请求中
	 *			 位于内存中,记录该物理页的首地址。
	 *			如果没有被加载进内存,将第i个4字节清0。
	 *		4), 完成测试用例后,将所有页的内容写入磁盘,保存为txt格式,每个虚页有一个
	 *			文件。在文件中用空格分开每一次请求的值。也就是文件中用空格分开了33项。
	 *			物理地址用16进制表示(%08x)。
	 */
	
	// 测试
	// 输入页请求序列:0 2 1 3 5 4 6 3 7 3 3 0 1 2 3 4 5 0 1 2 3 4 5 5 3 1 1 1 7 1 3 4 1  
	// 以表格的形式输出结果,表格中只记录虚页编号
	//////////////////////////////////////////////////////FIFO    先进先出算法
	for (i=0;i<5;i++)
    {
		new_pagelist[i]=page_alloc();
		new_pagelist[i]->page_number=-1;
	//	new_pagelist[i]->hit_num=0;
    }
	for (i=0;i<8;i++)
	{
		vfile[i]=fopen(name[i],"w");
	}
    for (i=0;i<33;i++)
    {
        k=request[i]<<12;
		for (j=0;j<5;j++)
        {
			if (request[i]==(new_pagelist[j]->page_number))
				signal=1;
		}
		if(signal==0)    //signal==0说明没有命中请求的页号
		{
			page_insert(k,new_pagelist[l]);
			(new_pagelist[l])->page_number=request[i];
			l=(l+1)%5;		
		}
		write_file(vfile,new_pagelist);
		signal=0;
    }
	for (i=0;i<8;i++)
	{
		fclose(vfile[i]);
	}
	return 0;
}
	



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -