remove some unused vm #defines

fix corner cases with alignment when mapping kernel ELF file
This commit is contained in:
Robert Morris 2010-08-05 16:00:59 -04:00
parent 2cf6b32d4d
commit c99599784e
4 changed files with 28 additions and 66 deletions

2
defs.h
View file

@ -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
View file

@ -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
View file

@ -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;

60
vm.c
View file

@ -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,9 +214,8 @@ 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",