操作系统实验 Lab5 xv6修改内存布局

本文档详细介绍了如何调整xv6操作系统内存布局,将用户栈空间移动到地址空间顶部,并实现栈的增长。通过修改proc.h、exec.c、syscall.c、vm.c、proc.c和trap.c等文件,实现栈的映射和动态扩展。实验步骤包括增加进程页数记录、修改地址范围、处理页面错误等。通过运行用户级程序recursive.c进行递归测试,验证了用户栈增长功能的正确性。
摘要由CSDN通过智能技术生成

一、实验目的
调整xv6的内存布局,将用户栈空间移动到地址空间的顶部;实现栈的增长。
二、实验内容
修改xv6的内存布局,在exec.c中通过allocuvm函数重新进行对栈的的地址空间的映射,将其置于高地址位置。实现栈的增长,当有进程申请分配更多的页时,在trap.c中加入T_PGFLT的case。
三、实验步骤
1、修改proc.h,新增pageNum记录为进程用户栈分配的页数

struct proc {
   
	uint sz;                     // Size of process memory (bytes)
	pde_t* pgdir;                // Page table
	char *kstack;                // Bottom of kernel stack for this process
	enum procstate state;        // Process state
	int pid;                     // Process ID
	struct proc *parent;         // Parent process
	struct trapframe *tf;        // Trap frame for current syscall
	struct context *context;     // swtch() here to run process
	void *chan;                  // If non-zero, sleeping on chan
	int killed;                  // If non-zero, have been killed
	struct file *ofile[NOFILE];  // Open files
	struct inode *cwd;           // Current directory
	char name[16];               // Process name (debugging)
	uint pageNum;
};

2、修改exec.c,将栈底移到KERNBASE-1

int
exec(char *path, char **argv)
{
   
	  char *s, *last;
	  int i, off;
	  uint argc, sz, sp, ustack[3+MAXARG+1];
	  struct elfhdr elf;
	  struct inode *ip;
	  struct proghdr ph;
	  pde_t *pgdir, *oldpgdir;
	  struct proc *curproc = myproc();

	  begin_op();
	
	  if((ip = namei(path)) == 0){
   
	    end_op();
	    cprintf("exec: fail\n");
	    return -1;
	  }
	  ilock(ip);
	  pgdir = 0;

	  // Check ELF header
	  if(readi(ip, (char*)&elf, 0, sizeof(elf)) != sizeof(elf))
	 	goto bad;
	  if(elf.magic != ELF_MAGIC)
	    goto bad;
	
	  if((pgdir = setupkvm()) == 0)
	    goto bad;

	  // Load program into memory.
	  sz = 0;
	  for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
   
		    if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
			      goto bad;
		    if(ph.type != ELF_PROG_LOAD)
			      continue;
		    if(ph.memsz < ph.filesz)
			      goto bad;
		    if(ph.vaddr + ph.memsz < ph.vaddr)
			      goto bad;
		    if((sz = allocuvm(pgdir, sz, ph.vaddr + ph.memsz)) == 0)
			      goto bad;
		    if(ph.vaddr % PGSIZE != 0)
			      goto bad;
		    if(loaduvm(pgdir, (char*)ph.vaddr, ip, ph.off, ph.filesz) < 0)
			      goto bad;
  		}
		iunlockput(ip);
		end_op();
		ip = 0;

		// Allocate two pages at the next page boundary.
		// Make the first inaccessible.  Use the second as the user stack.
		sz = PGROUNDUP(sz);

		//将KERNBASE-1作为栈底
		sp = KERNBASE-1;
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值