diff options
| author | Robert Morris <rtm@nephron.lcs.mit.edu> | 2010-08-05 16:00:59 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@nephron.lcs.mit.edu> | 2010-08-05 16:00:59 -0400 | 
| commit | c99599784e950169d85bf1e4446e7dbfb1a40f59 (patch) | |
| tree | 19dce8850f76ceca7d48aab7a5eb693887a486c1 | |
| parent | 2cf6b32d4dbc915f5d3b2d7b0e382c0ad20299be (diff) | |
| download | xv6-labs-c99599784e950169d85bf1e4446e7dbfb1a40f59.tar.gz xv6-labs-c99599784e950169d85bf1e4446e7dbfb1a40f59.tar.bz2 xv6-labs-c99599784e950169d85bf1e4446e7dbfb1a40f59.zip | |
remove some unused vm #defines
fix corner cases with alignment when mapping kernel ELF file
| -rw-r--r-- | defs.h | 2 | ||||
| -rw-r--r-- | mmu.h | 30 | ||||
| -rw-r--r-- | proc.c | 2 | ||||
| -rw-r--r-- | vm.c | 60 | 
4 files changed, 28 insertions, 66 deletions
| @@ -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); @@ -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) @@ -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; @@ -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,9 +214,8 @@ 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; -	  kfree((void *) pa, PGSIZE); +	  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",  | 
