diff --git a/defs.h b/defs.h index f2724ad..cc3a721 100644 --- a/defs.h +++ b/defs.h @@ -160,7 +160,7 @@ char* uva2ka(pde_t*, char*); int allocuvm(pde_t*, char*, uint); int deallocuvm(pde_t *pgdir, char *addr, uint sz); void freevm(pde_t*); -void inituvm(pde_t*, char*, char*, uint); +void inituvm(pde_t*, char*, uint); int loaduvm(pde_t*, char*, struct inode *ip, uint, uint); pde_t* copyuvm(pde_t*,uint); void switchuvm(struct proc*); diff --git a/proc.c b/proc.c index a72ec6c..853eb0a 100644 --- a/proc.c +++ b/proc.c @@ -120,11 +120,8 @@ userinit(void) initproc = p; if(!(p->pgdir = setupkvm())) panic("userinit: out of memory?"); - if(!allocuvm(p->pgdir, 0x0, (int)_binary_initcode_size)) - panic("userinit: out of memory?"); - inituvm(p->pgdir, 0x0, _binary_initcode_start, - (int)_binary_initcode_size); - p->sz = PGROUNDUP((int)_binary_initcode_size); + inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size); + p->sz = PGSIZE; memset(p->tf, 0, sizeof(*p->tf)); p->tf->cs = (SEG_UCODE << 3) | DPL_USER; p->tf->ds = (SEG_UDATA << 3) | DPL_USER; diff --git a/vm.c b/vm.c index 12aebe5..9c0783d 100644 --- a/vm.c +++ b/vm.c @@ -267,20 +267,14 @@ loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz) } void -inituvm(pde_t *pgdir, char *addr, char *init, uint sz) +inituvm(pde_t *pgdir, char *init, uint sz) { - uint i, pa, n, off; - pte_t *pte; - - for(i = 0; i < sz; i += PGSIZE){ - if(!(pte = walkpgdir(pgdir, (void *)(i+addr), 0))) - panic("inituvm: pte should exist\n"); - off = (i+(uint)addr) % PGSIZE; - pa = PTE_ADDR(*pte); - if(sz - i < PGSIZE) n = sz - i; - else n = PGSIZE; - memmove((char *)pa+off, init+i, n); - } + char *mem = kalloc(); + if (sz >= PGSIZE) + panic("inituvm: more than a page"); + memset(mem, 0, PGSIZE); + mappages(pgdir, 0, PGSIZE, PADDR(mem), PTE_W|PTE_U); + memmove(mem, init, sz); } // given a parent process's page table, create a copy