MIT_6.828_Lab2 Part3

实验地址:Lab2

Exercise 5. Fill in the missing code in mem_init() after the call to check_page().
Your code should now pass the check_kern_pgdir() and check_page_installed_pgdir() checks.

mem_init()函数里面添加相关代码,使之能够通过check_kern_pgdir()check_page_installed_pgdir()里面的测试用例。

解答如下:

	//
	// Map 'pages' read-only by the user at linear address UPAGES
	// Permissions:
	//    - the new image at UPAGES -- kernel R, user R
	//      (ie. perm = PTE_U | PTE_P)
	//    - pages itself -- kernel RW, user NONE
	// Your code goes here:
		
	boot_map_region(kern_pgdir,UPAGES,ROUNDUP((npages*sizeof(struct PageInfo)),PGSIZE),PADDR((void*)pages),PTE_U|PTE_P);

	boot_map_region(kern_pgdir,(uintptr_t)pages,ROUNDUP((npages*sizeof(struct PageInfo)),PGSIZE),PADDR((void*)pages),PTE_W|PTE_P);

UPAGESpages这两个虚拟地址同时映射到PADDR(pages)这个物理地址中,只不过由于添加的权限不同,USER只能够访问UPAGES而不能够访问pages

	//
	// Use the physical memory that 'bootstack' refers to as the kernel
	// stack.  The kernel stack grows down from virtual address KSTACKTOP.
	// We consider the entire range from [KSTACKTOP-PTSIZE, KSTACKTOP)
	// to be the kernel stack, but break this into two pieces:
	//     * [KSTACKTOP-KSTKSIZE, KSTACKTOP) -- backed by physical memory
	//     * [KSTACKTOP-PTSIZE, KSTACKTOP-KSTKSIZE) -- not backed; so if
	//       the kernel overflows its stack, it will fault rather than
	//       overwrite memory.  Known as a "guard page".
	//     Permissions: kernel RW, user NONE
	// Your code goes here:
	
	boot_map_region(kern_pgdir,KSTACKTOP-KSTKSIZE,KSTKSIZE,(physaddr_t)(PTE_ADDR(PADDR(bootstack))),PTE_W|PTE_P);

KSTACKTOP映射到bootstack指向的物理地址中。需要注意的是,bootstack本身是一个虚拟地址,需要进行物理地址变换。

	//
	// Map all of physical memory at KERNBASE.
	// Ie.  the VA range [KERNBASE, 2^32) should map to
	//      the PA range [0, 2^32 - KERNBASE)
	// We might not have 2^32 - KERNBASE bytes of physical memory, but
	// we just set up the mapping anyway.
	// Permissions: kernel RW, user NONE
	// Your code goes here:

	boot_map_region(kern_pgdir,KERNBASE,ROUNDUP(((long long)1<<32)-KERNBASE,PGSIZE),0,PTE_W|PTE_P);

KERNBASE之上的虚拟地址映射到0开始的物理地址空间,可能当前没有那么多物理地址,但是我们先进行映射。

需要注意的是boot_map_region()函数不要写错:

static void
boot_map_region(pde_t *pgdir, uintptr_t va, size_t size, physaddr_t pa, int perm)
{
	// Fill this function in
	
	uintptr_t now_va;	
	uintptr_t now_pa;
	int page_num = ROUNDUP(size,PGSIZE)/PGSIZE;
	pte_t *pte;

	now_va = va;
	now_pa = pa;

	for (int i=0; i<page_num; i++)
	{
		//下面两行是错误的代码,应该写在后面
		//now_va += PGSIZE;
		//now_pa += PGSIZE;
		
		pte = pgdir_walk(pgdir,(void*)now_va,true);

		if (!pte)
			panic("in function boot_map_region:pte is null\n");

		*pte = PTE_ADDR(now_pa) | perm | PTE_P;

		now_va += PGSIZE;
		now_pa += PGSIZE;
	}
}

结果

运行make;make qemu得到如下结果:

qemu -drive file=obj/kern/kernel.img,index=0,media=disk,format=raw -serial mon:stdio -gdb tcp::26000 -D qemu.log 
6828 decimal is 15254 octal!
Physical memory: 131072K available, base = 640K, extended = 130432K
check_page_free_list() succeeded!
check_page_alloc() succeeded!
check_page() succeeded!
check_kern_pgdir() succeeded!
check_page_free_list() succeeded!
check_page_installed_pgdir() succeeded!
Welcome to the JOS kernel monitor!
Type 'help' for a list of commands.

可以看到全部通过。最后进行make grade评分:

running JOS: (1.1s) 
  Physical page allocator: OK 
  Page management: OK 
  Kernel page directory: OK 
  Page management 2: OK 
Score: 70/70

下面对后面的思考题进行回答。

2.大致的表格如下

EntryBase Virtual AddressPoints to (logically):
UPAGES0xef000000pages
KSTACKTOP-STKSIZE0xf0000000-STKSIZEbootstack
UVPT0xef400000kern_pgdir

3.We have placed the kernel and user environment in the same address space. Why will user programs not be able to read or write the kernel’s memory? What specific mechanisms protect the kernel memory?

答:由于用户和内核是运行在同一地址空间的,为了防止用户代码更改内核数据的情况,需要对内核代码数据区进行相关的保护。在软件层面,我们在kern_pgdir里面将ULIM之上的虚拟空间地址的页表项不添加PTE_U,使用户不能够访问;在硬件层面,当用户访问ULIM之上的空间时,CPU发现PTE_U位为0,就会报错。这样一来,就保护了内核的数据和代码。

4.What is the maximum amount of physical memory that this operating system can support? Why?

答:在硬件层面上,80386有32根地址线,能够寻址4G的物理地址空间,但是这不等于我们的系统就能够寻址4G的空间。内核用UPAGES开始的PTSIZE 空间来存储物理页的信息。每个物理页信息占sizeof(struct PageInfo)=8B的大小,所以共PTSIZE/8个物理页,又每个物理页大小为4K,所以总的大小为(PTSIZE/8)*4K=2G

5.How much space overhead is there for managing memory, if we actually had the maximum amount of physical memory? How is this overhead broken down?

答:这个题目意思没太理解清楚。如果是说pages的话,那么就是npages*sizeof(struct PageInfo);如果是说kern_pgdir的话,那么就是PGSIZE这么大。

6.Revisit the page table setup in kern/entry.S and kern/entrypgdir.c. Immediately after we turn on paging, EIP is still a low number (a little over 1MB). At what point do we transition to running at an EIP above KERNBASE? What makes it possible for us to continue executing at a low EIP between when we enable paging and when we begin running at an EIP above KERNBASE? Why is this transition necessary?

答:在开启了分页之后,由于[0,4MB)和[KERNBASE,KERNBASE+4MB)都是映射到物理地址[0,4MB)的,所以在开启分页到跳转到高地址之间的语句能够正常执行。如果不把虚拟地址[0,4MB)映射到物理地址[0,4MB),就会出现崩溃的情况。执行跳转语句jmp *%eax后,EIP到高低址空间执行。

Challenge略。

END.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值