📄 main.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"
//mmu
extern int mem_end;
extern char memory[];
//cpu
extern phyaddr_t cpu_cr3;
extern phyaddr_t cpu_cr2;
extern phyaddr_t cpu_cr0;
extern uint32 cpu_errcode;
void write(FILE *myfile[],struct Page *mypage[],int record[5][33],int count){
int i,j,already=0;
for (i=0;i<=7;i++)
{
for (j=0;j<5;j++)
{
if (i==(mypage[j]->vitualpage))
{
fprintf(myfile[i],"%08x ",page2pa(mypage[j]));
already=1;
}
}
if(!already){
fprintf(myfile[i],"%08x ",0);
}
already=0;
}
/* for (i=0;i<5;i++)
{
record[i][count]=mypage[i]->vitualpage;
}*/
}
int main(int argc, char* argv)
{
extern struct Page pages[PAGE_NUM];
extern struct page_list free_page_list;
int read = 0;
int buf = 0;
char mybuf[129*PGSIZE]={0};
int i,j,k;
int address;
int visit;
int inmem=0;
int count=0;
int record[5][33];
struct Page *mypage[5];
struct Page *tmp;
struct page_list clocklist;
FILE *vpfile[8];
char *vpfilename[8]={"vpfile0.txt","vpfile1.txt","vpfile2.txt","vpfile3.txt","vpfile4.txt","vpfile5.txt","vpfile6.txt","vpfile7.txt"};
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 };
/*
* 1, 初始化页目录和页表。
* 1) 页目录和页表的内容要写在memory数组里。
* 2) 涉及到memory数组的,都必须用write_memory 和read_memory对其进行读写。以后也是一样
* 3) 全局变量mem_end可以用来指定memory数组中未被使用的第一个字节的位置,
* 4) 将虚拟地址0xf0000000之后的256M空间映射到memory上,可写。
* 5) 将虚拟地址0xe0000000之后的256M空间映射到memory上,只读。
*/
for (i=1;i<=128;i++)
{
address=(i*0x400);
if (i>=65)
visit=3;
else
visit=1;
((int*)mybuf)[(895+i)]=(((address*4/0x1000)<<12)+visit);
for (j=address;j<(address+1024);j++)
((int*)mybuf)[j]=(j-address)*0x1000+visit;
}
write_memory(0,mybuf,129*PGSIZE);
mem_end=129*PGSIZE;
/*2, 开启CPU的分页模式 */
cpu_cr0 =PAGING;
read = 0;
read_memory(0xf0000000 + PDX(0xf0000000) * 4, (char *)&read, 4);
assert(read == ((int*)memory)[PDX(0xf0000000)]);
buf = 0x00646c72;
write_memory(0xf0100000, (char *)&buf, 4);
read_memory(0xe0100000, (char *)&read, 4);
printf("H%x, Wo%s\n", 57616, &read);
check_pgdir();
/*3, 实现页管理 */
page_init();
/*
* 4,缺页中断
* 自定义一个中断响应函数,然后将函数地址赋给pgfault_handler.
*/
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
// 以表格的形式输出结果,表格中只记录虚页编号
for (i=0;i<5;i++){
mypage[i]=page_alloc();
mypage[i]->vitualpage=-1;
}
for (i=0;i<=7;i++)
vpfile[i]=fopen(vpfilename[i],"w");
//FIFO
k=0;
for (i=0;i<33;i++)
{
inmem=0;
for (j=0;j<5;j++)
if (request[i]==(mypage[j]->vitualpage))
inmem=1;
if (inmem!=1)
{
page_insert(request[i]<<12,mypage[k]);
mypage[k]->vitualpage=request[i];
printf("%d",(mypage[0])->vitualpage);
k=(k+1)%5;
}
write(vpfile,mypage,record,count++);
}
printf("FIFO output:\nVirtual page in each physical page:\n");
/* //Second Chance
k=0;
inmem=0;
count=0;
for (i=0;i<5;i++){
page_insert(request[i]<<12,mypage[i]);
mypage[i]->ref=1;
mypage[i]->vitualpage=request[i];
write(vpfile,mypage,record,count++);
}
clocklist.head=mypage[0];
mypage[0]->next=mypage[1];
mypage[1]->next=mypage[2];
mypage[2]->next=mypage[3];
mypage[3]->next=mypage[4];
clocklist.tail=mypage[4];
clocklist.tail->next=NULL;
for (i=5;i<33;i++)
{
inmem=0;
for (j=0;j<5;j++)
{
if (mypage[j]->vitualpage==request[i])
{
inmem=1;
write(vpfile,mypage,record,count++);
}
}
if (inmem!=1)
{
while (1)
{
tmp=clocklist.head;
if (tmp->ref!=0)
{
clocklist.tail->next=clocklist.head;
clocklist.tail=clocklist.tail->next;
clocklist.head->ref=0;
clocklist.head=clocklist.head->next;
}
else{
page_insert(request[i]<<12,tmp);
tmp->vitualpage=request[i];
write(vpfile,mypage,record,count++);
clocklist.tail->next=clocklist.head;
clocklist.tail=clocklist.tail->next;
clocklist.head->ref=1;
clocklist.head=clocklist.head->next;
break;
}
}
}
}
printf("Second Chance output:\nVirtual page in each physical page:\n");
*/
//Clock
/* k=0;
inmem=0;
count=0;
clocklist.head=mypage[0];
for (i=0;i<5;i++){
page_insert(request[i]<<12,mypage[i]);
mypage[i]->ref=1;
mypage[i]->vitualpage=request[i];
write(vpfile,mypage,record,count++);
mypage[i]->next=mypage[(i+1)%5];
}
for (i=5;i<33;i++)
{
inmem=0;
for (j=0;j<5;j++)
{
if (mypage[j]->vitualpage==request[i])
{
inmem=1;
write(vpfile,mypage,record,count++);
}
}
if (inmem!=1)
{
while (1)
{
tmp=clocklist.head;
if (tmp->ref!=0)
{
clocklist.head->ref=0;
clocklist.head=clocklist.head->next;
}
else{
page_insert(request[i]<<12,tmp);
tmp->vitualpage=request[i];
write(vpfile,mypage,record,count++);
clocklist.head->ref=1;
clocklist.head=clocklist.head->next;
break;
}
}
}
}
printf("Clock output:\nVirtual page in each physical page:\n");
for (i=0;i<5;i++)
{
printf("%d\t: ",i);
for (j=0;j<33;j++)
{
if (record[i][j]<0)
printf("x ");
else
printf("%d ",record[i][j]);
}
printf("\n");
}
for (i=0;i<=7;i++)
fclose(vpfile[i]);*/
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -