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

📄 mmu.c

📁 是关于页面替换算法的代码模拟
💻 C
字号:
/*
 * mmu.c	
 * Copyright (c) Inst. of Machine Intelligence at Nankai University
 */
#include "types.h"
#include "mmu.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


char	memory[MEMSIZE] = {0};

void my_pgfault_handler(){	
	extern phyaddr_t cpu_cr2 ;
	struct Page* get_mempage;
	get_mempage=page_alloc();   //分配一个空闲页给临时变量
	page_insert(cpu_cr2,get_mempage);
};

void (*pgfault_handler)() = my_pgfault_handler;


struct Page* pages;
struct Page* free_list;

int mem_end = 0; // memory 中最后一个被使用的字节

int	write_memory(viraddr_t va, char* buf, int size)
{
	extern phyaddr_t	cpu_cr3;	
	extern phyaddr_t	cpu_cr2;
	extern phyaddr_t	cpu_cr0;
	extern uint32		cpu_errcode;
	int i = 0;
	pde_t* pgdir;
	pte_t* pgtable = 0;
	pde_t	pde = 0;
	pte_t	pte = 0;
	int start = 0;	
	if (!buf){
		printf("\nError: Buffer is NULL.\n");
		exit(1);
	}
	
	if ((cpu_cr0 & PAGING) != PAGING)
	{
		//未开启分页的话,虚拟地址直接是物理内存的地址
		for (i = 0; i < size; i++)
			memory[va + i] = buf[i];
		return 0;
	} else
	{
		pgdir = (pde_t*)(memory + cpu_cr3);//得到顶级页表的首地址:模拟内存地址+进程的顶级页表的地址
		for (i = 0; i < size; i++)
		{		
			pde = pgdir[PDX(va + i)];//虚拟地址的前十位为在顶级页表中查找的偏移量,pde取得顶级页表项来分析
			if ((pde & PTE_P) != PTE_P || (pde & PTE_W) != PTE_W)//所需的二级页表不在内存中或不可写,缺页中断
			{
				if (pgfault_handler)
				{
					cpu_cr2 = va + i;
					cpu_errcode = 0x02;
					(*pgfault_handler)();
					i--;//当前还没有结束,不能i++
					continue;
				}
				printf("Error: Page Directory is invalid.\n");
				exit(1);
			}
			
			pgtable = (pde_t*)(memory + PTE_ADDR(pde));//pgtable是二级页表的首地址:模拟内存地址+顶级页表项的前20位
			pte = pgtable[PTX(va + i)];//虚拟地址的中间十位是二级页表的索引
			if (pte & PTE_P != PTE_P || (pde & PTE_W) != PTE_W)
			{
				if (pgfault_handler)
				{
					cpu_cr2 = va + i;
					cpu_errcode = 0x02;
					(*pgfault_handler)();
					i--;
					continue;
				}
				printf("Error: Page Table is invalid.\n");
				exit(1);
			}
			
			memory[PTE_ADDR(pte) + PGOFF(va + i)] = buf[i];
		}
		return 0;
	}
}


int read_memory(viraddr_t va, char* buf, int size)
{
	extern char memory[];
	extern phyaddr_t	cpu_cr3;	
	extern phyaddr_t	cpu_cr2;
	extern phyaddr_t	cpu_cr0;
	extern uint32		cpu_errcode;
	int i = 0;
	pde_t* pgdir;
	pte_t* pgtable = 0;
	pde_t	pde = 0;
	pte_t	pte = 0;
	int start = 0;

	
	if (!buf){
		printf("\nError: Buffer is NULL.\n");
		exit(1);
	}
	
	if ((cpu_cr0 & PAGING) != PAGING)
	{
		//未分页
		for (i = 0; i < size; i++)
			buf[i] = memory[va + i];
		return 0;
	} else
	{
		pgdir = (pde_t*)(memory + cpu_cr3);
	
		for (i = 0; i < size; i++)
		{		
	    	pde = pgdir[PDX(va + i)];
		
			if ((pde & PTE_P) != PTE_P)
			{
				if (pgfault_handler)
				{
					cpu_cr2 = va + i;
					cpu_errcode = 0x00;
					(*pgfault_handler)();
					i--;
					continue;
				}
				printf("Error: Page Directory is invalid.\n");
				exit(1);
			}
		
			pgtable = (pde_t*)(memory + PTE_ADDR(pde));
			pte = pgtable[PTX(va + i)];
			if ((pte & PTE_P) != PTE_P)
			{
				if (pgfault_handler)
				{
					cpu_cr2 = va + i;
					cpu_errcode = 0x00;
					(*pgfault_handler)();
					i--;
					continue;
				}
				printf("Error: Page Table is invalid.\n");
				exit(1);
			}
			
			buf[i] = memory[PTE_ADDR(pte) + PGOFF(va + i)];
		}
		return 0;
	}
}

⌨️ 快捷键说明

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