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            ksegment(void);
 | 
				
			||||||
void            kvmalloc(void);
 | 
					void            kvmalloc(void);
 | 
				
			||||||
void            vminit(void);
 | 
					void            vminit(void);
 | 
				
			||||||
void            printstack(void);
 | 
					 | 
				
			||||||
void            printpgdir(pde_t *);
 | 
					 | 
				
			||||||
pde_t*          setupkvm(void);
 | 
					pde_t*          setupkvm(void);
 | 
				
			||||||
char*           uva2ka(pde_t*, char*);
 | 
					char*           uva2ka(pde_t*, char*);
 | 
				
			||||||
int             allocuvm(pde_t*, char*, uint);
 | 
					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  |
 | 
					// | Page Directory |   Page Table   | Offset within Page  |
 | 
				
			||||||
// |      Index     |      Index     |                     |
 | 
					// |      Index     |      Index     |                     |
 | 
				
			||||||
// +----------------+----------------+---------------------+
 | 
					// +----------------+----------------+---------------------+
 | 
				
			||||||
//  \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/
 | 
					//  \--- PDX(la) --/ \--- PTX(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[]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// page directory index
 | 
					// page directory index
 | 
				
			||||||
#define PDX(la)		((((uint) (la)) >> PDXSHIFT) & 0x3FF)
 | 
					#define PDX(la)		((((uint) (la)) >> PDXSHIFT) & 0x3FF)
 | 
				
			||||||
#define VPD(la)		PDX(la)		// used to index into vpd[]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// page table index
 | 
					// page table index
 | 
				
			||||||
#define PTX(la)		((((uint) (la)) >> PTXSHIFT) & 0x3FF)
 | 
					#define PTX(la)		((((uint) (la)) >> PTXSHIFT) & 0x3FF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// offset in page
 | 
					 | 
				
			||||||
#define PGOFF(la)	(((uint) (la)) & 0xFFF)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// construct linear address from indexes and offset
 | 
					// construct linear address from indexes and offset
 | 
				
			||||||
#define PGADDR(d, t, o)	((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
 | 
					#define PGADDR(d, t, o)	((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// mapping from physical addresses to virtual addresses is the identity one
 | 
					// turn a kernel linear address into a physical address.
 | 
				
			||||||
// (really linear addresses, but we map linear to physical also directly)
 | 
					// all of the kernel data structures have linear and
 | 
				
			||||||
 | 
					// physical addresses that are equal.
 | 
				
			||||||
#define PADDR(a)       ((uint) a)
 | 
					#define PADDR(a)       ((uint) a)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Page directory and page table constants.
 | 
					// Page directory and page table constants.
 | 
				
			||||||
| 
						 | 
					@ -120,9 +108,6 @@ struct segdesc {
 | 
				
			||||||
#define PGSIZE		4096		// bytes mapped by a page
 | 
					#define PGSIZE		4096		// bytes mapped by a page
 | 
				
			||||||
#define PGSHIFT		12		// log2(PGSIZE)
 | 
					#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 PTXSHIFT	12		// offset of PTX in a linear address
 | 
				
			||||||
#define PDXSHIFT	22		// offset of PDX 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_PS		0x080	// Page Size
 | 
				
			||||||
#define PTE_MBZ		0x180	// Bits must be zero
 | 
					#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
 | 
					// Address in page table or page directory entry
 | 
				
			||||||
#define PTE_ADDR(pte)	((uint) (pte) & ~0xFFF)
 | 
					#define PTE_ADDR(pte)	((uint) (pte) & ~0xFFF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
					@ -414,9 +414,9 @@ wait(void)
 | 
				
			||||||
        // Found one.
 | 
					        // Found one.
 | 
				
			||||||
        pid = p->pid;
 | 
					        pid = p->pid;
 | 
				
			||||||
        kfree(p->kstack, KSTACKSIZE);
 | 
					        kfree(p->kstack, KSTACKSIZE);
 | 
				
			||||||
 | 
						p->kstack = 0;
 | 
				
			||||||
	freevm(p->pgdir);
 | 
						freevm(p->pgdir);
 | 
				
			||||||
        p->state = UNUSED;
 | 
					        p->state = UNUSED;
 | 
				
			||||||
	p->kstack = 0;
 | 
					 | 
				
			||||||
        p->pid = 0;
 | 
					        p->pid = 0;
 | 
				
			||||||
        p->parent = 0;
 | 
					        p->parent = 0;
 | 
				
			||||||
        p->name[0] = 0;
 | 
					        p->name[0] = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										58
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								vm.c
									
										
									
									
									
								
							| 
						 | 
					@ -33,27 +33,6 @@ static uint kernend;
 | 
				
			||||||
static uint freesz;
 | 
					static uint freesz;
 | 
				
			||||||
pde_t *kpgdir;         // One kernel page table for scheduler procs
 | 
					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
 | 
					// return the address of the PTE in page table pgdir
 | 
				
			||||||
// that corresponds to linear address va.  if create!=0,
 | 
					// that corresponds to linear address va.  if create!=0,
 | 
				
			||||||
// create any required page table pages.
 | 
					// 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
 | 
					// 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
 | 
					static int
 | 
				
			||||||
mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm)
 | 
					mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uint i;
 | 
					  char *first = PGROUNDDOWN(la);
 | 
				
			||||||
  pte_t *pte;
 | 
					  char *last = PGROUNDDOWN(la + size - 1);
 | 
				
			||||||
 | 
					  char *a = first;
 | 
				
			||||||
  for (i = 0; i < size; i += PGSIZE) {
 | 
					  while(1){
 | 
				
			||||||
    if (!(pte = walkpgdir(pgdir, (void*)(la + i), 1)))
 | 
					    pte_t *pte = walkpgdir(pgdir, a, 1);
 | 
				
			||||||
 | 
					    if(pte == 0)
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
    if(*pte & PTE_P)
 | 
					    if(*pte & PTE_P)
 | 
				
			||||||
      panic("remap");
 | 
					      panic("remap");
 | 
				
			||||||
    *pte = (pa + i) | perm | PTE_P;
 | 
					    *pte = pa | perm | PTE_P;
 | 
				
			||||||
 | 
					    if(a == last)
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    a += PGSIZE;
 | 
				
			||||||
 | 
					    pa += PGSIZE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return 1;
 | 
					  return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -160,10 +145,10 @@ setupkvm(void)
 | 
				
			||||||
  // Map IO space from 640K to 1Mbyte
 | 
					  // Map IO space from 640K to 1Mbyte
 | 
				
			||||||
  if (!mappages(pgdir, (void *)USERTOP, 0x60000, USERTOP, PTE_W))
 | 
					  if (!mappages(pgdir, (void *)USERTOP, 0x60000, USERTOP, PTE_W))
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  // Map kernel text from kern text addr read-only
 | 
					  // Map kernel text read-only
 | 
				
			||||||
  if (!mappages(pgdir, (void *) kerntext, kerntsz, kerntext, 0))
 | 
					  if (!mappages(pgdir, (void *) kerntext, kerntsz, kerntext, 0))
 | 
				
			||||||
    return 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))
 | 
					  if (!mappages(pgdir, (void *) kerndata, kerndsz, kerndata, PTE_W))
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  // Map dynamically-allocated memory read/write (kernel stacks, user mem)
 | 
					  // 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)
 | 
					  if (addr + sz >= (char*)USERTOP)
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  char *start = PGROUNDDOWN(addr);
 | 
					  char *first = PGROUNDDOWN(addr);
 | 
				
			||||||
  char *last = PGROUNDDOWN(addr + sz - 1);
 | 
					  char *last = PGROUNDDOWN(addr + sz - 1);
 | 
				
			||||||
  char *a;
 | 
					  char *a;
 | 
				
			||||||
  for(a = start; a <= last; a += PGSIZE){
 | 
					  for(a = first; a <= last; a += PGSIZE){
 | 
				
			||||||
    pte_t *pte = walkpgdir(pgdir, a, 0);
 | 
					    pte_t *pte = walkpgdir(pgdir, a, 0);
 | 
				
			||||||
    if(pte == 0 || (*pte & PTE_P) == 0){
 | 
					    if(pte == 0 || (*pte & PTE_P) == 0){
 | 
				
			||||||
      char *mem = kalloc(PGSIZE);
 | 
					      char *mem = kalloc(PGSIZE);
 | 
				
			||||||
| 
						 | 
					@ -212,6 +197,8 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
 | 
				
			||||||
  return 1;
 | 
					  return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// free a page table and all the physical memory pages
 | 
				
			||||||
 | 
					// in the user part.
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
freevm(pde_t *pgdir)
 | 
					freevm(pde_t *pgdir)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -227,8 +214,7 @@ freevm(pde_t *pgdir)
 | 
				
			||||||
	if (pgtab[j] != 0) {
 | 
						if (pgtab[j] != 0) {
 | 
				
			||||||
	  uint pa = PTE_ADDR(pgtab[j]);
 | 
						  uint pa = PTE_ADDR(pgtab[j]);
 | 
				
			||||||
	  uint va = PGADDR(i, j, 0);
 | 
						  uint va = PGADDR(i, j, 0);
 | 
				
			||||||
	  if (va >= USERTOP)   // done with user part?
 | 
						  if (va < USERTOP)   // user memory
 | 
				
			||||||
	    break;
 | 
					 | 
				
			||||||
            kfree((void *) pa, PGSIZE);
 | 
					            kfree((void *) pa, PGSIZE);
 | 
				
			||||||
	  pgtab[j] = 0;
 | 
						  pgtab[j] = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -314,8 +300,8 @@ pminit(void)
 | 
				
			||||||
  kernend = ((uint)end + PGSIZE) & ~(PGSIZE-1);
 | 
					  kernend = ((uint)end + PGSIZE) & ~(PGSIZE-1);
 | 
				
			||||||
  kerntext = ph[0].va;
 | 
					  kerntext = ph[0].va;
 | 
				
			||||||
  kerndata = ph[1].va;
 | 
					  kerndata = ph[1].va;
 | 
				
			||||||
  kerntsz = kerndata - kerntext;
 | 
					  kerntsz = ph[0].memsz;
 | 
				
			||||||
  kerndsz = kernend - kerndata;
 | 
					  kerndsz = ph[1].memsz;
 | 
				
			||||||
  freesz = PHYSTOP - kernend;
 | 
					  freesz = PHYSTOP - kernend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cprintf("kerntext@0x%x(sz=0x%x), kerndata@0x%x(sz=0x%x), kernend 0x%x freesz = 0x%x\n", 
 | 
					  cprintf("kerntext@0x%x(sz=0x%x), kerndata@0x%x(sz=0x%x), kernend 0x%x freesz = 0x%x\n", 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue