//////////////////////////////////////////////////////////////////////
// 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,PTSIZE,PADDR(pages),PTE_U);
//////////////////////////////////////////////////////////////////////
// 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,PADDR(bootstack),PTE_W);
//////////////////////////////////////////////////////////////////////
// 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,-KERNBASE,0,PTE_W);
Question
What entries (rows) in the page directory have been filled in at this point? What addresses do they map and where do they point? In other words, fill out this table as much as possible:
EntryBase Virtual AddressPoints to (logically):10230xffc00000Page table for top 4MB of phys memory10220xff800000?.??.??.??20x00800000?10x00400000?00x00000000[see next question]
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?
内核内存部分,PTE_U 无效,因此用户没有读写权限。
使用寻址区域限制,和权限类型检查来保护内核内存。
What is the maximum amount of physical memory that this operating system can support? Why?
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?
Challenge! We consumed many physical pages to hold the page tables for the KERNBASE mapping. Do a more space-efficient job using the PTE_PS ("Page Size") bit in the page directory entries. This bit was not supported in the original 80386, but is supported on more recent x86 processors. You will therefore have to refer to Volume 3 of the current Intel manuals. Make sure you design the kernel to use this optimization only on processors that support it!
Challenge! Extend the JOS kernel monitor with commands to:
Display in a useful and easy-to-read format all of the physical page mappings (or lack thereof) that apply to a particular range of virtual/linear addresses in the currently active address space. For example, you might enter showmappings 0x3000 0x5000 to display the physical page mappings and corresponding permission bits that apply to the pages at virtual addresses 0x3000, 0x4000, and 0x5000.
Explicitly set, clear, or change the permissions of any mapping in the current address space.
Dump the contents of a range of memory given either a virtual or physical address range. Be sure the dump code behaves correctly when the range extends across page boundaries!
Do anything else that you think might be useful later for debugging the kernel. (There's a good chance it will be!)
intshowmappings(intargc,char**argv,structTrapframe*tf){if(argc==1){cprintf("Usage: showmappings 0xbegin_addr 0xend_addr\n");return0;}uint32_tbegin=xtoi(argv[1]),end=xtoi(argv[2]);cprintf("begin: %x, end: %x\n",begin,end);for(;begin<=end;begin+=PGSIZE){pte_t*pte=pgdir_walk(kern_pgdir,(void*)begin,1);//create
if(!pte)panic("boot_map_region panic, out of memory");if(*pte&PTE_P){cprintf("page %x with ",begin);pprint(pte);}elsecprintf("page not exist: %x\n",begin);}return0;}
intsetm(intargc,char**argv,structTrapframe*tf){if(argc==1){cprintf("Usage: setm 0xaddr [0|1 :clear or set] [P|W|U]\n");return0;}uint32_taddr=xtoi(argv[1]);pte_t*pte=pgdir_walk(kern_pgdir,(void*)addr,1);cprintf("%x before setm: ",addr);pprint(pte);uint32_tperm=0;if(argv[3][0]=='P')perm=PTE_P;if(argv[3][0]=='W')perm=PTE_W;if(argv[3][0]=='U')perm=PTE_U;if(argv[2][0]=='0')//clear
*pte=*pte&~perm;else//set
*pte=*pte|perm;cprintf("%x after setm: ",addr);pprint(pte);return0;}
4.1 showvm: 查看内存
1
2
3
4
5
6
7
8
9
10
11
12
intshowvm(intargc,char**argv,structTrapframe*tf){if(argc==1){cprintf("Usage: showvm 0xaddr 0xn\n");return0;}void**addr=(void**)xtoi(argv[1]);uint32_tn=xtoi(argv[2]);inti;for(i=0;i<n;++i)cprintf("VM at %x is %x\n",addr+i,addr[i]);return0;}