remove some unused vm #defines
fix corner cases with alignment when mapping kernel ELF file
This commit is contained in:
		
							parent
							
								
									2cf6b32d4d
								
							
						
					
					
						commit
						c99599784e
					
				
					 4 changed files with 28 additions and 66 deletions
				
			
		
							
								
								
									
										2
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								defs.h
									
										
									
									
									
								
							|  | @ -156,8 +156,6 @@ void            pminit(void); | |||
| void            ksegment(void); | ||||
| void            kvmalloc(void); | ||||
| void            vminit(void); | ||||
| void            printstack(void); | ||||
| void            printpgdir(pde_t *); | ||||
| pde_t*          setupkvm(void); | ||||
| char*           uva2ka(pde_t*, char*); | ||||
| int             allocuvm(pde_t*, char*, uint); | ||||
|  |  | |||
							
								
								
									
										30
									
								
								mmu.h
									
										
									
									
									
								
							
							
						
						
									
										30
									
								
								mmu.h
									
										
									
									
									
								
							|  | @ -85,32 +85,20 @@ struct segdesc { | |||
| // | Page Directory |   Page Table   | Offset within Page  |
 | ||||
| // |      Index     |      Index     |                     |
 | ||||
| // +----------------+----------------+---------------------+
 | ||||
| //  \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/
 | ||||
| //  \----------- PPN(la) -----------/
 | ||||
| //
 | ||||
| // The PDX, PTX, PGOFF, and PPN macros decompose linear addresses as shown.
 | ||||
| // To construct a linear address la from PDX(la), PTX(la), and PGOFF(la),
 | ||||
| // use PGADDR(PDX(la), PTX(la), PGOFF(la)).
 | ||||
| 
 | ||||
| // page number field of address
 | ||||
| #define PPN(la)		(((uint) (la)) >> PTXSHIFT) | ||||
| #define VPN(la)		PPN(la)		// used to index into vpt[]
 | ||||
| //  \--- PDX(la) --/ \--- PTX(la) --/ 
 | ||||
| 
 | ||||
| // page directory index
 | ||||
| #define PDX(la)		((((uint) (la)) >> PDXSHIFT) & 0x3FF) | ||||
| #define VPD(la)		PDX(la)		// used to index into vpd[]
 | ||||
| 
 | ||||
| // page table index
 | ||||
| #define PTX(la)		((((uint) (la)) >> PTXSHIFT) & 0x3FF) | ||||
| 
 | ||||
| // offset in page
 | ||||
| #define PGOFF(la)	(((uint) (la)) & 0xFFF) | ||||
| 
 | ||||
| // construct linear address from indexes and offset
 | ||||
| #define PGADDR(d, t, o)	((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) | ||||
| 
 | ||||
| // mapping from physical addresses to virtual addresses is the identity one
 | ||||
| // (really linear addresses, but we map linear to physical also directly)
 | ||||
| // turn a kernel linear address into a physical address.
 | ||||
| // all of the kernel data structures have linear and
 | ||||
| // physical addresses that are equal.
 | ||||
| #define PADDR(a)       ((uint) a) | ||||
| 
 | ||||
| // Page directory and page table constants.
 | ||||
|  | @ -120,9 +108,6 @@ struct segdesc { | |||
| #define PGSIZE		4096		// bytes mapped by a page
 | ||||
| #define PGSHIFT		12		// log2(PGSIZE)
 | ||||
| 
 | ||||
| #define PTSIZE		(PGSIZE*NPTENTRIES) // bytes mapped by a page directory entry
 | ||||
| #define PTSHIFT		22		// log2(PTSIZE)
 | ||||
| 
 | ||||
| #define PTXSHIFT	12		// offset of PTX in a linear address
 | ||||
| #define PDXSHIFT	22		// offset of PDX in a linear address
 | ||||
| 
 | ||||
|  | @ -140,13 +125,6 @@ struct segdesc { | |||
| #define PTE_PS		0x080	// Page Size
 | ||||
| #define PTE_MBZ		0x180	// Bits must be zero
 | ||||
| 
 | ||||
| // The PTE_AVAIL bits aren't used by the kernel or interpreted by the
 | ||||
| // hardware, so user processes are allowed to set them arbitrarily.
 | ||||
| #define PTE_AVAIL	0xE00	// Available for software use
 | ||||
| 
 | ||||
| // Only flags in PTE_USER may be used in system calls.
 | ||||
| #define PTE_USER	(PTE_AVAIL | PTE_P | PTE_W | PTE_U) | ||||
| 
 | ||||
| // Address in page table or page directory entry
 | ||||
| #define PTE_ADDR(pte)	((uint) (pte) & ~0xFFF) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										2
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								proc.c
									
										
									
									
									
								
							|  | @ -414,9 +414,9 @@ wait(void) | |||
|         // Found one.
 | ||||
|         pid = p->pid; | ||||
|         kfree(p->kstack, KSTACKSIZE); | ||||
| 	p->kstack = 0; | ||||
| 	freevm(p->pgdir); | ||||
|         p->state = UNUSED; | ||||
| 	p->kstack = 0; | ||||
|         p->pid = 0; | ||||
|         p->parent = 0; | ||||
|         p->name[0] = 0; | ||||
|  |  | |||
							
								
								
									
										58
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								vm.c
									
										
									
									
									
								
							|  | @ -33,27 +33,6 @@ static uint kernend; | |||
| static uint freesz; | ||||
| pde_t *kpgdir;         // One kernel page table for scheduler procs
 | ||||
| 
 | ||||
| void | ||||
| printpgdir(pde_t *pgdir) | ||||
| { | ||||
|   uint i; | ||||
|   uint j; | ||||
| 
 | ||||
|   cprintf("printpgdir 0x%x\n", pgdir); | ||||
|   for (i = 0; i < NPDENTRIES; i++) { | ||||
|     if (pgdir[i] != 0 && i < 100) { | ||||
|       cprintf("pgdir %d, v=0x%x\n", i, pgdir[i]); | ||||
|       pte_t *pgtab = (pte_t*) PTE_ADDR(pgdir[i]); | ||||
|       for (j = 0; j < NPTENTRIES; j++) { | ||||
| 	if (pgtab[j] != 0) | ||||
| 	  cprintf("pgtab %d, v=0x%x, addr=0x%x\n", j, PGADDR(i, j, 0),  | ||||
| 		PTE_ADDR(pgtab[j])); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   cprintf("printpgdir done\n", pgdir); | ||||
| } | ||||
| 
 | ||||
| // return the address of the PTE in page table pgdir
 | ||||
| // that corresponds to linear address va.  if create!=0,
 | ||||
| // create any required page table pages.
 | ||||
|  | @ -84,19 +63,25 @@ walkpgdir(pde_t *pgdir, const void *va, int create) | |||
| } | ||||
| 
 | ||||
| // create PTEs for linear addresses starting at la that refer to
 | ||||
| // physical addresses starting at pa. 
 | ||||
| // physical addresses starting at pa. la and size might not
 | ||||
| // be page-aligned.
 | ||||
| static int | ||||
| mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm) | ||||
| { | ||||
|   uint i; | ||||
|   pte_t *pte; | ||||
| 
 | ||||
|   for (i = 0; i < size; i += PGSIZE) { | ||||
|     if (!(pte = walkpgdir(pgdir, (void*)(la + i), 1))) | ||||
|   char *first = PGROUNDDOWN(la); | ||||
|   char *last = PGROUNDDOWN(la + size - 1); | ||||
|   char *a = first; | ||||
|   while(1){ | ||||
|     pte_t *pte = walkpgdir(pgdir, a, 1); | ||||
|     if(pte == 0) | ||||
|       return 0; | ||||
|     if(*pte & PTE_P) | ||||
|       panic("remap"); | ||||
|     *pte = (pa + i) | perm | PTE_P; | ||||
|     *pte = pa | perm | PTE_P; | ||||
|     if(a == last) | ||||
|       break; | ||||
|     a += PGSIZE; | ||||
|     pa += PGSIZE; | ||||
|   } | ||||
|   return 1; | ||||
| } | ||||
|  | @ -160,10 +145,10 @@ setupkvm(void) | |||
|   // Map IO space from 640K to 1Mbyte
 | ||||
|   if (!mappages(pgdir, (void *)USERTOP, 0x60000, USERTOP, PTE_W)) | ||||
|     return 0; | ||||
|   // Map kernel text from kern text addr read-only
 | ||||
|   // Map kernel text read-only
 | ||||
|   if (!mappages(pgdir, (void *) kerntext, kerntsz, kerntext, 0)) | ||||
|     return 0; | ||||
|   // Map kernel data form kern data addr R/W
 | ||||
|   // Map kernel data read/write
 | ||||
|   if (!mappages(pgdir, (void *) kerndata, kerndsz, kerndata, PTE_W)) | ||||
|     return 0; | ||||
|   // Map dynamically-allocated memory read/write (kernel stacks, user mem)
 | ||||
|  | @ -194,10 +179,10 @@ allocuvm(pde_t *pgdir, char *addr, uint sz) | |||
| { | ||||
|   if (addr + sz >= (char*)USERTOP) | ||||
|     return 0; | ||||
|   char *start = PGROUNDDOWN(addr); | ||||
|   char *first = PGROUNDDOWN(addr); | ||||
|   char *last = PGROUNDDOWN(addr + sz - 1); | ||||
|   char *a; | ||||
|   for(a = start; a <= last; a += PGSIZE){ | ||||
|   for(a = first; a <= last; a += PGSIZE){ | ||||
|     pte_t *pte = walkpgdir(pgdir, a, 0); | ||||
|     if(pte == 0 || (*pte & PTE_P) == 0){ | ||||
|       char *mem = kalloc(PGSIZE); | ||||
|  | @ -212,6 +197,8 @@ allocuvm(pde_t *pgdir, char *addr, uint sz) | |||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // free a page table and all the physical memory pages
 | ||||
| // in the user part.
 | ||||
| void | ||||
| freevm(pde_t *pgdir) | ||||
| { | ||||
|  | @ -227,8 +214,7 @@ freevm(pde_t *pgdir) | |||
| 	if (pgtab[j] != 0) { | ||||
| 	  uint pa = PTE_ADDR(pgtab[j]); | ||||
| 	  uint va = PGADDR(i, j, 0); | ||||
| 	  if (va >= USERTOP)   // done with user part?
 | ||||
| 	    break; | ||||
| 	  if (va < USERTOP)   // user memory
 | ||||
|             kfree((void *) pa, PGSIZE); | ||||
| 	  pgtab[j] = 0; | ||||
| 	} | ||||
|  | @ -314,8 +300,8 @@ pminit(void) | |||
|   kernend = ((uint)end + PGSIZE) & ~(PGSIZE-1); | ||||
|   kerntext = ph[0].va; | ||||
|   kerndata = ph[1].va; | ||||
|   kerntsz = kerndata - kerntext; | ||||
|   kerndsz = kernend - kerndata; | ||||
|   kerntsz = ph[0].memsz; | ||||
|   kerndsz = ph[1].memsz; | ||||
|   freesz = PHYSTOP - kernend; | ||||
| 
 | ||||
|   cprintf("kerntext@0x%x(sz=0x%x), kerndata@0x%x(sz=0x%x), kernend 0x%x freesz = 0x%x\n",  | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Robert Morris
						Robert Morris