From c99599784e950169d85bf1e4446e7dbfb1a40f59 Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Thu, 5 Aug 2010 16:00:59 -0400 Subject: [PATCH] remove some unused vm #defines fix corner cases with alignment when mapping kernel ELF file --- defs.h | 2 -- mmu.h | 30 ++++------------------------- proc.c | 2 +- vm.c | 60 ++++++++++++++++++++++------------------------------------ 4 files changed, 28 insertions(+), 66 deletions(-) diff --git a/defs.h b/defs.h index 6a19244..4a63154 100644 --- a/defs.h +++ b/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); diff --git a/mmu.h b/mmu.h index e3ea46f..76a6f1b 100644 --- a/mmu.h +++ b/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) diff --git a/proc.c b/proc.c index c1faec6..dd6f27e 100644 --- a/proc.c +++ b/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; diff --git a/vm.c b/vm.c index 6689b82..c94e9a3 100644 --- a/vm.c +++ b/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,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",